am 29af77bf: am ca88104b: am 770379e1: am 6efd4463: Fix a deadlock in the breakpoint code.

Merge commit '29af77bfa00ac560680dea99cf0893fccc257176' into dalvik-dev

* commit '29af77bfa00ac560680dea99cf0893fccc257176':
  Fix a deadlock in the breakpoint code.
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index 69aa420..cfcd93d 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -1,3 +1,4 @@
+# -*- mode: makefile -*-
 # Copyright (C) 2007 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,26 +21,37 @@
 # Common definitions for host and target.
 #
 
-# The core library is divided into modules. Each module has a separate
-# Java source directory, and some (hopefully eventually all) also have
-# a directory for tests.
+# dalvik/libcore is divided into modules.
+#
+# The structure of each module is:
+#
+#   src/
+#       main/               # To be shipped on every device.
+#            java/          # Java source for library code.
+#            native/        # C++ source for library code.
+#            resources/     # Support files.
+#       test/               # Built only on demand, for testing.
+#            java/          # Java source for tests.
+#            native/        # C++ source for tests (rare).
+#            resources/     # Support files.
+#
+# All subdirectories are optional (hence the "2> /dev/null"s below).
 
-define all-core-java-files
-$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && find */src/$(1)/java -name "*.java"))
+define all-main-java-files-under
+$(foreach dir,$(1),$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && find $(dir)/src/main/java -name "*.java" 2> /dev/null)))
 endef
 
-# Redirect ls stderr to /dev/null because the corresponding resources
-# directories don't always exist.
+define all-test-java-files-under
+$(patsubst ./%,%,$(shell cd $(LOCAL_PATH) && find $(1)/src/test/java -name "*.java" 2> /dev/null))
+endef
+
 define all-core-resource-dirs
 $(shell cd $(LOCAL_PATH) && ls -d */src/$(1)/{java,resources} 2> /dev/null)
 endef
 
-# The core Java files and associated resources.
-core_src_files := $(call all-core-java-files,main)
+# The Java files and their associated resources.
+core_src_files := $(call all-main-java-files-under,annotation archive auth awt-kernel concurrent crypto dalvik dom icu json junit logging luni luni-kernel math nio nio_char openssl prefs regex security security-kernel sql suncompat support text x-net xml)
 core_resource_dirs := $(call all-core-resource-dirs,main)
-
-# The test Java files and associated resources.
-test_src_files := $(call all-core-java-files,test)
 test_resource_dirs := $(call all-core-resource-dirs,test)
 
 
@@ -72,22 +84,261 @@
 core-intermediates := ${intermediates}
 
 
-# Definitions to make the core-tests library.
+
+# Definitions to make the sqlite JDBC driver.
 
 include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-main-java-files-under,sqlite-jdbc)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core
+LOCAL_MODULE := sqlite-jdbc
+include $(BUILD_JAVA_LIBRARY)
 
-LOCAL_SRC_FILES := $(test_src_files)
+
+# Definitions to make the core-tests libraries.
+#
+# We make a library per module, because otherwise the .jar files get too
+# large, to the point that dx(1) can't cope (and the build is
+# ridiculously slow).
+#
+# TODO: DalvikRunner will make this nonsense obsolete.
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,annotation)
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-annotation
+include $(BUILD_JAVA_LIBRARY)
 
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,archive)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-archive
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,concurrent)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-concurrent
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,crypto)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-crypto
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,dom)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-dom
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,json)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-json
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,logging)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-logging
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,luni-kernel)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-luni-kernel
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,luni)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+# This module contains the top-level "tests.AllTests" that ties everything
+# together, so it has compile-time dependencies on all the other test
+# libraries.
+# TODO: we should have a bogus module that just contains tests.AllTests for speed.
+LOCAL_JAVA_LIBRARIES := \
+        core \
+        core-tests-support \
+        core-tests-annotation \
+        core-tests-archive \
+        core-tests-concurrent \
+        core-tests-crypto \
+        core-tests-dom \
+        core-tests-json \
+        core-tests-logging \
+        core-tests-luni-kernel \
+        core-tests-math \
+        core-tests-nio \
+        core-tests-nio_char \
+        core-tests-prefs \
+        core-tests-regex \
+        core-tests-security \
+        core-tests-sql \
+        core-tests-suncompat \
+        core-tests-text \
+        core-tests-x-net \
+        core-tests-xml
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-luni
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,math)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-math
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,nio)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-nio
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,nio_char)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-nio_char
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,prefs)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-prefs
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,regex)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-regex
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,security)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-security
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,sql)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support sqlite-jdbc
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-sql
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,suncompat)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-suncompat
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,support)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core
 LOCAL_DX_FLAGS := --core-library
-
 LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE := core-tests
-
+LOCAL_MODULE := core-tests-support
 include $(BUILD_JAVA_LIBRARY)
 
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,text)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-text
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,x-net)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-x-net
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-test-java-files-under,xml)
+LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core core-tests-support
+LOCAL_DX_FLAGS := --core-library
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE := core-tests-xml
+include $(BUILD_JAVA_LIBRARY)
+
+
 
 
 # This one's tricky. One of our tests needs to have a
@@ -169,21 +420,4 @@
 
     include $(BUILD_HOST_JAVA_LIBRARY)
 
-
-    # Definitions to make the core-tests library.
-
-    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
-    LOCAL_DX_FLAGS := --core-library
-
-    LOCAL_MODULE_TAGS := tests
-    LOCAL_MODULE := core-tests
-
-    include $(BUILD_HOST_JAVA_LIBRARY)
-
 endif
diff --git a/NOTICE b/NOTICE
index 39a4ea2..5a185c2 100644
--- a/NOTICE
+++ b/NOTICE
@@ -59,7 +59,7 @@
    ==  NOTICE file for the ICU License.                                   ==
    =========================================================================
 
-Copyright (c) 1995-2006 International Business Machines Corporation and others
+Copyright (c) 1995-2009 International Business Machines Corporation and others
 
 All rights reserved.
 
diff --git a/NativeCode.mk b/NativeCode.mk
index 57c4903..38ff709 100644
--- a/NativeCode.mk
+++ b/NativeCode.mk
@@ -85,6 +85,11 @@
 
 include $(CLEAR_VARS)
 
+ifeq ($(TARGET_ARCH),arm)
+# Ignore "note: the mangling of 'va_list' has changed in GCC 4.4"
+LOCAL_CFLAGS += -Wno-psabi
+endif
+
 # Define the rules.
 LOCAL_SRC_FILES := $(core_src_files)
 LOCAL_C_INCLUDES := $(core_c_includes)
diff --git a/annotation/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java b/annotation/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java
index 0ff79ec..75f1bed 100644
--- a/annotation/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java
+++ b/annotation/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java
@@ -19,8 +19,6 @@
 
 import java.lang.reflect.Method;
 
-import org.apache.harmony.annotation.internal.nls.Messages;
-
 /**
  * Indicates that an annotation type has changed since it was compiled or
  * serialized.
@@ -46,7 +44,7 @@
      *            so it may not be human-readable.
      */
     public AnnotationTypeMismatchException(Method element, String foundType) {
-        super(Messages.getString("annotation.1", element, foundType)); //$NON-NLS-1$
+        super("The annotation element " + element + " doesn't match the type " + foundType);
         this.element = element;
         this.foundType = foundType;
     }
diff --git a/annotation/src/main/java/java/lang/annotation/IncompleteAnnotationException.java b/annotation/src/main/java/java/lang/annotation/IncompleteAnnotationException.java
index a5d2068..9b7aa6a 100644
--- a/annotation/src/main/java/java/lang/annotation/IncompleteAnnotationException.java
+++ b/annotation/src/main/java/java/lang/annotation/IncompleteAnnotationException.java
@@ -17,8 +17,6 @@
 
 package java.lang.annotation;
 
-import org.apache.harmony.annotation.internal.nls.Messages;
-
 /**
  * Indicates that an element of an annotation type was accessed that was added
  * after the type was compiled or serialized. This does not apply to new
@@ -43,9 +41,10 @@
      * @param elementName
      *            the name of the incomplete element.
      */
-    public IncompleteAnnotationException(
-            Class<? extends Annotation> annotationType, String elementName) {
-        super(Messages.getString("annotation.0", elementName, annotationType.getName())); //$NON-NLS-1$
+    public IncompleteAnnotationException(Class<? extends Annotation> annotationType,
+            String elementName) {
+        super("The element " + elementName + " is not complete for the annotation " +
+                annotationType.getName());
         this.annotationType = annotationType;
         this.elementName = elementName;
     }
diff --git a/annotation/src/main/java/java/lang/annotation/package.html b/annotation/src/main/java/java/lang/annotation/package.html
index 99c98cc..5a150b3 100644
--- a/annotation/src/main/java/java/lang/annotation/package.html
+++ b/annotation/src/main/java/java/lang/annotation/package.html
@@ -5,6 +5,5 @@
       provides some predefined annotations that are used throughout the Android
       libraries.
     </p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/annotation/src/main/java/org/apache/harmony/annotation/internal/nls/Messages.java b/annotation/src/main/java/org/apache/harmony/annotation/internal/nls/Messages.java
deleted file mode 100644
index 91f3548..0000000
--- a/annotation/src/main/java/org/apache/harmony/annotation/internal/nls/Messages.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.annotation.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.annotation.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.annotation.internal.nls.messages";
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/annotation/src/main/java/org/apache/harmony/annotation/internal/nls/messages.properties b/annotation/src/main/java/org/apache/harmony/annotation/internal/nls/messages.properties
deleted file mode 100644
index 613c54d..0000000
--- a/annotation/src/main/java/org/apache/harmony/annotation/internal/nls/messages.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-annotation.0=The element, {0}, is not complete for the annotation {1}.
-annotation.1=The annotation element, {0}, doesn't match the type {1}.
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AllTests.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AllTests.java
index e306435..c2b179e 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AllTests.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AllTests.java
@@ -25,7 +25,7 @@
 public class AllTests {
 
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Test for java.lang.annotation");
+        TestSuite suite = new TestSuite("Test for java.lang.annotation");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AnnotationTest.class);
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationFormatErrorTest.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationFormatErrorTest.java
index c2a32b8a..b80f3a9 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationFormatErrorTest.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationFormatErrorTest.java
@@ -17,29 +17,17 @@
 
 package org.apache.harmony.annotation.tests.java.lang.annotation;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.lang.annotation.AnnotationFormatError;
 
 import junit.framework.TestCase;
 
-import java.lang.annotation.AnnotationFormatError;
-
 /**
  * Test case of java.lang.annotation.AnnotationFormatError
  */
-@TestTargetClass(AnnotationFormatError.class) 
 public class AnnotationFormatErrorTest extends TestCase {
     /**
      * @tests java.lang.annotation.AnnotationFormatError#AnnotationFormatError(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AnnotationFormatError",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_constructorLjava_lang_String() {
         AnnotationFormatError e = new AnnotationFormatError("some message");
@@ -49,12 +37,6 @@
     /**
      * @tests java.lang.annotation.AnnotationFormatError#AnnotationFormatError(Throwable)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AnnotationFormatError",
-        args = {java.lang.Throwable.class}
-    )
     public void test_constructorLjava_lang_Throwable() {
         IllegalArgumentException iae = new IllegalArgumentException();
         AnnotationFormatError e = new AnnotationFormatError(iae);
@@ -64,12 +46,6 @@
     /**
      * @tests java.lang.annotation.AnnotationFormatError#AnnotationFormatError(String,Throwable)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AnnotationFormatError",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
     @SuppressWarnings("nls")
     public void test_constructorLjava_lang_StringLjava_lang_Throwable() {
         IllegalArgumentException iae = new IllegalArgumentException();
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java
index c50c0e8..e9657dec 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.annotation.tests.java.lang.annotation;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
 import junit.framework.TestCase;
 
 import java.lang.annotation.Annotation;
@@ -35,23 +30,8 @@
 /**
  * Test case of java.lang.annotation.Annotation
  */
-@TestTargetClass(value = Annotation.class,
-        untestedMethods = {
-            @TestTargetNew(
-                level = TestLevel.NOT_NECESSARY,
-                notes = "the spec does not require any specific output (although @something is probable)",
-                method = "toString",
-                args = {}
-            )}
-) 
 public class AnnotationTest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "annotationType",
-        args = {}
-    )
     public void test_annotationType() {
         Annotation [] annotations = AnnotatedClass.class.getDeclaredAnnotations();
         assertEquals(1, annotations.length);
@@ -59,20 +39,6 @@
         assertEquals(TestAnnotation1.class, anno.annotationType());
     }
     
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "equals",
-            args = { Object.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "hashCode",
-            args = {}
-        )
-    })
     public void test_equals() throws Exception {
         // test type
         Method m1 = AnnotatedClass2.class
@@ -133,12 +99,6 @@
         }
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() throws SecurityException, NoSuchMethodException { 
         Annotation a1 = AnnotatedClass.class.getDeclaredAnnotations()[0];
         assertEquals(a1.hashCode(), (127 * "value".hashCode() ^ "foobar".hashCode()));
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java
index 5430286..37ee8c1 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java
@@ -17,20 +17,14 @@
 
 package org.apache.harmony.annotation.tests.java.lang.annotation;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.AnnotationTypeMismatchException;
 import java.lang.reflect.Method;
 
+import junit.framework.TestCase;
+
 /**
  * Test case of java.lang.annotation.AnnotationTypeMismatchException
  */
-@TestTargetClass(AnnotationTypeMismatchException.class) 
 public class AnnotationTypeMismatchExceptionTest extends TestCase {
 
     /**
@@ -39,26 +33,6 @@
      * @tests java.lang.annotation.AnnotationTypeMismatchException#AnnotationTypeMismatchException(Method,
      *        String)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "AnnotationTypeMismatchException",
-            args = {java.lang.reflect.Method.class, java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "element",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "foundType",
-            args = {}
-        )
-    })
     @SuppressWarnings("nls")
     public void test_constructorLjava_lang_reflect_MethodLjava_lang_String() throws SecurityException, ClassNotFoundException {
         Method[] methods = Class.forName("java.lang.String").getMethods();
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/ElementTypeTest.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/ElementTypeTest.java
index dec9bf7..d81cabd 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/ElementTypeTest.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/ElementTypeTest.java
@@ -17,32 +17,20 @@
 
 package org.apache.harmony.annotation.tests.java.lang.annotation;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.ElementType;
 import java.util.Arrays;
 
+import junit.framework.TestCase;
+
 /**
  * Test case of java.lang.annotation.ElementType
  */
-@TestTargetClass(ElementType.class)
 public class ElementTypeTest extends TestCase {
 
     /**
      * @throws Exception
      * @tests java.lang.annotation.ElementType#valueOf(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_valueOfLjava_lang_String() throws Exception {
         assertSame(ElementType.ANNOTATION_TYPE, ElementType
@@ -67,12 +55,6 @@
      * @throws Exception
      * @tests java.lang.annotation.ElementType#values()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "values",
-        args = {}
-    )
     @SuppressWarnings("nls")
     public void test_values() throws Exception {
         ElementType[] values = ElementType.values();
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/IncompleteAnnotationExceptionTest.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/IncompleteAnnotationExceptionTest.java
index 5c718ed..d44b90a 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/IncompleteAnnotationExceptionTest.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/IncompleteAnnotationExceptionTest.java
@@ -17,28 +17,19 @@
 
 package org.apache.harmony.annotation.tests.java.lang.annotation;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.lang.annotation.IncompleteAnnotationException;
 
 import junit.framework.TestCase;
 
-import java.lang.annotation.IncompleteAnnotationException;
-
-@TestTargetClass(IncompleteAnnotationException.class)
+/**
+ * 
+ */
 public class IncompleteAnnotationExceptionTest extends TestCase {
 
     /*
      * Class under test for void IncompleteAnnotationException(String)
      * Regression for HARMONY-2477
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Verifies NullPointerException.",
-        method = "IncompleteAnnotationException",
-        args = {java.lang.Class.class, java.lang.String.class}
-    )
     public void testNullType() {
         try {
             new IncompleteAnnotationException(null, "str");
@@ -53,26 +44,6 @@
      * @tests java.lang.annotation.IncompleteAnnotationException#IncompleteAnnotationException(Class,
      *        String)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "IncompleteAnnotationException",
-            args = {java.lang.Class.class, java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "annotationType",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "elementName",
-            args = {}
-        )
-    })
     @SuppressWarnings("nls")
     public void test_constructorLjava_lang_Class_Ljava_lang_String()
             throws Exception {
diff --git a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/RetentionPolicyTest.java b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/RetentionPolicyTest.java
index 1827b7d..c4f7c03 100644
--- a/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/RetentionPolicyTest.java
+++ b/annotation/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/RetentionPolicyTest.java
@@ -17,31 +17,19 @@
 
 package org.apache.harmony.annotation.tests.java.lang.annotation;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 
+import junit.framework.TestCase;
+
 /**
  * Test case of java.lang.annotation.RetentionPolicy
  */
-@TestTargetClass(RetentionPolicy.class)
 public class RetentionPolicyTest extends TestCase {
     /**
      * @throws Exception
      * @tests java.lang.annotation.RetentionPolicy#valueOf(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_valueOfLjava_lang_String() throws Exception {
         assertSame(RetentionPolicy.CLASS, RetentionPolicy
@@ -62,12 +50,6 @@
      * @throws Exception
      * @tests java.lang.annotation.RetentionPolicy#values()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "values",
-        args = {}
-    )
     @SuppressWarnings("nls")
     public void test_values() throws Exception {
         RetentionPolicy[] values = RetentionPolicy.values();
diff --git a/annotation/src/test/java/tests/annotation/AllTests.java b/annotation/src/test/java/tests/annotation/AllTests.java
index 172cc10..c95fe26 100644
--- a/annotation/src/test/java/tests/annotation/AllTests.java
+++ b/annotation/src/test/java/tests/annotation/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the NIO_Char project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Annotation test suites");
+        TestSuite suite = new TestSuite("All Annotation test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.annotation.tests.java.lang.annotation.AllTests.suite());
         // $JUnit-END$
diff --git a/archive/src/main/java/java/util/jar/package.html b/archive/src/main/java/java/util/jar/package.html
index 35eabe7..21103cc 100644
--- a/archive/src/main/java/java/util/jar/package.html
+++ b/archive/src/main/java/java/util/jar/package.html
@@ -7,6 +7,5 @@
       form of a MANIFEST file. This manifest can also be used
       to sign a JAR file.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/archive/src/main/java/java/util/zip/DeflaterInputStream.java b/archive/src/main/java/java/util/zip/DeflaterInputStream.java
new file mode 100644
index 0000000..13d65e4
--- /dev/null
+++ b/archive/src/main/java/java/util/zip/DeflaterInputStream.java
@@ -0,0 +1,243 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * An {@code InputStream} filter to compress data. Callers read
+ * compressed data in the "deflate" format from the uncompressed
+ * underlying stream.
+ * @since 1.6
+ * @hide
+ */
+public class DeflaterInputStream extends FilterInputStream {
+    private static final int DEFAULT_BUFFER_SIZE = 1024;
+
+    protected final Deflater deflater;
+    protected final byte[] buf;
+
+    private boolean closed = false;
+    private boolean available = true;
+
+    /**
+     * Constructs a {@code DeflaterInputStream} with a new {@code Deflater} and an
+     * implementation-defined default internal buffer size. {@code in} is a source of
+     * uncompressed data, and this stream will be a source of compressed data.
+     * 
+     * @param in the source {@code InputStream}
+     */
+    public DeflaterInputStream(InputStream in) {
+        this(in, new Deflater(), DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Constructs a {@code DeflaterInputStream} with the given {@code Deflater} and an
+     * implementation-defined default internal buffer size. {@code in} is a source of
+     * uncompressed data, and this stream will be a source of compressed data.
+     * 
+     * @param in the source {@code InputStream}
+     * @param deflater the {@code Deflater} to be used for compression
+     */
+    public DeflaterInputStream(InputStream in, Deflater deflater) {
+        this(in, deflater, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Constructs a {@code DeflaterInputStream} with the given {@code Deflater} and
+     * given internal buffer size. {@code in} is a source of
+     * uncompressed data, and this stream will be a source of compressed data.
+     * 
+     * @param in the source {@code InputStream}
+     * @param deflater the {@code Deflater} to be used for compression
+     * @param bufferSize the length in bytes of the internal buffer
+     */
+    public DeflaterInputStream(InputStream in, Deflater deflater, int bufferSize) {
+        super(in);
+        if (in == null || deflater == null) {
+            throw new NullPointerException();
+        }
+        if (bufferSize <= 0) {
+            throw new IllegalArgumentException();
+        }
+        this.deflater = deflater;
+        this.buf = new byte[bufferSize];
+    }
+
+    /**
+     * Closes the underlying input stream and discards any remaining uncompressed
+     * data.
+     */
+    @Override
+    public void close() throws IOException {
+        closed = true;
+        deflater.end();
+        in.close();
+    }
+
+    /**
+     * Reads a byte from the compressed input stream. The result will be a byte of compressed
+     * data corresponding to an uncompressed byte or bytes read from the underlying stream.
+     * 
+     * @return the byte or -1 if the end of the stream has been reached.
+     */
+    @Override
+    public int read() throws IOException {
+        byte[] result = new byte[1];
+        if (read(result, 0, 1) == -1) {
+            return -1;
+        }
+        return result[0] & 0xff;
+    }
+
+    /**
+     * Reads compressed data into a byte buffer. The result will be bytes of compressed
+     * data corresponding to an uncompressed byte or bytes read from the underlying stream.
+     * 
+     * @param b
+     *            the byte buffer that compressed data will be read into.
+     * @param off
+     *            the offset in the byte buffer where compressed data will start
+     *            to be read into.
+     * @param len
+     *            the length of the compressed data that is expected to read.
+     * @return the number of bytes read or -1 if the end of the compressed input
+     *         stream has been reached.
+     */
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        checkClosed();
+        if (b == null) {
+            throw new NullPointerException();
+        }
+        if (off < 0 || len < 0 || len > b.length - off) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (len == 0) {
+            return 0;
+        }
+
+        if (!available) {
+            return -1;
+        }
+
+        int count = 0;
+        while (count < len && !deflater.finished()) {
+            if (deflater.needsInput()) {
+                // read data from input stream
+                int byteCount = in.read(buf);
+                if (byteCount == -1) {
+                    deflater.finish();
+                } else {
+                    deflater.setInput(buf, 0, byteCount);
+                }
+            }
+            int byteCount = deflater.deflate(buf, 0, Math.min(buf.length, len - count));
+            if (byteCount == -1) {
+                break;
+            }
+            System.arraycopy(buf, 0, b, off + count, byteCount);
+            count += byteCount;
+        }
+        if (count == 0) {
+            count = -1;
+            available = false;
+        }
+        return count;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>Note: if {@code n > Integer.MAX_VALUE}, this stream will only attempt to
+     * skip {@code Integer.MAX_VALUE} bytes.
+     */
+    @Override
+    public long skip(long n) throws IOException {
+        if (n < 0) {
+            throw new IllegalArgumentException();
+        }
+        if (n > Integer.MAX_VALUE) {
+            n = Integer.MAX_VALUE;
+        }
+        checkClosed();
+
+        int remaining = (int) n;
+        byte[] tmp = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
+        while (remaining > 0) {
+            int count = read(tmp, 0, Math.min(remaining, tmp.length));
+            if (count == -1) {
+                break;
+            }
+            remaining -= count;
+        }
+        return n - remaining;
+    }
+
+    /**
+     * Returns 0 when when this stream has exhausted its input; and 1 otherwise.
+     * A result of 1 does not guarantee that further bytes can be returned,
+     * with or without blocking.
+     * 
+     * <p>Although consistent with the RI, this behavior is inconsistent with
+     * {@link InputStream#available()}, and violates the <a
+     * href="http://en.wikipedia.org/wiki/Liskov_substitution_principle">Liskov
+     * Substitution Principle</a>. This method should not be used.
+     * 
+     * @return 0 if no further bytes are available. Otherwise returns 1,
+     *         which suggests (but does not guarantee) that additional bytes are
+     *         available.
+     * @throws IOException if this stream is closed or an error occurs
+     */
+    @Override
+    public int available() throws IOException {
+        checkClosed();
+        return available ? 1 : 0;
+    }
+
+    /**
+     * Returns false because {@code DeflaterInputStream} does not support
+     * {@code mark}/{@code reset}.
+     */
+    @Override
+    public boolean markSupported() {
+        return false;
+    }
+
+    /**
+     * This operation is not supported and does nothing.
+     */
+    @Override
+    public void mark(int limit) {
+    }
+
+    /**
+     * This operation is not supported and throws {@code IOException}.
+     */
+    @Override
+    public void reset() throws IOException {
+        throw new IOException();
+    }
+
+    private void checkClosed() throws IOException {
+        if (closed) {
+            throw new IOException("Stream is closed");
+        }
+    }
+}
diff --git a/archive/src/main/java/java/util/zip/GZIPInputStream.java b/archive/src/main/java/java/util/zip/GZIPInputStream.java
index dd0da9b..d7f412e 100644
--- a/archive/src/main/java/java/util/zip/GZIPInputStream.java
+++ b/archive/src/main/java/java/util/zip/GZIPInputStream.java
@@ -159,7 +159,7 @@
     @Override
     public int read(byte[] buffer, int off, int nbytes) throws IOException {
         if (closed) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
+            throw new IOException("Stream is closed");
         }
         if (eos) {
             return -1;
diff --git a/archive/src/main/java/java/util/zip/InflaterInputStream.java b/archive/src/main/java/java/util/zip/InflaterInputStream.java
index 8cd8cf2..fcaf8c15 100644
--- a/archive/src/main/java/java/util/zip/InflaterInputStream.java
+++ b/archive/src/main/java/java/util/zip/InflaterInputStream.java
@@ -151,12 +151,8 @@
      */
     @Override
     public int read(byte[] buffer, int off, int nbytes) throws IOException {
-        /* archive.1E=Stream is closed */
-        if (closed) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
-
-        if (null == buffer) {
+        checkClosed();
+        if (buffer == null) {
             throw new NullPointerException();
         }
 
@@ -216,9 +212,7 @@
      *             if an {@code IOException} occurs.
      */
     protected void fill() throws IOException {
-        if (closed) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         // BEGIN android-only
         if (nativeEndBufSize > 0) {
             ZipFile.RAFStream is = (ZipFile.RAFStream)in;
@@ -283,10 +277,7 @@
      */
     @Override
     public int available() throws IOException {
-        if (closed) {
-            // archive.1E=Stream is closed
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         if (eof) {
             return 0;
         }
@@ -345,4 +336,9 @@
         return false;
     }
 
+    private void checkClosed() throws IOException {
+        if (closed) {
+            throw new IOException("Stream is closed");
+        }
+    }
 }
diff --git a/archive/src/main/java/java/util/zip/InflaterOutputStream.java b/archive/src/main/java/java/util/zip/InflaterOutputStream.java
new file mode 100644
index 0000000..1329393
--- /dev/null
+++ b/archive/src/main/java/java/util/zip/InflaterOutputStream.java
@@ -0,0 +1,171 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An {@code OutputStream} filter to decompress data. Callers write
+ * compressed data in the "deflate" format, and uncompressed data is
+ * written to the underlying stream.
+ * @since 1.6
+ * @hide
+ */
+public class InflaterOutputStream extends FilterOutputStream {
+    private static final int DEFAULT_BUFFER_SIZE = 1024;
+
+    protected final Inflater inflater;
+    protected final byte[] buf;
+
+    private boolean closed = false;
+
+    /**
+     * Constructs an {@code InflaterOutputStream} with a new {@code Inflater} and an
+     * implementation-defined default internal buffer size. {@code out} is a destination
+     * for uncompressed data, and compressed data will be written to this stream.
+     * 
+     * @param out the destination {@code OutputStream}
+     */
+    public InflaterOutputStream(OutputStream out) {
+        this(out, new Inflater());
+    }
+
+    /**
+     * Constructs an {@code InflaterOutputStream} with the given {@code Inflater} and an
+     * implementation-defined default internal buffer size. {@code out} is a destination
+     * for uncompressed data, and compressed data will be written to this stream.
+     * 
+     * @param out the destination {@code OutputStream}
+     * @param inflater the {@code Inflater} to be used for decompression
+     */
+    public InflaterOutputStream(OutputStream out, Inflater inflater) {
+        this(out, inflater, DEFAULT_BUFFER_SIZE);
+    }
+
+    /**
+     * Constructs an {@code InflaterOutputStream} with the given {@code Inflater} and
+     * given internal buffer size. {@code out} is a destination
+     * for uncompressed data, and compressed data will be written to this stream.
+     * 
+     * @param out the destination {@code OutputStream}
+     * @param inflater the {@code Inflater} to be used for decompression
+     * @param bufferSize the length in bytes of the internal buffer
+     */
+    public InflaterOutputStream(OutputStream out, Inflater inflater, int bufferSize) {
+        super(out);
+        if (out == null || inflater == null) {
+            throw new NullPointerException();
+        }
+        if (bufferSize <= 0) {
+            throw new IllegalArgumentException();
+        }
+        this.inflater = inflater;
+        this.buf = new byte[bufferSize];
+    }
+
+    /**
+     * Writes remaining data into the output stream and closes the underlying
+     * output stream.
+     */
+    @Override
+    public void close() throws IOException {
+        if (!closed) {
+            finish();
+            inflater.end();
+            out.close();
+            closed = true;
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        finish();
+        out.flush();
+    }
+
+    /**
+     * Finishes writing current uncompressed data into the InflaterOutputStream
+     * without closing it.
+     * 
+     * @throws IOException if an I/O error occurs, or the stream has been closed
+     */
+    public void finish() throws IOException {
+        checkClosed();
+        write();
+    }
+
+    /**
+     * Writes a byte to the decompressing output stream. {@code b} should be a byte of
+     * compressed input. The corresponding uncompressed data will be written to the underlying
+     * stream.
+     * 
+     * @param b the byte
+     * @throws IOException if an I/O error occurs, or the stream has been closed
+     * @throws ZipException if a zip exception occurs.
+     */
+    @Override
+    public void write(int b) throws IOException, ZipException {
+        write(new byte[] { (byte) b }, 0, 1);
+    }
+
+    /**
+     * Writes bytes to the decompressing output stream. {@code b} should be an array of
+     * compressed input. The corresponding uncompressed data will be written to the underlying
+     * stream.
+     * 
+     * @param b the byte array
+     * @param off the start offset in the byte array
+     * @param len the number of the bytes to take from the byte array
+     * @throws IOException if an I/O error occurs, or the stream has been closed
+     * @throws ZipException if a zip exception occurs.
+     * @throws NullPointerException if {@code b == null}.
+     * @throws IndexOutOfBoundsException if {@code off < 0 || len < 0 || off + len > b.length}
+     */
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException, ZipException {
+        checkClosed();
+        if (b == null) {
+            throw new NullPointerException();
+        }
+        if (off < 0 || len < 0 || len > b.length - off) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        inflater.setInput(b, off, len);
+        write();
+    }
+
+    private void write() throws IOException, ZipException {
+        try {
+            int inflated;
+            while ((inflated = inflater.inflate(buf)) > 0) {
+                out.write(buf, 0, inflated);
+            }
+        } catch (DataFormatException e) {
+            throw new ZipException();
+        }
+    }
+
+    private void checkClosed() throws IOException {
+        if (closed) {
+            throw new IOException();
+        }
+    }
+}
diff --git a/archive/src/main/java/java/util/zip/ZipConstants.java b/archive/src/main/java/java/util/zip/ZipConstants.java
index 9fbce06..4ce65bc 100644
--- a/archive/src/main/java/java/util/zip/ZipConstants.java
+++ b/archive/src/main/java/java/util/zip/ZipConstants.java
@@ -17,6 +17,11 @@
 
 package java.util.zip;
 
+/**
+ * Do not add constants to this interface! It's implemented by the classes
+ * in this package whose names start "Zip", and the constants are thereby
+ * public API.
+ */
 interface ZipConstants {
 
     public static final long LOCSIG = 0x4034b50, EXTSIG = 0x8074b50,
diff --git a/archive/src/main/java/java/util/zip/ZipEntry.java b/archive/src/main/java/java/util/zip/ZipEntry.java
index 75466ce..d68aa2f 100644
--- a/archive/src/main/java/java/util/zip/ZipEntry.java
+++ b/archive/src/main/java/java/util/zip/ZipEntry.java
@@ -400,20 +400,16 @@
         }
 
         try {
-            /*
-             * The actual character set is "IBM Code Page 437".  As of
-             * Sep 2006, the Zip spec (APPNOTE.TXT) supports UTF-8.  When
-             * bit 11 of the GP flags field is set, the file name and
-             * comment fields are UTF-8.
-             *
-             * TODO: add correct UTF-8 support.
-             */
-            name = new String(nameBytes, "ISO-8859-1");
+            // BEGIN android-changed
+            // The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is
+            // actually IBM-437.)
+            name = new String(nameBytes, "UTF-8");
             if (commentBytes != null) {
-                comment = new String(commentBytes, "ISO-8859-1");
+                comment = new String(commentBytes, "UTF-8");
             } else {
                 comment = null;
             }
+            // END android-changed
         } catch (UnsupportedEncodingException uee) {
             throw new InternalError(uee.getMessage());
         }
diff --git a/archive/src/main/java/java/util/zip/ZipError.java b/archive/src/main/java/java/util/zip/ZipError.java
new file mode 100644
index 0000000..a244d80
--- /dev/null
+++ b/archive/src/main/java/java/util/zip/ZipError.java
@@ -0,0 +1,34 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+/**
+ * Thrown when an unrecoverable ZIP error has occurred.
+ * @since 1.6
+ * @hide
+ */
+public class ZipError extends InternalError {
+    private static final long serialVersionUID = 853973422266861979L;
+
+    /**
+     * Constructs a ZipError with the given detail message.
+     */
+    public ZipError(String s) {
+        super(s);
+    }
+}
diff --git a/archive/src/main/java/java/util/zip/ZipFile.java b/archive/src/main/java/java/util/zip/ZipFile.java
index 48541e1..a2ca35a 100644
--- a/archive/src/main/java/java/util/zip/ZipFile.java
+++ b/archive/src/main/java/java/util/zip/ZipFile.java
@@ -43,6 +43,26 @@
  * @see ZipOutputStream
  */
 public class ZipFile implements ZipConstants {
+    /**
+     * General Purpose Bit Flags, Bit 3.
+     * If this bit is set, the fields crc-32, compressed
+     * size and uncompressed size are set to zero in the
+     * local header.  The correct values are put in the
+     * data descriptor immediately following the compressed
+     * data.  (Note: PKZIP version 2.04g for DOS only
+     * recognizes this bit for method 8 compression, newer
+     * versions of PKZIP recognize this bit for any
+     * compression method.)
+     */
+    static final int GPBF_DATA_DESCRIPTOR_FLAG = 1 << 3; // android-added
+
+    /**
+     * General Purpose Bit Flags, Bit 11.
+     * Language encoding flag (EFS).  If this bit is set,
+     * the filename and comment fields for this file
+     * must be encoded using UTF-8.
+     */
+    static final int GPBF_UTF8_FLAG = 1 << 11; // android-added
 
     /**
      * Open ZIP file for read.
@@ -161,7 +181,7 @@
 
     private void checkNotClosed() {
         if (mRaf == null) {
-            throw new IllegalStateException("Zip File closed.");
+            throw new IllegalStateException("Zip file closed");
         }
     }
 
@@ -438,6 +458,12 @@
 
         @Override
         public int available() throws IOException {
+            if (closed) {
+                // Our superclass will throw an exception, but there's a jtreg test that
+                // explicitly checks that the InputStream returned from ZipFile.getInputStream
+                // returns 0 even when closed.
+                return 0;
+            }
             return super.available() == 0 ? 0 : (int) (entry.getSize() - bytesRead);
         }
     }
diff --git a/archive/src/main/java/java/util/zip/ZipInputStream.java b/archive/src/main/java/java/util/zip/ZipInputStream.java
index e547612..14141e9 100644
--- a/archive/src/main/java/java/util/zip/ZipInputStream.java
+++ b/archive/src/main/java/java/util/zip/ZipInputStream.java
@@ -49,8 +49,6 @@
 
     static final int STORED = 0;
 
-    static final int ZIPDataDescriptorFlag = 8;
-
     static final int ZIPLocalHeaderVersionNeeded = 20;
 
     private boolean entriesEnd = false;
@@ -105,15 +103,13 @@
      *             if an {@code IOException} occurs.
      */
     public void closeEntry() throws IOException {
-        if (closed) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         if (currentEntry == null) {
             return;
         }
         if (currentEntry instanceof java.util.jar.JarEntry) {
             Attributes temp = ((JarEntry) currentEntry).getAttributes();
-            if (temp != null && temp.containsKey("hidden")) { //$NON-NLS-1$
+            if (temp != null && temp.containsKey("hidden")) {
                 return;
             }
         }
@@ -236,7 +232,7 @@
             throw new ZipException(Messages.getString("archive.22")); //$NON-NLS-1$
         }
         int flags = getShort(hdrBuf, LOCFLG - LOCVER);
-        hasDD = ((flags & ZIPDataDescriptorFlag) == ZIPDataDescriptorFlag);
+        hasDD = ((flags & ZipFile.GPBF_DATA_DESCRIPTOR_FLAG) != 0);
         int cetime = getShort(hdrBuf, LOCTIM - LOCVER);
         int cemodDate = getShort(hdrBuf, LOCTIM - LOCVER + 2);
         int cecompressionMethod = getShort(hdrBuf, LOCHOW - LOCVER);
@@ -303,9 +299,7 @@
      */
     @Override
     public int read(byte[] buffer, int start, int length) throws IOException {
-        if (closed) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         if (inf.finished() || currentEntry == null) {
             return -1;
         }
@@ -387,9 +381,7 @@
 
     @Override
     public int available() throws IOException {
-        if (closed) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         // The InflaterInputStream contract says we must only return 0 or 1.
         return (currentEntry == null || inRead < currentEntry.size) ? 1 : 0;
     }
@@ -417,4 +409,10 @@
         l |= ((long) (buffer[off + 3] & 0xFF)) << 24;
         return l;
     }
+
+    private void checkClosed() throws IOException {
+        if (closed) {
+            throw new IOException("Stream is closed");
+        }
+    }
 }
diff --git a/archive/src/main/java/java/util/zip/ZipOutputStream.java b/archive/src/main/java/java/util/zip/ZipOutputStream.java
index 21b4221..3a9bd7e 100644
--- a/archive/src/main/java/java/util/zip/ZipOutputStream.java
+++ b/archive/src/main/java/java/util/zip/ZipOutputStream.java
@@ -54,8 +54,6 @@
      */
     public static final int STORED = 0;
 
-    static final int ZIPDataDescriptorFlag = 8;
-
     static final int ZIPLocalHeaderVersionNeeded = 20;
 
     private String comment;
@@ -111,9 +109,7 @@
      *             If an error occurs closing the entry.
      */
     public void closeEntry() throws IOException {
-        if (cDir == null) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         if (currentEntry == null) {
             return;
         }
@@ -141,11 +137,12 @@
             writeLong(out, currentEntry.size = def.getTotalIn());
         }
         // Update the CentralDirectory
+        // http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+        int flags = currentEntry.getMethod() == STORED ? 0 : ZipFile.GPBF_DATA_DESCRIPTOR_FLAG;
         writeLong(cDir, CENSIG);
         writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version created
         writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version to extract
-        writeShort(cDir, currentEntry.getMethod() == STORED ? 0
-                : ZIPDataDescriptorFlag);
+        writeShort(cDir, flags);
         writeShort(cDir, currentEntry.getMethod());
         writeShort(cDir, currentEntry.time);
         writeShort(cDir, currentEntry.modDate);
@@ -197,8 +194,9 @@
      */
     @Override
     public void finish() throws IOException {
+        // TODO: is there a bug here? why not checkClosed?
         if (out == null) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
+            throw new IOException("Stream is closed");
         }
         if (cDir == null) {
             return;
@@ -262,10 +260,7 @@
                 throw new ZipException(Messages.getString("archive.21")); //$NON-NLS-1$
             }
         }
-        /* [MSG "archive.1E", "Stream is closed"] */
-        if (cDir == null) {
-            throw new IOException(Messages.getString("archive.1E")); //$NON-NLS-1$
-        }
+        checkClosed();
         if (entries.contains(ze.name)) {
             /* [MSG "archive.29", "Entry already exists: {0}"] */
             throw new ZipException(Messages.getString("archive.29", ze.name)); //$NON-NLS-1$
@@ -283,16 +278,23 @@
         if (currentEntry.getMethod() == -1) {
             currentEntry.setMethod(compressMethod);
         }
+        // BEGIN android-changed
+        // Local file header.
+        // http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+        int flags = currentEntry.getMethod() == STORED ? 0 : ZipFile.GPBF_DATA_DESCRIPTOR_FLAG;
+        // Java always outputs UTF-8 filenames. (Before Java 7, the RI didn't set this flag and used
+        // modified UTF-8. From Java 7, it sets this flag and uses normal UTF-8.)
+        flags |= ZipFile.GPBF_UTF8_FLAG;
         writeLong(out, LOCSIG); // Entry header
         writeShort(out, ZIPLocalHeaderVersionNeeded); // Extraction version
-        writeShort(out, currentEntry.getMethod() == STORED ? 0
-                : ZIPDataDescriptorFlag);
+        writeShort(out, flags);
         writeShort(out, currentEntry.getMethod());
         if (currentEntry.getTime() == -1) {
             currentEntry.setTime(System.currentTimeMillis());
         }
         writeShort(out, currentEntry.time);
         writeShort(out, currentEntry.modDate);
+        // END android-changed
 
         if (currentEntry.getMethod() == STORED) {
             if (currentEntry.size == -1) {
@@ -444,4 +446,10 @@
         }
         return result;
     }
+
+    private void checkClosed() throws IOException {
+        if (cDir == null) {
+            throw new IOException("Stream is closed");
+        }
+    }
 }
diff --git a/archive/src/main/java/java/util/zip/package.html b/archive/src/main/java/java/util/zip/package.html
index 2a09bf1..8b4f91b 100644
--- a/archive/src/main/java/java/util/zip/package.html
+++ b/archive/src/main/java/java/util/zip/package.html
@@ -4,6 +4,5 @@
       This package contains classes for compressing and decompressing data in 
       ZIP and GZIP file formats.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/archive/src/main/native/java_util_zip_Adler32.c b/archive/src/main/native/java_util_zip_Adler32.c
index 0fcf549..4410e5b 100644
--- a/archive/src/main/native/java_util_zip_Adler32.c
+++ b/archive/src/main/native/java_util_zip_Adler32.c
@@ -43,17 +43,10 @@
   return adler32 ((uLong) crc, (Bytef *) (&bytefVal), 1);
 }
 
-
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "updateImpl", "([BIIJ)J",     Java_java_util_zip_Adler32_updateImpl },
     { "updateByteImpl", "(IJ)J",     Java_java_util_zip_Adler32_updateByteImpl },
 };
-int register_java_util_zip_Adler32(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/util/zip/Adler32",
-                gMethods, NELEM(gMethods));
+int register_java_util_zip_Adler32(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/util/zip/Adler32", gMethods, NELEM(gMethods));
 }
diff --git a/archive/src/main/native/java_util_zip_CRC32.c b/archive/src/main/native/java_util_zip_CRC32.c
index fe50fca..95369a2 100644
--- a/archive/src/main/native/java_util_zip_CRC32.c
+++ b/archive/src/main/native/java_util_zip_CRC32.c
@@ -41,17 +41,10 @@
   return crc32 ((uLong) crc, (Bytef *) (&val), 1);
 }
 
-
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "updateImpl", "([BIIJ)J",     Java_java_util_zip_CRC32_updateImpl },
     { "updateByteImpl", "(BJ)J",     Java_java_util_zip_CRC32_updateByteImpl },
 };
-int register_java_util_zip_CRC32(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/util/zip/CRC32",
-                gMethods, NELEM(gMethods));
+int register_java_util_zip_CRC32(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/util/zip/CRC32", gMethods, NELEM(gMethods));
 }
diff --git a/archive/src/main/native/java_util_zip_Deflater.c b/archive/src/main/native/java_util_zip_Deflater.c
index af0bfcc..59c7433 100644
--- a/archive/src/main/native/java_util_zip_Deflater.c
+++ b/archive/src/main/native/java_util_zip_Deflater.c
@@ -286,11 +286,7 @@
     gCachedFields.finished = (*env)->GetFieldID (env, clazz, "finished", "Z");
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "setDictionaryImpl", "([BIIJ)V",     Java_java_util_zip_Deflater_setDictionaryImpl },
     { "getTotalInImpl", "(J)J",     Java_java_util_zip_Deflater_getTotalInImpl },
     { "getTotalOutImpl", "(J)J",     Java_java_util_zip_Deflater_getTotalOutImpl },
@@ -303,8 +299,6 @@
     { "setLevelsImpl", "(IIJ)V",     Java_java_util_zip_Deflater_setLevelsImpl },
     { "oneTimeInitialization", "()V",     Java_java_util_zip_Deflater_oneTimeInitialization },
 };
-int register_java_util_zip_Deflater(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/util/zip/Deflater",
-                gMethods, NELEM(gMethods));
+int register_java_util_zip_Deflater(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/util/zip/Deflater", gMethods, NELEM(gMethods));
 }
diff --git a/archive/src/main/native/java_util_zip_Inflater.c b/archive/src/main/native/java_util_zip_Inflater.c
index ba89ce8..6281081 100644
--- a/archive/src/main/native/java_util_zip_Inflater.c
+++ b/archive/src/main/native/java_util_zip_Inflater.c
@@ -322,11 +322,7 @@
     gCachedFields.needsDictionary = (*env)->GetFieldID (env, clazz, "needsDictionary", "Z");
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "createStream", "(Z)J",     Java_java_util_zip_Inflater_createStream },
     { "setInputImpl", "([BIIJ)V",     Java_java_util_zip_Inflater_setInputImpl },
     { "setFileInputImpl", "(Ljava/io/FileDescriptor;JIJ)I",     Java_java_util_zip_Inflater_setFileInputImpl },
@@ -339,8 +335,6 @@
     { "getTotalInImpl", "(J)J",     Java_java_util_zip_Inflater_getTotalInImpl },
     { "oneTimeInitialization", "()V",     Java_java_util_zip_Inflater_oneTimeInitialization },
 };
-int register_java_util_zip_Inflater(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/util/zip/Inflater",
-                gMethods, NELEM(gMethods));
+int register_java_util_zip_Inflater(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/util/zip/Inflater", gMethods, NELEM(gMethods));
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AllTests.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AllTests.java
index 13fe019..7b39de6 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AllTests.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AllTests.java
@@ -24,13 +24,8 @@
  * Test suite for java.util.jar package.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
+        TestSuite suite = new TestSuite(
                 "Suite org.apache.harmony.archive.tests.java.util.jar");
         suite.addTestSuite(AttributesNameTest.class);
         suite.addTestSuite(AttributesTest.class);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesNameTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesNameTest.java
index 067bf49..efeb128 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesNameTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesNameTest.java
@@ -17,26 +17,14 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.util.jar.Attributes;
 import junit.framework.TestCase;
 
-@TestTargetClass(Attributes.Name.class)
 public class AttributesNameTest extends TestCase {
 
     /**
      * @tests java.util.jar.Attributes.Name#Name(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Name",
-        args = {java.lang.String.class}
-    )
     public void test_AttributesName_Constructor() {
         // Regression for HARMONY-85
         try {
@@ -57,12 +45,6 @@
         assertNotNull(new Attributes.Name("Attr"));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         Attributes.Name attr1 = new Attributes.Name("Attr");
         Attributes.Name attr2 = new Attributes.Name("Attr");
@@ -72,12 +54,6 @@
         assertFalse(attr1.equals(attr2));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         Attributes.Name attr1 = new Attributes.Name("Attr1");
         Attributes.Name attr2 = new Attributes.Name("Attr2");
@@ -85,12 +61,6 @@
         assertNotSame(attr1.hashCode(), attr2.hashCode());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         String str1 = "Attr1";
         String str2 = "Attr2";
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesTest.java
index 0b3d2cf..f437d20 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/AttributesTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -31,7 +26,6 @@
 import java.util.jar.Attributes;
 import junit.framework.TestCase;
 
-@TestTargetClass(Attributes.class)
 public class AttributesTest extends TestCase {
     private Attributes a;
 
@@ -47,12 +41,6 @@
     /**
      * @tests java.util.jar.Attributes#Attributes(java.util.jar.Attributes)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Attributes",
-        args = {java.util.jar.Attributes.class}
-    )
     public void test_ConstructorLjava_util_jar_Attributes() {
         Attributes a2 = new Attributes(a);
         assertEquals(a, a2);
@@ -63,12 +51,6 @@
     /**
      * @tests java.util.jar.Attributes#clear()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clear",
-        args = {}
-    )
     public void test_clear() {
         a.clear();
         assertNull("a) All entries should be null after clear", a.get("1"));
@@ -81,12 +63,6 @@
     /**
      * @tests java.util.jar.Attributes#containsKey(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "containsKey",
-        args = {java.lang.Object.class}
-    )
     public void test_containsKeyLjava_lang_Object() {
         assertTrue("a) Should have returned false", !a.containsKey(new Integer(
                 1)));
@@ -98,12 +74,6 @@
     /**
      * @tests java.util.jar.Attributes#containsValue(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "containsValue",
-        args = {java.lang.Object.class}
-    )
     public void test_containsValueLjava_lang_Object() {
         assertTrue("Should have returned false", !a.containsValue("One"));
         assertTrue("Should have returned true", a.containsValue("one"));
@@ -112,12 +82,6 @@
     /**
      * @tests java.util.jar.Attributes#entrySet()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entrySet",
-        args = {}
-    )
     public void test_entrySet() {
         Set<Map.Entry<Object, Object>> entrySet = a.entrySet();
         Set<Object> keySet = new HashSet<Object>();
@@ -148,12 +112,6 @@
     /**
      * @tests java.util.jar.Attributes#get(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getValue",
-        args = {java.lang.String.class}
-    )
     public void test_getLjava_lang_Object() {
         assertEquals("a) Incorrect value returned", "one", a.getValue("1"));
         assertNull("b) Incorrect value returned", a.getValue("0"));
@@ -168,12 +126,6 @@
     /**
      * @tests java.util.jar.Attributes#isEmpty()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isEmpty",
-        args = {}
-    )
     public void test_isEmpty() {
         assertTrue("Should not be empty", !a.isEmpty());
         a.clear();
@@ -185,12 +137,6 @@
     /**
      * @tests java.util.jar.Attributes#keySet()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "keySet",
-        args = {}
-    )
     public void test_keySet() {
         Set<?> s = a.keySet();
         assertEquals(4, s.size());
@@ -207,12 +153,6 @@
     /**
      * @tests java.util.jar.Attributes#putAll(java.util.Map)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "putAll",
-        args = {java.util.Map.class}
-    )
     public void test_putAllLjava_util_Map() {
         Attributes b = new Attributes();
         b.putValue("3", "san");
@@ -245,12 +185,6 @@
     /**
      * @tests java.util.jar.Attributes#putAll(java.util.Map)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test",
-        method = "putAll",
-        args = {java.util.Map.class}
-    )
     public void test_putAllLjava_util_Map2() {
         // Regression for HARMONY-464
         try {
@@ -275,12 +209,6 @@
     /**
      * @tests java.util.jar.Attributes#remove(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "remove",
-        args = {java.lang.Object.class}
-    )
     public void test_removeLjava_lang_Object() {
         a.remove(new Attributes.Name("1"));
         a.remove(new Attributes.Name("3"));
@@ -291,12 +219,6 @@
     /**
      * @tests java.util.jar.Attributes#size()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "size",
-        args = {}
-    )
     public void test_size() {
         assertEquals("Incorrect size returned", 4, a.size());
         a.clear();
@@ -306,12 +228,6 @@
     /**
      * @tests java.util.jar.Attributes#values()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "values",
-        args = {}
-    )
     public void test_values() {
         Collection<?> valueCollection = a.values();
         assertTrue("a) Should contain entry", valueCollection.contains("one"));
@@ -323,12 +239,6 @@
     /**
      * @tests java.util.jar.Attributes#clone()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clone",
-        args = {}
-    )
     public void test_clone() {
         Attributes a2 = (Attributes) a.clone();
         assertEquals(a, a2);
@@ -339,12 +249,6 @@
     /**
      * @tests java.util.jar.Attributes#equals(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         Attributes.Name n1 = new Attributes.Name("name"), n2 = new Attributes.Name(
                 "Name");
@@ -361,12 +265,6 @@
     /**
      * @tests java.util.jar.Attributes.put(java.lang.Object, java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test. Checks ClassCastException",
-        method = "put",
-        args = {java.lang.Object.class, java.lang.Object.class}
-    )
     public void test_putLjava_lang_ObjectLjava_lang_Object() {
         Attributes atts = new Attributes();
         assertNull("Assert 0: ", atts.put(Attributes.Name.CLASS_PATH,
@@ -391,12 +289,6 @@
     /**
      * @tests java.util.jar.Attributes.put(java.lang.Object, java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "ClassCastException checking missed.",
-        method = "put",
-        args = {java.lang.Object.class, java.lang.Object.class}
-    )
     public void test_putLjava_lang_ObjectLjava_lang_Object_Null() {
 
         Attributes attribute = new Attributes();
@@ -424,12 +316,6 @@
     /**
      * @tests java.util.jar.Attributes.hashCode()
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "hashCode",
-            args = {}
-    )
     public void test_hashCode_consistent_with_map() {
         MockAttributes mockAttr = new MockAttributes();
         mockAttr.putValue("1", "one");
@@ -442,34 +328,16 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Attributes",
-        args = {}
-    )
     public void test_Constructor() {
         Attributes attr = new Attributes();
         assertTrue(attr.size() >= 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Attributes",
-        args = {int.class}
-    )
     public void test_ConstructorI() {
         Attributes attr = new Attributes(10);
         assertTrue(attr.size() >= 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "get",
-        args = {java.lang.Object.class}
-    )
     public void test_getLjava_lang_Object_true() {
         assertEquals("a) Incorrect value returned", "one", a
                 .get(new Attributes.Name("1")));
@@ -477,12 +345,6 @@
         assertNull("b) Incorrect value returned", a.get("1"));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getValue",
-        args = {java.util.jar.Attributes.Name.class}
-    )
     public void test_getValueLjava_util_jar_Attributes_Name() {
         assertEquals("a) Incorrect value returned", "one", a
                 .getValue(new Attributes.Name("1")));
@@ -490,12 +352,6 @@
                 .getValue(new Attributes.Name("0")));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         Attributes b = (Attributes) a.clone();
         b.putValue("33", "Thirty three");
@@ -505,12 +361,6 @@
         assertNotSame(a.hashCode(), b.hashCode());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "putValue",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void test_putValueLjava_lang_StringLjava_lang_String() {
         Attributes b = new Attributes();
         b.put(new Attributes.Name("1"), "one");
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
index 601fe42..a8c6148 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/DalvikExecTest.java
@@ -16,11 +16,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
 import junit.framework.TestCase;
 import static tests.support.Support_Exec.execAndGetOutput;
 import tests.support.resource.Support_Resources;
@@ -37,8 +32,6 @@
 import java.util.jar.Manifest;
 
 
-@TestTargetClass(JarOutputStream.class)
-@AndroidOnly("dalvik vm specific")
 public class DalvikExecTest extends TestCase {
 
     String execDalvik1(String classpath, String mainClass, String arg1)
@@ -78,15 +71,7 @@
         return execDalvik1(classpath, mainClass, null);
     }
 
-    @TestTargets ({
-        @TestTargetNew(
-            level = TestLevel.ADDITIONAL,
-            notes = "Execute an existing JAR on dalvikvm using -classpath option.",
-            clazz = Runtime.class,
-            method = "exec",
-            args = {java.lang.String[].class}
-        )
-    })
+    // Execute an existing JAR on dalvikvm using -classpath option.",
     public void test_execExistingJar () throws IOException, InterruptedException {
         String res;
         File jarFile;
@@ -113,26 +98,7 @@
         }
     }
 
-
-    @TestTargets ({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "putNextEntry",
-            args = {java.util.zip.ZipEntry.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.ADDITIONAL,
-            method = "JarOutputStream",
-            args = {java.io.OutputStream.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.ADDITIONAL,
-            notes = "Create a temp file, fill it with contents according to Dalvik JAR format, and execute it on dalvikvm using -classpath option.",
-            clazz = Runtime.class,
-            method = "exec",
-            args = {java.lang.String[].class}
-        )
-    })
+    // Create a temp file, fill it with contents according to Dalvik JAR format, and execute it on dalvikvm using -classpath option.",
     public void test_execCreatedJar () throws IOException, InterruptedException {
         File jarFile = File.createTempFile("cts_dalvikExecTest_", ".jar");
         jarFile.deleteOnExit();
@@ -171,24 +137,6 @@
     }
 
 
-    @TestTargets ({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "putNextEntry",
-            args = {java.util.zip.ZipEntry.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "JarOutputStream",
-            args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.ADDITIONAL,
-            clazz = Runtime.class,
-            method = "exec",
-            args = {java.lang.String[].class}
-        )
-    })
     /**
      * This test does quite the same as test_execCreatedJar, but includes a manifest.
      * Note however that the Dalvik JAR format does not require this manifest.
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarEntryTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarEntryTest.java
index 90144be..e179024 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarEntryTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarEntryTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -35,7 +30,6 @@
 import tests.support.resource.Support_Resources;
 
 
-@TestTargetClass(JarEntry.class)
 public class JarEntryTest extends TestCase {
     private ZipEntry zipEntry;
 
@@ -75,12 +69,6 @@
      * @throws IOException
      * @tests java.util.jar.JarEntry#JarEntry(java.util.jar.JarEntry)
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "JarEntry",
-            args = {java.util.jar.JarEntry.class}
-    )
     public void test_ConstructorLjava_util_jar_JarEntry_on_null() throws IOException {
         JarEntry newJarEntry = new JarEntry(jarFile.getJarEntry(entryName));
         assertNotNull(newJarEntry);
@@ -97,12 +85,6 @@
     /**
      * @tests java.util.jar.JarEntry#JarEntry(java.util.zip.ZipEntry)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarEntry",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_ConstructorLjava_util_zip_ZipEntry() {
         assertNotNull("Jar file is null", jarFile);
         zipEntry = jarFile.getEntry(entryName);
@@ -118,12 +100,6 @@
     /**
      * @tests java.util.jar.JarEntry#getAttributes()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAttributes",
-        args = {}
-    )
     public void test_getAttributes() {
         JarFile attrJar = null;
         File file = null;
@@ -165,12 +141,6 @@
     /**
      * @tests java.util.jar.JarEntry#getCertificates()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCertificates",
-        args = {}
-    )
     public void test_getCertificates() throws Exception {
         zipEntry = jarFile.getEntry(entryName2);
         jarEntry = new JarEntry(zipEntry);
@@ -206,12 +176,6 @@
     /**
      * @tests java.util.jar.JarEntry#getCodeSigners()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCodeSigners",
-        args = {}
-    )
     public void test_getCodeSigners() throws IOException {
         String jarFileName = "TestCodeSigners.jar";
         Support_Resources.copyFile(resources, null, jarFileName);
@@ -247,12 +211,6 @@
                 new JarEntry("aaa").getCodeSigners());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarEntry",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         assertNotNull("Jar file is null", jarFile);
         zipEntry = jarFile.getEntry(entryName);
@@ -279,12 +237,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "JarEntry",
-        args = {java.util.jar.JarEntry.class}
-    )
     public void test_ConstructorLjava_util_jar_JarEntry() {
         assertNotNull("Jar file is null", jarFile);
         JarEntry je = jarFile.getJarEntry(entryName);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExceptionTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExceptionTest.java
index 7f48342..9a0caf4 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExceptionTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExceptionTest.java
@@ -17,28 +17,16 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.jar.Manifest;
 import junit.framework.TestCase;
 import java.util.jar.JarException;
 
-@TestTargetClass(JarException.class)
 public class JarExceptionTest extends TestCase {
     /**
      * @tests java.util.jar.JarException#JarException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarException",
-        args = {}
-    )
     public void test_Constructor() throws Exception {
         JarException ex = new JarException();
         JarException ex1 = new JarException("Test string");
@@ -49,12 +37,6 @@
         assertSame(ex.getMessage(), ex2.getMessage());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() throws Exception {
         JarException ex1 = new JarException("Test string");
         JarException ex2 = new JarException(null);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
index 01f5a8c..e2a11c7 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarExecTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 import static tests.support.Support_Exec.execAndGetOutput;
 import static tests.support.Support_Exec.javaProcessBuilder;
 import tests.support.resource.Support_Resources;
@@ -40,19 +36,11 @@
  * 
  */
 
-@TestTargetClass(JarOutputStream.class)
 public class JarExecTest extends junit.framework.TestCase {
     /**
      * regression test for HARMONY-1562 issue
      * 
      */
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression functional test. Exception checking missed.",
-        method = "putNextEntry",
-        args = {java.util.zip.ZipEntry.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_1562() throws Exception {
         // create the manifest
         Manifest man = new Manifest();
@@ -87,13 +75,6 @@
      * 
      * @throws Exception in case of troubles
      */
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "JarOutputStream",
-        args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_jar_class_path() throws Exception {
         File fooJar = File.createTempFile("hyts_", ".jar");
         File barJar = File.createTempFile("hyts_", ".jar");
@@ -159,13 +140,6 @@
      * 
      * @throws Exception in case of troubles
      */
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "JarOutputStream",
-        args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_main_class_in_another_jar() throws Exception {
         File fooJar = File.createTempFile("hyts_", ".jar");
         File barJar = File.createTempFile("hyts_", ".jar");
@@ -201,13 +175,6 @@
                 execAndGetOutput(builder).startsWith("FOOBAR"));
     }
 
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "JarOutputStream",
-        args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_classpath() throws Exception {
         File resources = Support_Resources.createTempFolder();
 
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
index d2a5110..67debfc 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarFileTest.java
@@ -17,11 +17,6 @@
 package org.apache.harmony.archive.tests.java.util.jar;
 
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import tests.support.Support_PlatformFile;
@@ -47,7 +42,6 @@
 import java.util.zip.ZipFile;
 
 
-@TestTargetClass(JarFile.class)
 public class JarFileTest extends TestCase {
 
     // BEGIN android-added
@@ -112,12 +106,6 @@
     /**
      * @tests java.util.jar.JarFile#JarFile(java.io.File)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "JarFile",
-        args = {java.io.File.class}
-    )
     public void test_ConstructorLjava_io_File() {
         try {
             JarFile jarFile = new JarFile(new File("Wrong.file"));
@@ -149,12 +137,6 @@
     /**
      * @tests java.util.jar.JarFile#JarFile(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarFile",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         try {
             JarFile jarFile = new JarFile("Wrong.file");
@@ -187,12 +169,6 @@
     /**
      * @tests java.util.jar.JarFile#JarFile(java.lang.String, boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarFile",
-        args = {java.lang.String.class, boolean.class}
-    )
     public void test_ConstructorLjava_lang_StringZ() {
         try {
             JarFile jarFile = new JarFile("Wrong.file", false);
@@ -225,12 +201,6 @@
     /**
      * @tests java.util.jar.JarFile#JarFile(java.io.File, boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarFile",
-        args = {java.io.File.class, boolean.class}
-    )
     public void test_ConstructorLjava_io_FileZ() {
         try {
             JarFile jarFile = new JarFile(new File("Wrong.file"), true);
@@ -262,12 +232,6 @@
     /**
      * @tests java.util.jar.JarFile#JarFile(java.io.File, boolean, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarFile",
-        args = {java.io.File.class, boolean.class, int.class}
-    )
     public void test_ConstructorLjava_io_FileZI() {
         try {
             JarFile jarFile = new JarFile(new File("Wrong.file"), true,
@@ -316,12 +280,6 @@
      * @tests java.util.jar.JarFile#JarFile(java.io.File)
      * @tests java.util.jar.JarFile#JarFile(java.lang.String)
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "JarFile",
-            args = {java.io.File.class}
-    )
     public void testConstructor_file() throws IOException {
         File f = new File(resources, jarName);
         Support_Resources.copyFile(resources, null, jarName);
@@ -334,12 +292,6 @@
     /**
      * @tests java.util.jar.JarFile#entries()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_entries() throws Exception {
         /*
          * Note only (and all of) the following should be contained in the file
@@ -357,12 +309,6 @@
         assertEquals(6, i);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_entries2() throws Exception {
         Support_Resources.copyFile(resources, null, jarName);
         JarFile jarFile = new JarFile(new File(resources, jarName));
@@ -388,12 +334,6 @@
      * @throws IOException
      * @tests java.util.jar.JarFile#getJarEntry(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getEntry",
-        args = {java.lang.String.class}
-    )
     public void test_getEntryLjava_lang_String() throws IOException {
         try {
             Support_Resources.copyFile(resources, null, jarName);
@@ -431,12 +371,6 @@
      * @throws IOException
      * @tests java.util.jar.JarFile#getJarEntry(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getJarEntry",
-        args = {java.lang.String.class}
-    )
     public void test_getJarEntryLjava_lang_String() throws IOException {
         try {
             Support_Resources.copyFile(resources, null, jarName);
@@ -474,12 +408,6 @@
     /**
      * @tests java.util.jar.JarFile#getJarEntry(java.lang.String)
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getEntry",
-            args = {java.lang.String.class}
-    )
     public void testGetJarEntry() throws Exception {
         Support_Resources.copyFile(resources, null, jarName);
         JarFile jarFile = new JarFile(new File(resources, jarName));
@@ -559,12 +487,6 @@
     /**
      * @tests java.util.jar.JarFile#getManifest()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getManifest",
-        args = {}
-    )
     public void test_getManifest() {
         // Test for method java.util.jar.Manifest
         // java.util.jar.JarFile.getManifest()
@@ -656,16 +578,9 @@
     /**
      * @tests java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "SecurityException and functionality checked.",
-        method = "getInputStream",
-        args = {java.util.zip.ZipEntry.class}
-    )
-    @AndroidOnly("This test doesn't pass on RI. If entry size is set up " +
-            "incorrectly, SecurityException is thrown. " +
-            "But SecurityException is thrown on RI only " +
-            "if jar file is signed incorreclty.")
+    // This test doesn't pass on RI. If entry size is set up incorrectly,
+    // SecurityException is thrown. But SecurityException is thrown on RI only
+    // if jar file is signed incorrectly.
     public void test_getInputStreamLjava_util_jar_JarEntry_subtest0() {
         File signedFile = null;
         try {
@@ -734,12 +649,6 @@
      * The jar created by 1.4 which does not provide a
      * algorithm-Digest-Manifest-Main-Attributes entry in .SF file.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_Jar_created_before_java_5() throws IOException {
         String modifiedJarName = "Created_by_1_4.jar";
         Support_Resources.copyFile(resources, null, modifiedJarName);
@@ -753,12 +662,6 @@
     }
 
     /* The jar is intact, then everything is all right. */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_JarFile_Integrate_Jar() throws IOException {
         String modifiedJarName = "Integrate.jar";
         Support_Resources.copyFile(resources, null, modifiedJarName);
@@ -774,12 +677,6 @@
     /**
      * The jar is intact, but the entry object is modified.
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getInputStream",
-            args = {ZipEntry.class}
-    )
     public void testJarVerificationModifiedEntry() throws IOException {
         Support_Resources.copyFile(resources, null, integrateJar);
         File f = new File(resources, integrateJar);
@@ -805,12 +702,6 @@
      * If another entry is inserted into Manifest, no security exception will be
      * thrown out.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_JarFile_InsertEntry_in_Manifest_Jar() throws IOException {
         String modifiedJarName = "Inserted_Entry_Manifest.jar";
         Support_Resources.copyFile(resources, null, modifiedJarName);
@@ -831,12 +722,6 @@
      * If another entry is inserted into Manifest, no security exception will be
      * thrown out.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_Inserted_Entry_Manifest_with_DigestCode()
             throws IOException {
         String modifiedJarName = "Inserted_Entry_Manifest_with_DigestCode.jar";
@@ -858,12 +743,6 @@
      * throw security Exception, but it will anytime before the inputStream got
      * from getInputStream method has been read to end.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "SecurityException and functionality checked.",
-        method = "getInputStream",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_JarFile_Modified_Class() throws IOException {
         String modifiedJarName = "Modified_Class.jar";
         Support_Resources.copyFile(resources, null, modifiedJarName);
@@ -893,12 +772,6 @@
      * tampered manually. Hence the RI 5.0 JarFile.getInputStream of any
      * JarEntry will throw security exception.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "SecurityException and functionality checked.",
-        method = "getInputStream",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_JarFile_Modified_Manifest_MainAttributes()
             throws IOException {
         String modifiedJarName = "Modified_Manifest_MainAttributes.jar";
@@ -922,12 +795,6 @@
      * example Test.class in our jar, the jarFile.getInputStream will throw
      * Security Exception.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "SecurityException and functionality checked.",
-        method = "getInputStream",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_JarFile_Modified_Manifest_EntryAttributes()
             throws IOException {
         String modifiedJarName = "Modified_Manifest_EntryAttributes.jar";
@@ -950,12 +817,6 @@
      * If the content of the .SA file is modified, no matter what it resides,
      * JarFile.getInputStream of any JarEntry will throw Security Exception.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "SecurityException and functionality checked.",
-        method = "getInputStream",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_JarFile_Modified_SF_EntryAttributes() throws IOException {
         String modifiedJarName = "Modified_SF_EntryAttributes.jar";
         Support_Resources.copyFile(resources, null, modifiedJarName);
@@ -973,12 +834,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
     public void test_close() throws IOException {
         String modifiedJarName = "Modified_SF_EntryAttributes.jar";
         Support_Resources.copyFile(resources, null, modifiedJarName);
@@ -996,12 +851,6 @@
      * @throws IOException
      * @tests java.util.jar.JarFile#getInputStream(java.util.zip.ZipEntry)
      */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getInputStream",
-            args = {java.util.zip.ZipEntry.class}
-    )
     public void test_getInputStreamLjava_util_jar_JarEntry() throws IOException {
         File localFile = null;
         try {
@@ -1074,13 +923,7 @@
     /**
      * The jar is intact, but the entry object is modified.
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Regression test for issue introduced by HAROMNY-4569. "
-                + "signed archives containing files with size 0 could not get verified",
-            method = "getInputStream",
-            args = {ZipEntry.class}
-    )
+    // Regression test for issue introduced by HARMONY-4569: signed archives containing files with size 0 could not get verified.
     public void testJarVerificationEmptyEntry() throws IOException {
         Support_Resources.copyFile(resources, null, emptyEntryJar);
         File f = new File(resources, emptyEntryJar);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
index 5befa77..06853e7 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarInputStreamTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 import tests.support.resource.Support_Resources;
 
 import java.io.File;
@@ -36,7 +32,6 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipException;
 
-@TestTargetClass(JarInputStream.class)
 public class JarInputStreamTest extends junit.framework.TestCase {
     // a 'normal' jar file
     private String jarName;
@@ -61,12 +56,6 @@
     /**
      * @tests java.util.jar.JarInputStream#JarInputStream(java.io.InputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarInputStream",
-        args = {java.io.InputStream.class}
-    )
     public void test_ConstructorLjava_io_InputStream() {
         // Test for method java.util.jar.JarInputStream(java.io.InputStream)
         InputStream is = null;
@@ -103,12 +92,6 @@
     /**
      * @tests java.util.jar.JarInputStream#getManifest()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getManifest",
-        args = {}
-    )
     public void test_getManifest() {
         // Test for method java.util.jar.Manifest
         // java.util.jar.JarInputStream.getManifest()
@@ -134,11 +117,6 @@
     /**
      * @tests java.util.jar.JarInputStream#getNextJarEntry()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "getNextJarEntry",
-        args = {}
-    )
     public void test_getNextJarEntry() throws Exception {
         final Set<String> desired = new HashSet<String>(Arrays
                 .asList(new String[] {
@@ -174,11 +152,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "getNextJarEntry",
-        args = {}
-    )
     public void test_getNextJarEntry_Ex() throws Exception {
         final Set<String> desired = new HashSet<String>(Arrays
                 .asList("foo/", "foo/bar/", "foo/bar/A.class", "Blah.txt"));
@@ -213,12 +186,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Exceptions checking missed. Case2",
-        method = "getNextJarEntry",
-        args = {}
-    )
     public void test_JarInputStream_Integrate_Jar_getNextEntry()
             throws IOException {
         String intJarName = Support_Resources.getURL("Integrate.jar");
@@ -234,12 +201,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "getNextEntry",
-        args = {}
-    )
     public void test_JarInputStream_Modified_Class_getNextEntry()
             throws IOException {
         String modJarName = Support_Resources.getURL("Modified_Class.jar");
@@ -266,12 +227,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "getNextEntry",
-        args = {}
-    )
     public void test_JarInputStream_Modified_Manifest_MainAttributes_getNextEntry()
             throws IOException {
         String modJarName = Support_Resources.getURL("Modified_Manifest_MainAttributes.jar");
@@ -292,12 +247,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "getNextEntry",
-        args = {}
-    )
     public void test_JarInputStream_Modified_Manifest_EntryAttributes_getNextEntry()
             throws IOException {
         String modJarName = Support_Resources
@@ -324,12 +273,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "getNextEntry",
-        args = {}
-    )
     public void test_JarInputStream_Modified_SF_EntryAttributes_getNextEntry()
             throws IOException {
         String modJarName = Support_Resources
@@ -356,12 +299,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "read",
-        args = {byte[].class}
-    )
     public void test_JarInputStream_Modified_Class_read() throws IOException {
         String modJarName = Support_Resources.getURL("Modified_Class.jar");
         InputStream is = new URL(modJarName).openConnection().getInputStream();
@@ -390,12 +327,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "read",
-        args = {byte[].class}
-    )
     public void test_Integrate_Jar_read() throws IOException {
         String intJarName = Support_Resources.getURL("Integrate.jar");
         InputStream is = new URL(intJarName).openConnection().getInputStream();
@@ -416,12 +347,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "read",
-        args = {byte[].class}
-    )
     public void test_JarInputStream_Modified_Manifest_MainAttributes_read()
             throws IOException {
         String modJarName = Support_Resources
@@ -452,12 +377,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException & ZipException checking missed.",
-        method = "read",
-        args = {byte[].class}
-    )
     public void test_JarInputStream_Modified_SF_EntryAttributes_read()
             throws IOException {
         String modJarName = Support_Resources
@@ -488,12 +407,6 @@
         jin.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "JarInputStream",
-        args = {java.io.InputStream.class, boolean.class}
-    )
     public void test_ConstructorLjava_io_InputStreamZ() {
         // Test for method java.util.jar.JarInputStream(java.io.InputStream)
         InputStream is = null;
@@ -527,11 +440,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "close",
-        args = {}
-    )
     public void test_closeAfterException() throws Exception {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
@@ -553,11 +461,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getNextEntry",
-        args = {}
-    )
     public void test_getNextEntry() throws Exception {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
@@ -591,12 +494,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "createZipEntry",
-        args = {java.lang.String.class}
-    )
     public void test_createZipEntryLjava_lang_String() throws Exception {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_entry.jar");
@@ -605,11 +502,6 @@
         assertNotNull(mjis.createZipEntry("New entry"));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_read$ZII() throws Exception {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_entry_data.jar");
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
index b2ecdec..72dfcab 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/JarOutputStreamTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -36,17 +31,11 @@
 
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(JarOutputStream.class)
 public class JarOutputStreamTest extends junit.framework.TestCase {
 
     /**
      * @tests java.util.jar.JarOutputStream#putNextEntry(java.util.zip.ZipEntry)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "putNextEntry",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_putNextEntryLjava_util_zip_ZipEntry() throws Exception {
         // testClass file`s actual extension is .class, since having .class
         // extension files in source dir causes
@@ -133,12 +122,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks IOException",
-        method = "JarOutputStream",
-        args = {java.io.OutputStream.class, java.util.jar.Manifest.class}
-    )
     public void test_JarOutputStreamLjava_io_OutputStreamLjava_util_jar_Manifest()
             throws IOException {
         File fooJar = File.createTempFile("hyts_", ".jar");
@@ -161,12 +144,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Can not check IOException",
-        method = "JarOutputStream",
-        args = {java.io.OutputStream.class}
-    )
     public void test_JarOutputStreamLjava_io_OutputStream() throws IOException {
         File fooJar = File.createTempFile("hyts_", ".jar");
 
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ManifestTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ManifestTest.java
index 42b2543..0834fb1 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ManifestTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ManifestTest.java
@@ -16,11 +16,6 @@
  */
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -38,7 +33,6 @@
 
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(Manifest.class)
 public class ManifestTest extends TestCase {
 
     private final String jarName = "hyts_patch.jar";
@@ -88,12 +82,6 @@
     /**
      * @tests java.util.jar.Manifest#Manifest()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Manifest",
-        args = {}
-    )
     public void test_Constructor() {
         // Test for method java.util.jar.Manifest()
         Manifest emptyManifest = new Manifest();
@@ -106,12 +94,6 @@
     /**
      * @tests java.util.jar.Manifest#Manifest(java.util.jar.Manifest)
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "Manifest",
-            args = {java.util.jar.Manifest.class}
-    )
     public void testCopyingConstructor() throws IOException {
         Manifest firstManifest = new Manifest(new URL(Support_Resources
                 .getURL(MANIFEST_NAME)).openStream());
@@ -122,12 +104,6 @@
     /**
      * @tests java.util.jar.Manifest#Manifest(Manifest)
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "Manifest",
-            args = {java.util.jar.Manifest.class}
-    )
     public void test_ConstructorLjava_util_jar_Manifest() {
         // Test for method java.util.jar.Manifest()
         Manifest emptyManifest = new Manifest();
@@ -173,12 +149,6 @@
     /**
      * @tests java.util.jar.Manifest#Manifest(java.io.InputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "IOException checking missed.",
-        method = "Manifest",
-        args = {java.io.InputStream.class}
-    )
     public void test_ConstructorLjava_io_InputStream() throws IOException {
         Manifest m = getManifest(attJarName);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -214,12 +184,6 @@
     /**
      * @tests java.util.jar.Manifest#clear()
      */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "clear",
-            args = {}
-    )
     public void test_clear() {
         m2.clear();
         assertTrue("Should have no entries", m2.getEntries().isEmpty());
@@ -227,12 +191,6 @@
                 .isEmpty());
     }
 
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "clone",
-            args = {}
-    )
     public void test_clone() throws IOException {
         Manifest emptyManifest = new Manifest();
         Manifest emptyClone = (Manifest) emptyManifest.clone();
@@ -250,12 +208,6 @@
         checkManifest(manifestClone);
     }
 
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "equals",
-            args = {java.lang.Object.class}
-    )
     public void test_equals() throws IOException {
         Manifest manifest1 = new Manifest(new URL(Support_Resources.getURL(
                 "manifest/hyts_MANIFEST.MF")).openStream());
@@ -269,12 +221,6 @@
         assertFalse(manifest1.equals(this));
     }
 
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "hashCode",
-            args = {}
-    )
     public void test_hashCode() throws IOException {
         Manifest manifest1 = new Manifest(new URL(Support_Resources
                 .getURL("manifest/hyts_MANIFEST.MF")).openStream());
@@ -286,12 +232,6 @@
 	/**
 	 * @tests java.util.jar.Manifest#getAttributes(java.lang.String)
 	 */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getAttributes",
-            args = {String.class}
-    )
 	public void test_getAttributesLjava_lang_String() {
 		assertNull("Should not exist",
 				m2.getAttributes("Doesn't Exist"));
@@ -302,12 +242,6 @@
 	/**
 	 * @tests java.util.jar.Manifest#getEntries()
 	 */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getEntries",
-            args = {}
-    )
 	public void test_getEntries() {
 		Map<String, Attributes> myMap = m2.getEntries();
 		assertNull("Shouldn't exist", myMap.get("Doesn't exist"));
@@ -319,12 +253,6 @@
 	/**
 	 * @tests java.util.jar.Manifest#getMainAttributes()
 	 */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getMainAttributes",
-            args = {}
-    )
 	public void test_getMainAttributes() {
 		// Test for method java.util.jar.Attributes
 		// java.util.jar.Manifest.getMainAttributes()
@@ -333,12 +261,6 @@
 				Attributes.Name.MANIFEST_VERSION));
 	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {java.io.OutputStream.class}
-    )
     public void test_writeLjava_io_OutputStream() throws IOException {
         byte b[] = null;
         Manifest manifest1 = null;
@@ -385,12 +307,6 @@
      * @see <a
      *      href="http://issues.apache.org/jira/browse/HARMONY-5662">HARMONY-5662</a>
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "Manifest",
-            args = {InputStream.class}
-    )
     public void testNul() throws IOException {
         String manifestContent =
                 "Manifest-Version: 1.0\nCreated-By: nasty gcc tool\n\n\0";
@@ -413,12 +329,6 @@
         }
     }
 
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "Manifest",
-            args = {InputStream.class}
-    )
-    @KnownFailure("CharsetDecoder fails with an IllegalStateException")
     public void testDecoding() throws IOException {
         Manifest m = getManifest(attJarName);
         final byte[] bVendor = new byte[] { (byte) 0xd0, (byte) 0x9C,
@@ -565,12 +475,6 @@
     /**
      * @tests {@link java.util.jar.Manifest#read(java.io.InputStream)
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "",
-            method = "read",
-            args = {InputStream.class}
-    )
     public void testRead() {
         // Regression for HARMONY-89
         InputStream is = new InputStreamImpl();
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java
index 0d72108..5e4b668 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200PackerTest.java
@@ -16,11 +16,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import tests.support.resource.Support_Resources;
@@ -37,29 +32,14 @@
 import java.util.jar.Pack200;
 import java.util.jar.Pack200.Packer;
 
-@TestTargetClass(Pack200.Packer.class)
 public class Pack200PackerTest extends TestCase {
     Packer packer;
     Map properties;
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "properties",
-        args = {}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testProperties() {
         assertTrue(properties.size()>0); 
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pack",
-        args = {java.util.jar.JarFile.class, java.io.OutputStream.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testPackJarFileOutputStream() throws IOException {
         File resources = Support_Resources.createTempFolder();
         //Use junit4.jar file for testing pack200 compressing rate.
@@ -93,13 +73,6 @@
         assertTrue(packFile2.length()>packFile3.length());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pack",
-        args = {java.util.jar.JarInputStream.class, java.io.OutputStream.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testPackJarInputStreamOutputStream() throws IOException {
         File resources = Support_Resources.createTempFolder();
         //Use junit4.jar file for testing pack200 compressing rate.
@@ -142,13 +115,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "addPropertyChangeListener",
-        args = {java.beans.PropertyChangeListener.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testAddPropertyChangeListener() {
         MyPCL pcl = new MyPCL();
         packer.addPropertyChangeListener(pcl);
@@ -157,13 +123,6 @@
         assertTrue(pcl.isCalled());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removePropertyChangeListener",
-        args = {java.beans.PropertyChangeListener.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testRemovePropertyChangeListener() {
         MyPCL pcl = new MyPCL();
         packer.addPropertyChangeListener(pcl);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200Test.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200Test.java
index 9fb3cf9..0e2b688 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200Test.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200Test.java
@@ -16,27 +16,14 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.jar.Pack200;
 
-@TestTargetClass(Pack200.class)
 public class Pack200Test extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "newPacker",
-        args = {}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testNewPacker() {
         Method[] methodsInt = Pack200.Packer.class.getDeclaredMethods();
         Method[] methodsImpl = Pack200.newPacker().getClass()
@@ -68,13 +55,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "newUnpacker",
-        args = {}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testNewUnpacker() {
         assertNotNull(Pack200.newUnpacker().getClass());
         Method[] methodsInt = Pack200.Unpacker.class.getDeclaredMethods();
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java
index c1f9813..249a7cf 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/Pack200UnpackerTest.java
@@ -16,11 +16,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import tests.support.resource.Support_Resources;
@@ -38,29 +33,14 @@
 import java.util.jar.Pack200.Packer;
 import java.util.jar.Pack200.Unpacker;
 
-@TestTargetClass(Pack200.Unpacker.class)
 public class Pack200UnpackerTest extends TestCase {
     Unpacker unpacker;
     Map properties;
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "properties",
-        args = {}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testProperties() {
         assertTrue(properties.size()>0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "unpack",
-        args = {java.io.File.class, java.util.jar.JarOutputStream.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testUnpackInputStreamJarOutputStream() throws IOException {
         File resources = Support_Resources.createTempFolder();
         //Use junit4.jar file for testing pack200 compressing rate.
@@ -115,13 +95,6 @@
         assertEquals(jarEntries, new JarFile(jarFile3).size());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "unpack",
-        args = {java.io.InputStream.class, java.util.jar.JarOutputStream.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testUnpackFileJarOutputStream() throws IOException {
         File resources = Support_Resources.createTempFolder();
         //Use junit4.jar file for testing pack200 compressing rate.
@@ -191,13 +164,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "addPropertyChangeListener",
-        args = {java.beans.PropertyChangeListener.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testAddPropertyChangeListener() {
         MyPCL pcl = new MyPCL();
         unpacker.addPropertyChangeListener(pcl);
@@ -206,13 +172,6 @@
         assertTrue(pcl.isCalled());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removePropertyChangeListener",
-        args = {java.beans.PropertyChangeListener.class}
-    )
-    @KnownFailure("No Implementation in Android!")
     public void testRemovePropertyChangeListener() {
         MyPCL pcl = new MyPCL();
         unpacker.addPropertyChangeListener(pcl);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
index 013974c..5ce657b 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/jar/ZipExecTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.jar;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 import static tests.support.Support_Exec.javaProcessBuilder;
 import static tests.support.Support_Exec.execAndGetOutput;
 import tests.support.resource.Support_Resources;
@@ -42,15 +38,7 @@
  * some tests are just copy of JarExecTest ones
  */
 
-@TestTargetClass(ZipOutputStream.class)
 public class ZipExecTest extends junit.framework.TestCase {
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression functional test. Exception checking missed.",
-        method = "putNextEntry",
-        args = {java.util.zip.ZipEntry.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_1562() throws Exception {
         Manifest man = new Manifest();
         Attributes att = man.getMainAttributes();
@@ -86,13 +74,6 @@
      * 
      * @throws Exception in case of troubles
      */
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "ZipOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_zip_class_path() throws Exception {
         File fooZip = File.createTempFile("hyts_", ".zip");
         File barZip = File.createTempFile("hyts_", ".zip");
@@ -160,13 +141,6 @@
     }
 
 
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "ZipOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_zip_jar_mix() throws Exception {
         File fooJar = File.createTempFile("hyts_", ".jar");
         File barZip = File.createTempFile("hyts_", ".zip");
@@ -201,13 +175,6 @@
                 execAndGetOutput(builder).startsWith("FOOBAR"));
     }
 
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "ZipOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_zip_jar_mix_1() throws Exception {
         File fooZip = File.createTempFile("hyts_", ".zip");
         File barJar = File.createTempFile("hyts_", ".jar");
@@ -251,13 +218,6 @@
      * 
      * @throws Exception in case of troubles
      */
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Functional test.",
-        method = "ZipOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    @KnownFailure("Maybe not a failure, but dalvikvm -jar is not supported (, as yet).")
     public void test_main_class_in_another_zip() throws Exception {
         File fooZip = File.createTempFile("hyts_", ".zip");
         File barZip = File.createTempFile("hyts_", ".zip");
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/Adler32Test.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/Adler32Test.java
index 532a3a6..7290ac2 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/Adler32Test.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/Adler32Test.java
@@ -14,211 +14,156 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.util.zip.Adler32;
 
-@TestTargetClass(Adler32.class)
 public class Adler32Test extends junit.framework.TestCase {
 
-    /**
-     * @tests java.util.zip.Adler32#Adler32()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Adler32",
-        args = {}
-    )
-    public void test_Constructor() {
-        // test method of java.util.zip.Adler32()
-        Adler32 adl = new Adler32();
-        assertEquals("Constructor of adl32 failed", 1, adl.getValue());
-    }
+	/**
+	 * @tests java.util.zip.Adler32#Adler32()
+	 */
+	public void test_Constructor() {
+		// test method of java.util.zip.Adler32()
+		Adler32 adl = new Adler32();
+		assertEquals("Constructor of adl32 failed", 1, adl.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.Adler32#getValue()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getValue",
-        args = {}
-    )
-    public void test_getValue() {
-        // test methods of java.util.zip.getValue()
-        Adler32 adl = new Adler32();
-        assertEquals(
-                "GetValue should return a zero as a result of construction an object of Adler32",
-                1, adl.getValue());
+	/**
+	 * @tests java.util.zip.Adler32#getValue()
+	 */
+	public void test_getValue() {
+		// test methods of java.util.zip.getValue()
+		Adler32 adl = new Adler32();
+		assertEquals("GetValue should return a zero as a result of construction an object of Adler32",
+				1, adl.getValue());
 
-        adl.reset();
-        adl.update(1);
-        // System.out.print("value of adl"+adl.getValue());
-        // The value of the adl should be 131074
-        assertEquals(
-                "update(int) failed to update the checksum to the correct value ",
-                131074, adl.getValue());
-        adl.reset();
-        assertEquals("reset failed to reset the checksum value to zero", 1, adl
-                .getValue());
+		adl.reset();
+		adl.update(1);
+		// System.out.print("value of adl"+adl.getValue());
+		// The value of the adl should be 131074
+		assertEquals("update(int) failed to update the checksum to the correct value ",
+				131074, adl.getValue());
+		adl.reset();
+		assertEquals("reset failed to reset the checksum value to zero", 1, adl
+				.getValue());
 
-        adl.reset();
-        adl.update(Integer.MIN_VALUE);
-        // System.out.print("value of adl " + adl.getValue());
-        // The value of the adl should be 65537
-        assertEquals(
-                "update(min) failed to update the checksum to the correct value ",
-                65537L, adl.getValue());
-    }
+		adl.reset();
+		adl.update(Integer.MIN_VALUE);
+		// System.out.print("value of adl " + adl.getValue());
+		// The value of the adl should be 65537
+		assertEquals("update(min) failed to update the checksum to the correct value ",
+				65537L, adl.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.Adler32#reset()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reset",
-        args = {}
-    )
-    public void test_reset() {
-        // test methods of java.util.zip.reset()
-        Adler32 adl = new Adler32();
-        adl.update(1);
-        // System.out.print("value of adl"+adl.getValue());
-        // The value of the adl should be 131074
-        assertEquals(
-                "update(int) failed to update the checksum to the correct value ",
-                131074, adl.getValue());
-        adl.reset();
-        assertEquals("reset failed to reset the checksum value to zero", 1, adl
-                .getValue());
-    }
+	/**
+	 * @tests java.util.zip.Adler32#reset()
+	 */
+	public void test_reset() {
+		// test methods of java.util.zip.reset()
+		Adler32 adl = new Adler32();
+		adl.update(1);
+		// System.out.print("value of adl"+adl.getValue());
+		// The value of the adl should be 131074
+		assertEquals("update(int) failed to update the checksum to the correct value ",
+				131074, adl.getValue());
+		adl.reset();
+		assertEquals("reset failed to reset the checksum value to zero", 1, adl
+				.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.Adler32#update(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "update",
-        args = {int.class}
-    )
-    public void test_updateI() {
-        // test methods of java.util.zip.update(int)
-        Adler32 adl = new Adler32();
-        adl.update(1);
-        // The value of the adl should be 131074
-        assertEquals(
-                "update(int) failed to update the checksum to the correct value ",
-                131074, adl.getValue());
+	/**
+	 * @tests java.util.zip.Adler32#update(int)
+	 */
+	public void test_updateI() {
+		// test methods of java.util.zip.update(int)
+		Adler32 adl = new Adler32();
+		adl.update(1);
+		// The value of the adl should be 131074
+		assertEquals("update(int) failed to update the checksum to the correct value ",
+				131074, adl.getValue());
 
-        adl.reset();
-        adl.update(Integer.MAX_VALUE);
-        // System.out.print("value of adl " + adl.getValue());
-        // The value of the adl should be 16777472
-        assertEquals(
-                "update(max) failed to update the checksum to the correct value ",
-                16777472L, adl.getValue());
+		adl.reset();
+		adl.update(Integer.MAX_VALUE);
+		// System.out.print("value of adl " + adl.getValue());
+		// The value of the adl should be 16777472
+		assertEquals("update(max) failed to update the checksum to the correct value ",
+				16777472L, adl.getValue());
 
-        adl.reset();
-        adl.update(Integer.MIN_VALUE);
-        // System.out.print("value of adl " + adl.getValue());
-        // The value of the adl should be 65537
-        assertEquals(
-                "update(min) failed to update the checksum to the correct value ",
-                65537L, adl.getValue());
+		adl.reset();
+		adl.update(Integer.MIN_VALUE);
+		// System.out.print("value of adl " + adl.getValue());
+		// The value of the adl should be 65537
+		assertEquals("update(min) failed to update the checksum to the correct value ",
+				65537L, adl.getValue());
 
-    }
+	}
 
-    /**
-     * @tests java.util.zip.Adler32#update(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "update",
-        args = {byte[].class}
-    )
-    public void test_update$B() {
-        // test method of java.util.zip.update(byte[])
-        byte byteArray[] = {1, 2};
-        Adler32 adl = new Adler32();
-        adl.update(byteArray);
-        // System.out.print("value of adl"+adl.getValue());
-        // The value of the adl should be 393220
-        assertEquals(
-                "update(byte[]) failed to update the checksum to the correct value ",
-                393220, adl.getValue());
+	/**
+	 * @tests java.util.zip.Adler32#update(byte[])
+	 */
+	public void test_update$B() {
+		// test method of java.util.zip.update(byte[])
+		byte byteArray[] = { 1, 2 };
+		Adler32 adl = new Adler32();
+		adl.update(byteArray);
+		// System.out.print("value of adl"+adl.getValue());
+		// The value of the adl should be 393220
+		assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+				393220, adl.getValue());
 
-        adl.reset();
-        byte byteEmpty[] = new byte[10000];
-        adl.update(byteEmpty);
-        // System.out.print("value of adl"+adl.getValue());
-        // The value of the adl should be 655360001
-        assertEquals(
-                "update(byte[]) failed to update the checksum to the correct value ",
-                655360001L, adl.getValue());
+		adl.reset();
+		byte byteEmpty[] = new byte[10000];
+		adl.update(byteEmpty);
+		// System.out.print("value of adl"+adl.getValue());
+		// The value of the adl should be 655360001
+		assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+				655360001L, adl.getValue());
 
-    }
+	}
 
-    /**
-     * @tests java.util.zip.Adler32#update(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "update",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_update$BII() {
-        // test methods of java.util.zip.update(byte[],int,int)
-        byte[] byteArray = {1, 2, 3};
-        Adler32 adl = new Adler32();
-        int off = 2;// accessing the 2nd element of byteArray
-        int len = 1;
-        int lenError = 3;
-        int offError = 4;
-        adl.update(byteArray, off, len);
-        // System.out.print("value of adl"+adl.getValue());
-        // The value of the adl should be 262148
-        assertEquals(
-                "update(byte[],int,int) failed to update the checksum to the correct value ",
-                262148, adl.getValue());
-        int r = 0;
+	/**
+	 * @tests java.util.zip.Adler32#update(byte[], int, int)
+	 */
+	public void test_update$BII() {
+		// test methods of java.util.zip.update(byte[],int,int)
+		byte[] byteArray = { 1, 2, 3 };
+		Adler32 adl = new Adler32();
+		int off = 2;// accessing the 2nd element of byteArray
+		int len = 1;
+		int lenError = 3;
+		int offError = 4;
+		adl.update(byteArray, off, len);
+		// System.out.print("value of adl"+adl.getValue());
+		// The value of the adl should be 262148
+		assertEquals("update(byte[],int,int) failed to update the checksum to the correct value ",
+				262148, adl.getValue());
+		int r = 0;
 
-        try {
-            adl.update(byteArray, off, lenError);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            r = 1;
-        }
-        assertEquals(
-                "update(byte[],int,int) failed b/c lenError>byte[].length-off",
-                1, r);
+		try {
+			adl.update(byteArray, off, lenError);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 1;
+		}
+		assertEquals("update(byte[],int,int) failed b/c lenError>byte[].length-off",
+				1, r);
 
-        try {
-            adl.update(byteArray, offError, len);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            r = 2;
-        }
-        assertEquals(
-                "update(byte[],int,int) failed b/c offError>byte[].length", 2,
-                r);
+		try {
+			adl.update(byteArray, offError, len);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 2;
+		}
+		assertEquals("update(byte[],int,int) failed b/c offError>byte[].length",
+				2, r);
 
-    }
+	}
 
-    @Override
+	@Override
     protected void setUp() {
-    }
+	}
 
-    @Override
+	@Override
     protected void tearDown() {
-    }
+	}
 
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/AllTests.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/AllTests.java
index acde889..bf27661 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/AllTests.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/AllTests.java
@@ -24,25 +24,20 @@
  * Test suite for java.util.zip package.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "Suite org.apache.harmony.archive.tests.java.util.zip");
-        // $JUnit-BEGIN$
+        TestSuite suite = new TestSuite("Suite org.apache.harmony.archive.tests.java.util.zip");
         suite.addTestSuite(Adler32Test.class);
         suite.addTestSuite(CheckedInputStreamTest.class);
         suite.addTestSuite(CheckedOutputStreamTest.class);
         suite.addTestSuite(CRC32Test.class);
         suite.addTestSuite(DataFormatExceptionTest.class);
+        suite.addTestSuite(DeflaterInputStreamTest.class);
         suite.addTestSuite(DeflaterOutputStreamTest.class);
         suite.addTestSuite(DeflaterTest.class);
         suite.addTestSuite(GZIPInputStreamTest.class);
         suite.addTestSuite(GZIPOutputStreamTest.class);
         suite.addTestSuite(InflaterInputStreamTest.class);
+        suite.addTestSuite(InflaterOutputStreamTest.class);
         suite.addTestSuite(InflaterTest.class);
         suite.addTestSuite(ZipEntryTest.class);
         suite.addTestSuite(ZipExceptionTest.class);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CRC32Test.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CRC32Test.java
index 805cab3..7eb0566 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CRC32Test.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CRC32Test.java
@@ -14,229 +14,173 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.util.zip.CRC32;
 
-@TestTargetClass(CRC32.class)
 public class CRC32Test extends junit.framework.TestCase {
 
-    /**
-     * @tests java.util.zip.CRC32#CRC32()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "CRC32",
-        args = {}
-    )
-    public void test_Constructor() {
-        // test methods of java.util.zip.CRC32()
-        CRC32 crc = new CRC32();
-        assertEquals("Constructor of CRC32 failed", 0, crc.getValue());
-    }
+	/**
+	 * @tests java.util.zip.CRC32#CRC32()
+	 */
+	public void test_Constructor() {
+		// test methods of java.util.zip.CRC32()
+		CRC32 crc = new CRC32();
+		assertEquals("Constructor of CRC32 failed", 0, crc.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.CRC32#getValue()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getValue",
-        args = {}
-    )
-    public void test_getValue() {
-        // test methods of java.util.zip.crc32.getValue()
-        CRC32 crc = new CRC32();
-        assertEquals(
-                "getValue() should return a zero as a result of constructing a CRC32 instance",
-                0, crc.getValue());
+	/**
+	 * @tests java.util.zip.CRC32#getValue()
+	 */
+	public void test_getValue() {
+		// test methods of java.util.zip.crc32.getValue()
+		CRC32 crc = new CRC32();
+		assertEquals("getValue() should return a zero as a result of constructing a CRC32 instance",
+				0, crc.getValue());
 
-        crc.reset();
-        crc.update(Integer.MAX_VALUE);
-        // System.out.print("value of crc " + crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 4278190080
-        assertEquals(
-                "update(max) failed to update the checksum to the correct value ",
-                4278190080L, crc.getValue());
+		crc.reset();
+		crc.update(Integer.MAX_VALUE);
+		// System.out.print("value of crc " + crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 4278190080
+		assertEquals("update(max) failed to update the checksum to the correct value ",
+				4278190080L, crc.getValue());
 
-        crc.reset();
-        byte byteEmpty[] = new byte[10000];
-        crc.update(byteEmpty);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 1295764014
-        assertEquals(
-                "update(byte[]) failed to update the checksum to the correct value ",
-                1295764014L, crc.getValue());
+		crc.reset();
+		byte byteEmpty[] = new byte[10000];
+		crc.update(byteEmpty);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 1295764014
+		assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+				1295764014L, crc.getValue());
 
-        crc.reset();
-        crc.update(1);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 2768625435
-        // assertEquals("update(int) failed to update the checksum to the
-        // correct
-        // value ",2768625435L, crc.getValue());
-        crc.reset();
-        assertEquals("reset failed to reset the checksum value to zero", 0, crc
-                .getValue());
-    }
+		crc.reset();
+		crc.update(1);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 2768625435
+		// assertEquals("update(int) failed to update the checksum to the correct
+		// value ",2768625435L, crc.getValue());
+		crc.reset();
+		assertEquals("reset failed to reset the checksum value to zero", 0, crc
+				.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.CRC32#reset()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reset",
-        args = {}
-    )
-    public void test_reset() {
-        // test methods of java.util.zip.crc32.reset()
-        CRC32 crc = new CRC32();
-        crc.update(1);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 2768625435
-        assertEquals(
-                "update(int) failed to update the checksum to the correct value ",
-                2768625435L, crc.getValue());
-        crc.reset();
-        assertEquals("reset failed to reset the checksum value to zero", 0, crc
-                .getValue());
+	/**
+	 * @tests java.util.zip.CRC32#reset()
+	 */
+	public void test_reset() {
+		// test methods of java.util.zip.crc32.reset()
+		CRC32 crc = new CRC32();
+		crc.update(1);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 2768625435
+		assertEquals("update(int) failed to update the checksum to the correct value ",
+				2768625435L, crc.getValue());
+		crc.reset();
+		assertEquals("reset failed to reset the checksum value to zero", 0, crc
+				.getValue());
 
-    }
+	}
 
-    /**
-     * @tests java.util.zip.CRC32#update(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "update",
-        args = {int.class}
-    )
-    public void test_updateI() {
-        // test methods of java.util.zip.crc32.update(int)
-        CRC32 crc = new CRC32();
-        crc.update(1);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 2768625435
-        assertEquals(
-                "update(1) failed to update the checksum to the correct value ",
-                2768625435L, crc.getValue());
+	/**
+	 * @tests java.util.zip.CRC32#update(int)
+	 */
+	public void test_updateI() {
+		// test methods of java.util.zip.crc32.update(int)
+		CRC32 crc = new CRC32();
+		crc.update(1);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 2768625435
+		assertEquals("update(1) failed to update the checksum to the correct value ",
+				2768625435L, crc.getValue());
 
-        crc.reset();
-        crc.update(Integer.MAX_VALUE);
-        // System.out.print("value of crc " + crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 4278190080
-        assertEquals(
-                "update(max) failed to update the checksum to the correct value ",
-                4278190080L, crc.getValue());
+		crc.reset();
+		crc.update(Integer.MAX_VALUE);
+		// System.out.print("value of crc " + crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 4278190080
+		assertEquals("update(max) failed to update the checksum to the correct value ",
+				4278190080L, crc.getValue());
 
-        crc.reset();
-        crc.update(Integer.MIN_VALUE);
-        // System.out.print("value of crc " + crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 3523407757
-        assertEquals(
-                "update(min) failed to update the checksum to the correct value ",
-                3523407757L, crc.getValue());
-    }
+		crc.reset();
+		crc.update(Integer.MIN_VALUE);
+		// System.out.print("value of crc " + crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 3523407757
+		assertEquals("update(min) failed to update the checksum to the correct value ",
+				3523407757L, crc.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.CRC32#update(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "update",
-        args = {byte[].class}
-    )
-    public void test_update$B() {
-        // test methods of java.util.zip.crc32.update(byte[])
-        byte byteArray[] = {1, 2};
-        CRC32 crc = new CRC32();
-        crc.update(byteArray);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 3066839698
-        assertEquals(
-                "update(byte[]) failed to update the checksum to the correct value ",
-                3066839698L, crc.getValue());
+	/**
+	 * @tests java.util.zip.CRC32#update(byte[])
+	 */
+	public void test_update$B() {
+		// test methods of java.util.zip.crc32.update(byte[])
+		byte byteArray[] = { 1, 2 };
+		CRC32 crc = new CRC32();
+		crc.update(byteArray);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 3066839698
+		assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+				3066839698L, crc.getValue());
 
-        crc.reset();
-        byte byteEmpty[] = new byte[10000];
-        crc.update(byteEmpty);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 1295764014
-        assertEquals(
-                "update(byte[]) failed to update the checksum to the correct value ",
-                1295764014L, crc.getValue());
-    }
+		crc.reset();
+		byte byteEmpty[] = new byte[10000];
+		crc.update(byteEmpty);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 1295764014
+		assertEquals("update(byte[]) failed to update the checksum to the correct value ",
+				1295764014L, crc.getValue());
+	}
 
-    /**
-     * @tests java.util.zip.CRC32#update(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "update",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_update$BII() {
-        // test methods of java.util.zip.update(byte[],int,int)
-        byte[] byteArray = {1, 2, 3};
-        CRC32 crc = new CRC32();
-        int off = 2;// accessing the 2nd element of byteArray
-        int len = 1;
-        int lenError = 3;
-        int offError = 4;
-        crc.update(byteArray, off, len);
-        // System.out.print("value of crc"+crc.getValue());
-        // Ran JDK and discovered that the value of the CRC should be
-        // 1259060791
-        assertEquals(
-                "update(byte[],int,int) failed to update the checksum to the correct value ",
-                1259060791L, crc.getValue());
-        int r = 0;
-        try {
-            crc.update(byteArray, off, lenError);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            r = 1;
-        }
-        assertEquals(
-                "update(byte[],int,int) failed b/c lenError>byte[].length-off",
-                1, r);
+	/**
+	 * @tests java.util.zip.CRC32#update(byte[], int, int)
+	 */
+	public void test_update$BII() {
+		// test methods of java.util.zip.update(byte[],int,int)
+		byte[] byteArray = { 1, 2, 3 };
+		CRC32 crc = new CRC32();
+		int off = 2;// accessing the 2nd element of byteArray
+		int len = 1;
+		int lenError = 3;
+		int offError = 4;
+		crc.update(byteArray, off, len);
+		// System.out.print("value of crc"+crc.getValue());
+		// Ran JDK and discovered that the value of the CRC should be
+		// 1259060791
+		assertEquals("update(byte[],int,int) failed to update the checksum to the correct value ",
+				1259060791L, crc.getValue());
+		int r = 0;
+		try {
+			crc.update(byteArray, off, lenError);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 1;
+		}
+		assertEquals("update(byte[],int,int) failed b/c lenError>byte[].length-off",
+				1, r);
 
-        try {
-            crc.update(byteArray, offError, len);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            r = 2;
-        }
-        assertEquals(
-                "update(byte[],int,int) failed b/c offError>byte[].length", 2,
-                r);
-    }
+		try {
+			crc.update(byteArray, offError, len);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 2;
+		}
+		assertEquals("update(byte[],int,int) failed b/c offError>byte[].length",
+				2, r);
+	}
 
-    @Override
+	@Override
     protected void setUp() {
 
-    }
+	}
 
-    @Override
+	@Override
     protected void tearDown() {
-    }
+	}
 
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedInputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedInputStreamTest.java
index 4450bdf..393923d 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedInputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedInputStreamTest.java
@@ -14,139 +14,99 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
+import java.io.IOException;
 import java.util.zip.CRC32;
 import java.util.zip.CheckedInputStream;
+
 import junit.framework.TestCase;
 import tests.support.resource.Support_Resources;
 
-
-@TestTargetClass(CheckedInputStream.class)
 public class CheckedInputStreamTest extends TestCase {
+    
+    @Override
+    protected void tearDown() {
+        try {
+            File deletedFile = new File("empty.txt");
+            deletedFile.delete();
+        } catch (SecurityException e) {
+            fail("Cannot delete file for security reasons");
+        }
 
-    /**
-     * @tests java.util.zip.CheckedInputStream#CheckedInputStream(java.io.InputStream,
-     *        java.util.zip.Checksum)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "CheckedInputStream",
-        args = {java.io.InputStream.class, java.util.zip.Checksum.class}
-    )
-    public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Checksum()
-            throws Exception {
-        InputStream checkInput = Support_Resources
-                .getStream("hyts_checkInput.txt");
-        CheckedInputStream checkIn = new CheckedInputStream(checkInput,
-                new CRC32());
-        assertEquals("constructor of checkedInputStream has failed", 0, checkIn
-                .getChecksum().getValue());
+    }
+
+	/**
+	 * @tests java.util.zip.CheckedInputStream#CheckedInputStream(java.io.InputStream,
+	 *        java.util.zip.Checksum)
+	 */
+	public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Checksum() throws Exception {
+        InputStream checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+        CheckedInputStream checkIn = new CheckedInputStream(checkInput, new CRC32());
+        assertEquals("constructor of checkedInputStream has failed", 0, checkIn.getChecksum()
+                .getValue());
         checkInput.close();
     }
 
-    /**
-     * @tests java.util.zip.CheckedInputStream#getChecksum()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getChecksum",
-        args = {}
-    )
-    public void test_getChecksum() throws Exception {
+	/**
+	 * @tests java.util.zip.CheckedInputStream#getChecksum()
+	 */
+	public void test_getChecksum() throws Exception {
         byte outBuf[] = new byte[100];
         // testing getChecksum for an empty file
-        File empty = File.createTempFile("empty", ".txt");
-        empty.deleteOnExit();
-        FileOutputStream outEmp = new FileOutputStream(empty);
+        FileOutputStream outEmp = new FileOutputStream("empty.txt");
         outEmp.close();
-        InputStream inEmp = new FileInputStream(empty);
-        CheckedInputStream checkEmpty = new CheckedInputStream(inEmp,
-                new CRC32());
+        InputStream inEmp = new FileInputStream("empty.txt");
+        CheckedInputStream checkEmpty = new CheckedInputStream(inEmp, new CRC32());
         while (checkEmpty.read() >= 0) {
         }
-        assertEquals("the checkSum value of an empty file is not zero", 0,
-                checkEmpty.getChecksum().getValue());
+        assertEquals("the checkSum value of an empty file is not zero", 0, checkEmpty
+                .getChecksum().getValue());
         inEmp.close();
 
         // testing getChecksum for the file checkInput
-        InputStream checkInput = Support_Resources
-                .getStream("hyts_checkInput.txt");
-        CheckedInputStream checkIn = new CheckedInputStream(checkInput,
-                new CRC32());
+        InputStream checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+        CheckedInputStream checkIn = new CheckedInputStream(checkInput, new CRC32());
         while (checkIn.read() >= 0) {
         }
         // ran JDK and found that the checkSum value of this is 2036203193
         // System.out.print(" " + checkIn.getChecksum().getValue());
-        assertEquals("the checksum value is incorrect", 2036203193, checkIn
-                .getChecksum().getValue());
+        assertEquals("the checksum value is incorrect", 2036203193, checkIn.getChecksum()
+                .getValue());
         checkInput.close();
         // testing getChecksum for file checkInput
         checkInput = Support_Resources.getStream("hyts_checkInput.txt");
-        CheckedInputStream checkIn2 = new CheckedInputStream(checkInput,
-                new CRC32());
+        CheckedInputStream checkIn2 = new CheckedInputStream(checkInput, new CRC32());
         checkIn2.read(outBuf, 0, 10);
         // ran JDK and found that the checkSum value of this is 2235765342
         // System.out.print(" " + checkIn2.getChecksum().getValue());
-        assertEquals("the checksum value is incorrect", 2235765342L, checkIn2
-                .getChecksum().getValue());
+        assertEquals("the checksum value is incorrect", 2235765342L, checkIn2.getChecksum()
+                .getValue());
         checkInput.close();
     }
 
-    /**
-     * @tests java.util.zip.CheckedInputStream#skip(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "skip",
-        args = {long.class}
-    )
-    public void test_skipJ() throws Exception {
+	/**
+	 * @tests java.util.zip.CheckedInputStream#skip(long)
+	 */
+	public void test_skipJ() throws Exception {
         // testing that the return by skip is valid
-        InputStream checkInput = Support_Resources
-                .getStream("hyts_checkInput.txt");
-        CheckedInputStream checkIn = new CheckedInputStream(checkInput,
-                new CRC32());
+        InputStream checkInput = Support_Resources.getStream("hyts_checkInput.txt");
+        CheckedInputStream checkIn = new CheckedInputStream(checkInput, new CRC32());
         long skipValue = 5;
-        assertEquals(
-                "the value returned by skip(n) is not the same as its parameter",
+        assertEquals("the value returned by skip(n) is not the same as its parameter",
                 skipValue, checkIn.skip(skipValue));
         checkIn.skip(skipValue);
         // ran JDK and found the checkSum value is 2235765342
         // System.out.print(checkIn.getChecksum().getValue());
-        assertEquals("checkSum value is not correct", 2235765342L, checkIn
-                .getChecksum().getValue());
+        assertEquals("checkSum value is not correct", 2235765342L, checkIn.getChecksum()
+                .getValue());
         checkInput.close();
-        try {
-            checkInput.skip(33);
-            fail("IOException expected");
-        } catch (IOException ee) {
-            // expected
-        }
     }
 
-    /**
-     * @tests java.util.zip.CheckedInputStream#read()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "read",
-        args = {}
-    )
     public void test_read() throws Exception {
         // testing that the return by skip is valid
         InputStream checkInput = Support_Resources
@@ -161,16 +121,9 @@
         } catch (IOException ee) {
             // expected
         }
-        long skipValue = 5;
         checkInput.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_read$byteII() throws Exception {
         // testing that the return by skip is valid
         InputStream checkInput = Support_Resources
@@ -186,7 +139,6 @@
         } catch (IOException ee) {
             // expected
         }
-        long skipValue = 5;
         checkInput.close();
     }
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedOutputStreamTest.java
index 31974d1..9a562262 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedOutputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/CheckedOutputStreamTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -29,19 +24,12 @@
 import java.util.zip.CRC32;
 import java.util.zip.CheckedOutputStream;
 
-@TestTargetClass(CheckedOutputStream.class)
 public class CheckedOutputStreamTest extends junit.framework.TestCase {
 
     /**
      * @tests java.util.zip.CheckedOutputStream#CheckedOutputStream(java.io.OutputStream,
      *        java.util.zip.Checksum)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "CheckedOutputStream",
-        args = {java.io.OutputStream.class, java.util.zip.Checksum.class}
-    )
     public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Checksum() {
         // test method java.util.zip.checkedOutputStream.constructor
         try {
@@ -62,12 +50,6 @@
     /**
      * @tests java.util.zip.CheckedOutputStream#getChecksum()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getChecksum",
-        args = {}
-    )
     public void test_getChecksum() {
         // test method java.util.zip.checkedOutputStream.getChecksum()
         byte byteArray[] = {1, 2, 3, 'e', 'r', 't', 'g', 3, 6};
@@ -100,12 +82,6 @@
     /**
      * @tests java.util.zip.CheckedOutputStream#write(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {int.class}
-    )
     public void test_writeI() {
         // test method java.util.zip.checkedOutputStream.writeI()
         CheckedOutputStream chkOut = null;
@@ -137,12 +113,6 @@
     /**
      * @tests java.util.zip.CheckedOutputStream#write(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_write$BII() {
         // test method java.util.zip.checkOutputStream.writeBII()
         CheckedOutputStream chkOut = null;
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DataFormatExceptionTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DataFormatExceptionTest.java
index 6561bbd..929227d 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DataFormatExceptionTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DataFormatExceptionTest.java
@@ -16,35 +16,17 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 import java.util.zip.DataFormatException;
 
-@TestTargetClass(DataFormatException.class)
 public class DataFormatExceptionTest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "DataFormatException",
-        args = {}
-    )
     public void testDataFormatException() {
         DataFormatException dfe = new DataFormatException();
         assertEquals(dfe.getMessage(), null);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "DataFormatException",
-        args = {java.lang.String.class}
-    )
     public void testDataFormatExceptionString() {
         DataFormatException dfe = new DataFormatException("Test");
         assertEquals(dfe.getMessage(), "Test");
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterInputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterInputStreamTest.java
new file mode 100644
index 0000000..9ed0f67
--- /dev/null
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterInputStreamTest.java
@@ -0,0 +1,378 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.archive.tests.java.util.zip;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterInputStream;
+
+import junit.framework.TestCase;
+
+public class DeflaterInputStreamTest extends TestCase {
+
+    String testStr = "Hi,this is a test";
+
+    InputStream is;
+
+    /**
+     * @tests DeflaterInputStream#available()
+     */
+    public void testAvailable() throws IOException {
+        byte[] buf = new byte[1024];
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        assertEquals(1, dis.available());
+        assertEquals(120, dis.read());
+        assertEquals(1, dis.available());
+        assertEquals(22, dis.read(buf, 0, 1024));
+        assertEquals(1, dis.available());
+        assertEquals(-1, dis.read());
+        assertEquals(0, dis.available());
+        dis.close();
+        try {
+            dis.available();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests DeflaterInputStream#close()
+     */
+    public void testClose() throws IOException {
+        byte[] buf = new byte[1024];
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        assertEquals(1, dis.available());
+        dis.close();
+        try {
+            dis.available();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(buf, 0, 1024);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        // can close after close
+        dis.close();
+    }
+
+    /**
+     * @tests DeflaterInputStream#mark()
+     */
+    public void testMark() throws IOException {
+        // mark do nothing
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        dis.mark(-1);
+        dis.mark(0);
+        dis.mark(1);
+        dis.close();
+        dis.mark(1);
+    }
+
+    /**
+     * @tests DeflaterInputStream#markSupported()
+     */
+    public void testMarkSupported() throws IOException {
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        assertFalse(dis.markSupported());
+        dis.close();
+        assertFalse(dis.markSupported());
+    }
+
+    /**
+     * @tests DeflaterInputStream#read()
+     */
+    public void testRead() throws IOException {
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        assertEquals(1, dis.available());
+        assertEquals(120, dis.read());
+        assertEquals(1, dis.available());
+        assertEquals(156, dis.read());
+        assertEquals(1, dis.available());
+        assertEquals(243, dis.read());
+        assertEquals(1, dis.available());
+        dis.close();
+        try {
+            dis.read();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests DeflaterInputStream#read(byte[],int,int)
+     */
+    public void testReadByteArrayIntInt() throws IOException {
+        byte[] buf1 = new byte[256];
+        byte[] buf2 = new byte[256];
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        assertEquals(23, dis.read(buf1, 0, 256));
+        dis = new DeflaterInputStream(is);
+        assertEquals(8, dis.read(buf2, 0, 256));
+        is = new ByteArrayInputStream(testStr.getBytes("UTF-8"));
+        dis = new DeflaterInputStream(is);
+        assertEquals(1, dis.available());
+        assertEquals(120, dis.read());
+        assertEquals(1, dis.available());
+        assertEquals(22, dis.read(buf2, 0, 256));
+        assertEquals(1, dis.available());
+        assertEquals(-1, dis.read());
+        assertEquals(0, dis.available());
+        try {
+            dis.read(buf1, 0, 512);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            dis.read(null, 0, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            dis.read(null, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            dis.read(null, -1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            dis.read(buf1, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            dis.read(buf1, 0, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        dis.close();
+        try {
+            dis.read(buf1, 0, 512);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(buf1, 0, 1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(null, 0, 0);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(null, -1, 0);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(null, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(buf1, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.read(buf1, 0, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests DeflaterInputStream#reset()
+     */
+    public void testReset() throws IOException {
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        try {
+            dis.reset();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        dis.close();
+        try {
+            dis.reset();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests DeflaterInputStream#skip()
+     */
+    public void testSkip() throws IOException {
+        byte[] buf = new byte[1024];
+        DeflaterInputStream dis = new DeflaterInputStream(is);
+        assertEquals(1, dis.available());
+        dis.skip(1);
+        assertEquals(1, dis.available());
+        assertEquals(22, dis.read(buf, 0, 1024));
+        assertEquals(1, dis.available());
+        dis.skip(1);
+        assertEquals(0, dis.available());
+        is = new ByteArrayInputStream(testStr.getBytes("UTF-8"));
+        dis = new DeflaterInputStream(is);
+        assertEquals(1, dis.available());
+        dis.skip(56);
+        assertEquals(0, dis.available());
+        assertEquals(-1, dis.read(buf, 0, 1024));
+        try {
+            dis.skip(-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(0, dis.available());
+        // can still skip
+        dis.skip(1);
+        dis.close();
+        try {
+            dis.skip(1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            dis.skip(-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        is = new ByteArrayInputStream(testStr.getBytes("UTF-8"));
+        dis = new DeflaterInputStream(is);
+        assertEquals(23, dis.skip(Long.MAX_VALUE));
+        assertEquals(0, dis.available());
+    }
+
+    /**
+     * @tests DeflaterInputStream#DeflaterInputStream(InputStream)
+     */
+    public void testDeflaterInputStreamInputStream() {
+        // ok
+        new DeflaterInputStream(is);
+        // fail
+        try {
+            new DeflaterInputStream(null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests DeflaterInputStream#DeflaterInputStream(InputStream,Deflater)
+     */
+    public void testDeflaterInputStreamInputStreamDeflater() {
+        // ok
+        new DeflaterInputStream(is, new Deflater());
+        // fail
+        try {
+            new DeflaterInputStream(is, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new DeflaterInputStream(null, new Deflater());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests DeflaterInputStream#DeflaterInputStream(InputStream,Deflater,int)
+     */
+    public void testDeflaterInputStreamInputStreamDeflaterInt() {
+        // ok
+        new DeflaterInputStream(is, new Deflater(), 1024);
+        // fail
+        try {
+            new DeflaterInputStream(is, null, 1024);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new DeflaterInputStream(null, new Deflater(), 1024);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new DeflaterInputStream(is, new Deflater(), -1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            new DeflaterInputStream(null, new Deflater(), -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new DeflaterInputStream(is, null, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        is = new ByteArrayInputStream(testStr.getBytes("UTF-8"));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        is.close();
+        super.tearDown();
+    }
+}
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterOutputStreamTest.java
index 738f610..be28774 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterOutputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterOutputStreamTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
@@ -34,7 +29,6 @@
 
 import junit.framework.TestCase;
 
-@TestTargetClass(DeflaterOutputStream.class)
 public class DeflaterOutputStreamTest extends TestCase {
 
     private class MyDeflaterOutputStream extends DeflaterOutputStream {
@@ -64,10 +58,6 @@
         boolean getDaflateFlag() {
             return deflateFlag;
         }
-
-        void cleanDaflateFlag() {
-            deflateFlag = false;
-        }
     }
 
     private byte outPutBuf[] = new byte[500];
@@ -75,7 +65,7 @@
     @Override
     protected void setUp() {
         // setting up a deflater to be used
-        byte byteArray[] = {1, 3, 4, 7, 8};
+        byte byteArray[] = { 1, 3, 4, 7, 8 };
         int x = 0;
         Deflater deflate = new Deflater(1);
         deflate.setInput(byteArray);
@@ -93,16 +83,9 @@
      * @tests java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream,
      *        java.util.zip.Deflater)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "DeflaterOutputStream",
-        args = {java.io.OutputStream.class, java.util.zip.Deflater.class}
-    )
-    public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Deflater()
-            throws Exception {
-        byte byteArray[] = {1, 3, 4, 7, 8};
-        File f1 = File.createTempFile("hyts_Constru_OD", ".tst");
+    public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Deflater() throws Exception {
+        byte byteArray[] = { 1, 3, 4, 7, 8 };
+        File f1 = new File("hyts_Constru(OD).tst");
         FileOutputStream fos = new FileOutputStream(f1);
         Deflater defl = null;
         MyDeflaterOutputStream dos;
@@ -127,14 +110,8 @@
     /**
      * @tests java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "DeflaterOutputStream",
-        args = {java.io.OutputStream.class}
-    )
     public void test_ConstructorLjava_io_OutputStream() throws Exception {
-        File f1 = File.createTempFile("hyts_Constru_O", ".tst");
+        File f1 = new File("hyts_Constru(O).tst");
         FileOutputStream fos = new FileOutputStream(f1);
         MyDeflaterOutputStream dos = new MyDeflaterOutputStream(fos);
 
@@ -151,19 +128,13 @@
      * @tests java.util.zip.DeflaterOutputStream#DeflaterOutputStream(java.io.OutputStream,
      *        java.util.zip.Deflater, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "DeflaterOutputStream",
-        args = {java.io.OutputStream.class, java.util.zip.Deflater.class, int.class}
-    )
     public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_DeflaterI()
             throws Exception {
         int buf = 5;
         int negBuf = -5;
         int zeroBuf = 0;
-        byte byteArray[] = {1, 3, 4, 7, 8, 3, 6};
-        File f1 = File.createTempFile("hyts_Constru_ODI", ".tst");
+        byte byteArray[] = { 1, 3, 4, 7, 8, 3, 6 };
+        File f1 = new File("hyts_Constru(ODI).tst");
         FileOutputStream fos = new FileOutputStream(f1);
         Deflater defl = null;
         MyDeflaterOutputStream dos;
@@ -203,12 +174,6 @@
     /**
      * @tests java.util.zip.DeflaterOutputStream#close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "IOException can not be checked.",
-        method = "close",
-        args = {}
-    )
     public void test_close() throws Exception {
         File f1 = File.createTempFile("close", ".tst");
 
@@ -268,20 +233,14 @@
     /**
      * @tests java.util.zip.DeflaterOutputStream#finish()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finish",
-        args = {}
-    )
     public void test_finish() throws Exception {
         // Need test to see if method finish() actually finishes
         // Only testing possible errors, not if it actually works
 
-        File f1 = File.createTempFile("finish", ".tst");
+        File f1 = new File("finish.tst");
         FileOutputStream fos1 = new FileOutputStream(f1);
         DeflaterOutputStream dos = new DeflaterOutputStream(fos1);
-        byte byteArray[] = {1, 3, 4, 6};
+        byte byteArray[] = { 1, 3, 4, 6 };
         dos.write(byteArray);
         dos.finish();
 
@@ -325,14 +284,8 @@
     /**
      * @tests java.util.zip.DeflaterOutputStream#write(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {int.class}
-    )
     public void test_writeI() throws Exception {
-        File f1 = File.createTempFile("writeI1", ".tst");
+        File f1 = new File("writeI1.tst");
         FileOutputStream fos = new FileOutputStream(f1);
         DeflaterOutputStream dos = new DeflaterOutputStream(fos);
         for (int i = 0; i < 3; i++) {
@@ -367,17 +320,11 @@
     /**
      * @tests java.util.zip.DeflaterOutputStream#write(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_write$BII() throws Exception {
-        byte byteArray[] = {1, 3, 4, 7, 8, 3, 6};
+        byte byteArray[] = { 1, 3, 4, 7, 8, 3, 6 };
 
         // Test to see if the correct bytes are saved.
-        File f1 = File.createTempFile("writeBII", ".tst");
+        File f1 = new File("writeBII.tst");
         FileOutputStream fos1 = new FileOutputStream(f1);
         DeflaterOutputStream dos1 = new DeflaterOutputStream(fos1);
         dos1.write(byteArray, 2, 3);
@@ -393,7 +340,7 @@
         f1.delete();
 
         // Test for trying to write more bytes than available from the array
-        File f2 = File.createTempFile("writeBII", ".tst");
+        File f2 = new File("writeBII2.tst");
         FileOutputStream fos2 = new FileOutputStream(f2);
         DeflaterOutputStream dos2 = new DeflaterOutputStream(fos2);
         try {
@@ -441,13 +388,6 @@
         f2.delete();
     }
 
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "deflate",
-        args = {}
-    )
     public void test_deflate() throws Exception {
         File f1 = File.createTempFile("writeI1", ".tst");
         FileOutputStream fos = new FileOutputStream(f1);
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterTest.java
index ae77450..93fe710 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/DeflaterTest.java
@@ -17,15 +17,9 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.zip.Adler32;
-
 import java.util.zip.DataFormatException;
 import java.util.zip.Deflater;
 import java.util.zip.Inflater;
@@ -33,447 +27,376 @@
 import junit.framework.TestCase;
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(Deflater.class)
 public class DeflaterTest extends TestCase {
 
-    class MyDeflater extends Deflater {
-        MyDeflater() {
-            super();
-        }
+	class MyDeflater extends Deflater {
+		MyDeflater() {
+			super();
+		}
 
-        MyDeflater(int lvl) {
-            super(lvl);
-        }
+		MyDeflater(int lvl) {
+			super(lvl);
+		}
 
-        MyDeflater(int lvl, boolean noHeader) {
-            super(lvl, noHeader);
-        }
+		MyDeflater(int lvl, boolean noHeader) {
+			super(lvl, noHeader);
+		}
 
-        void myFinalize() {
-            finalize();
-        }
+		void myFinalize() {
+			finalize();
+		}
 
-        int getDefCompression() {
-            return DEFAULT_COMPRESSION;
-        }
+		int getDefCompression() {
+			return DEFAULT_COMPRESSION;
+		}
 
-        int getDefStrategy() {
-            return DEFAULT_STRATEGY;
-        }
+		int getDefStrategy() {
+			return DEFAULT_STRATEGY;
+		}
 
-        int getHuffman() {
-            return HUFFMAN_ONLY;
-        }
+		int getHuffman() {
+			return HUFFMAN_ONLY;
+		}
 
-        int getFiltered() {
-            return FILTERED;
-        }
-    }
+		int getFiltered() {
+			return FILTERED;
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#deflate(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "deflate",
-        args = {byte[].class}
-    )
-    public void test_deflate$B() {
-        byte outPutBuf[] = new byte[50];
-        byte byteArray[] = {1, 3, 4, 7, 8};
-        byte outPutInf[] = new byte[50];
-        int x = 0;
+	/**
+	 * @tests java.util.zip.Deflater#deflate(byte[])
+	 */
+	public void test_deflate$B() {
+		byte outPutBuf[] = new byte[50];
+		byte byteArray[] = { 1, 3, 4, 7, 8 };
+		byte outPutInf[] = new byte[50];
+		int x = 0;
 
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             x += defl.deflate(outPutBuf);
         }
-        assertEquals("Deflater at end of stream, should return 0", 0, defl
-                .deflate(outPutBuf));
+		assertEquals("Deflater at end of stream, should return 0", 0, defl
+				.deflate(outPutBuf));
         int totalOut = defl.getTotalOut();
         int totalIn = defl.getTotalIn();
         assertEquals(x, totalOut);
         assertEquals(byteArray.length, totalIn);
-        defl.end();
+		defl.end();
 
-        Inflater infl = new Inflater();
-        try {
-            infl.setInput(outPutBuf);
-            while (!infl.finished()) {
+		Inflater infl = new Inflater();
+		try {
+			infl.setInput(outPutBuf);
+			while (!infl.finished()) {
                 infl.inflate(outPutInf);
             }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
         assertEquals(totalIn, infl.getTotalOut());
         assertEquals(totalOut, infl.getTotalIn());
-        for (int i = 0; i < byteArray.length; i++) {
+		for (int i = 0; i < byteArray.length; i++) {
             assertEquals(byteArray[i], outPutInf[i]);
         }
-        assertEquals(
-                "Final decompressed data contained more bytes than original",
-                0, outPutInf[byteArray.length]);
-        infl.end();
-    }
+		assertEquals("Final decompressed data contained more bytes than original",
+				0, outPutInf[byteArray.length]);
+		infl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#deflate(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "deflate",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_deflate$BII() {
-        byte outPutBuf[] = new byte[50];
-        byte byteArray[] = {5, 2, 3, 7, 8};
-        byte outPutInf[] = new byte[50];
-        int offSet = 1;
-        int length = outPutBuf.length - 1;
-        int x = 0;
+	/**
+	 * @tests java.util.zip.Deflater#deflate(byte[], int, int)
+	 */
+	public void test_deflate$BII() {
+		byte outPutBuf[] = new byte[50];
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
+		byte outPutInf[] = new byte[50];
+		int offSet = 1;
+		int length = outPutBuf.length - 1;
+		int x = 0;
 
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             x += defl.deflate(outPutBuf, offSet, length);
         }
-        assertEquals("Deflater at end of stream, should return 0", 0, defl
-                .deflate(outPutBuf, offSet, length));
-        int totalOut = defl.getTotalOut();
-        int totalIn = defl.getTotalIn();
+		assertEquals("Deflater at end of stream, should return 0", 0, defl.deflate(
+				outPutBuf, offSet, length));
+		int totalOut = defl.getTotalOut();
+		int totalIn = defl.getTotalIn();
         assertEquals(x, totalOut);
         assertEquals(byteArray.length, totalIn);
-        defl.end();
+		defl.end();
 
-        Inflater infl = new Inflater();
-        try {
-            infl.setInput(outPutBuf, offSet, length);
-            while (!infl.finished()) {
+		Inflater infl = new Inflater();
+		try {
+			infl.setInput(outPutBuf, offSet, length);
+			while (!infl.finished()) {
                 infl.inflate(outPutInf);
             }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
         assertEquals(totalIn, infl.getTotalOut());
         assertEquals(totalOut, infl.getTotalIn());
-        for (int i = 0; i < byteArray.length; i++) {
+		for (int i = 0; i < byteArray.length; i++) {
             assertEquals(byteArray[i], outPutInf[i]);
         }
-        assertEquals(
-                "Final decompressed data contained more bytes than original",
-                0, outPutInf[byteArray.length]);
-        infl.end();
+		assertEquals("Final decompressed data contained more bytes than original",
+				0, outPutInf[byteArray.length]);
+		infl.end();
 
-        // Set of tests testing the boundaries of the offSet/length
-        defl = new Deflater();
-        outPutBuf = new byte[100];
-        defl.setInput(byteArray);
-        for (int i = 0; i < 2; i++) {
-            if (i == 0) {
-                offSet = outPutBuf.length + 1;
-                length = outPutBuf.length;
-            } else {
-                offSet = 0;
-                length = outPutBuf.length + 1;
-            }
-            try {
-                defl.deflate(outPutBuf, offSet, length);
-                fail("Test " + i
-                        + ": ArrayIndexOutOfBoundsException not thrown");
-            } catch (ArrayIndexOutOfBoundsException e) {
-            }
-        }
-        defl.end();
-    }
+		// Set of tests testing the boundaries of the offSet/length
+		defl = new Deflater();
+		outPutBuf = new byte[100];
+		defl.setInput(byteArray);
+		for (int i = 0; i < 2; i++) {
+			if (i == 0) {
+				offSet = outPutBuf.length + 1;
+				length = outPutBuf.length;
+			} else {
+				offSet = 0;
+				length = outPutBuf.length + 1;
+			}
+			try {
+				defl.deflate(outPutBuf, offSet, length);
+				fail("Test " + i
+						+ ": ArrayIndexOutOfBoundsException not thrown");
+			} catch (ArrayIndexOutOfBoundsException e) {
+			}
+		}
+		defl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#end()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "end",
-        args = {}
-    )
-    public void test_end() {
-        byte byteArray[] = {5, 2, 3, 7, 8};
-        byte outPutBuf[] = new byte[100];
+	/**
+	 * @tests java.util.zip.Deflater#end()
+	 */
+	public void test_end() {
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
+		byte outPutBuf[] = new byte[100];
 
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        defl.end();
-        helper_end_test(defl, "end");
-    }
+		defl.end();
+		helper_end_test(defl, "end");
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#finalize()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finalize",
-        args = {}
-    )
-    public void test_finalize() {
-        MyDeflater mdefl = new MyDeflater();
-        mdefl.myFinalize();
-        System.gc();
-        helper_end_test(mdefl, "finalize");
-    }
+	/**
+	 * @tests java.util.zip.Deflater#finalize()
+	 */
+	public void test_finalize() {
+		MyDeflater mdefl = new MyDeflater();
+		mdefl.myFinalize();
+		System.gc();
+		helper_end_test(mdefl, "finalize");
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#finish()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finish",
-        args = {}
-    )
-    public void test_finish() throws Exception {
-        // This test already here, its the same as test_deflate()
-        byte byteArray[] = {5, 2, 3, 7, 8};
-        byte outPutBuf[] = new byte[100];
-        byte outPutInf[] = new byte[100];
-        int x = 0;
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        defl.finish();
+	/**
+	 * @tests java.util.zip.Deflater#finish()
+	 */
+	public void test_finish() throws Exception {
+		// This test already here, its the same as test_deflate()
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
+		byte outPutBuf[] = new byte[100];
+		byte outPutInf[] = new byte[100];
+		int x = 0;
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		defl.finish();
 
-        // needsInput should never return true after finish() is called
-        if (System.getProperty("java.vendor").startsWith("IBM")) {
-            assertFalse(
-                    "needsInput() should return false after finish() is called",
-                    defl.needsInput());
+		// needsInput should never return true after finish() is called
+		if (System.getProperty("java.vendor").startsWith("IBM")) {
+            assertFalse("needsInput() should return false after finish() is called", defl
+                    .needsInput());
         }
 
-        while (!defl.finished()) {
+		while (!defl.finished()) {
             x += defl.deflate(outPutBuf);
         }
-        int totalOut = defl.getTotalOut();
-        int totalIn = defl.getTotalIn();
+		int totalOut = defl.getTotalOut();
+		int totalIn = defl.getTotalIn();
         assertEquals(x, totalOut);
         assertEquals(byteArray.length, totalIn);
-        defl.end();
+		defl.end();
 
-        Inflater infl = new Inflater();
-        infl.setInput(outPutBuf);
-        while (!infl.finished()) {
-            infl.inflate(outPutInf);
-        }
+		Inflater infl = new Inflater();
+		infl.setInput(outPutBuf);
+		while (!infl.finished()) {
+		    infl.inflate(outPutInf);
+		}
         assertEquals(totalIn, infl.getTotalOut());
         assertEquals(totalOut, infl.getTotalIn());
-        for (int i = 0; i < byteArray.length; i++) {
+		for (int i = 0; i < byteArray.length; i++) {
             assertEquals(byteArray[i], outPutInf[i]);
         }
-        assertEquals(
-                "Final decompressed data contained more bytes than original",
-                0, outPutInf[byteArray.length]);
-        infl.end();
-    }
+		assertEquals("Final decompressed data contained more bytes than original",
+				0, outPutInf[byteArray.length]);
+		infl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#finished()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finished",
-        args = {}
-    )
-    public void test_finished() {
-        byte byteArray[] = {5, 2, 3, 7, 8};
-        byte outPutBuf[] = new byte[100];
-        Deflater defl = new Deflater();
-        assertTrue("Test 1: Deflater should not be finished.", !defl.finished());
-        defl.setInput(byteArray);
-        assertTrue("Test 2: Deflater should not be finished.", !defl.finished());
-        defl.finish();
-        assertTrue("Test 3: Deflater should not be finished.", !defl.finished());
-        while (!defl.finished()) {
+	/**
+	 * @tests java.util.zip.Deflater#finished()
+	 */
+	public void test_finished() {
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
+		byte outPutBuf[] = new byte[100];
+		Deflater defl = new Deflater();
+		assertTrue("Test 1: Deflater should not be finished.", !defl.finished());
+		defl.setInput(byteArray);
+		assertTrue("Test 2: Deflater should not be finished.", !defl.finished());
+		defl.finish();
+		assertTrue("Test 3: Deflater should not be finished.", !defl.finished());
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        assertTrue("Test 4: Deflater should be finished.", defl.finished());
-        defl.end();
-        assertTrue("Test 5: Deflater should be finished.", defl.finished());
-    }
+		assertTrue("Test 4: Deflater should be finished.", defl.finished());
+		defl.end();
+		assertTrue("Test 5: Deflater should be finished.", defl.finished());
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#getAdler()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAdler",
-        args = {}
-    )
-    public void test_getAdler() {
-        byte byteArray[] = {'a', 'b', 'c', 1, 2, 3};
-        byte outPutBuf[] = new byte[100];
-        Deflater defl = new Deflater();
+	/**
+	 * @tests java.util.zip.Deflater#getAdler()
+	 */
+	public void test_getAdler() {
+		byte byteArray[] = { 'a', 'b', 'c', 1, 2, 3 };
+		byte outPutBuf[] = new byte[100];
+		Deflater defl = new Deflater();
 
-        // getting the checkSum value using the Adler
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		// getting the checkSum value using the Adler
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        long checkSumD = defl.getAdler();
-        defl.end();
+		long checkSumD = defl.getAdler();
+		defl.end();
 
-        // getting the checkSum value through the Adler32 class
-        Adler32 adl = new Adler32();
-        adl.update(byteArray);
-        long checkSumR = adl.getValue();
-        assertEquals(
+		// getting the checkSum value through the Adler32 class
+		Adler32 adl = new Adler32();
+		adl.update(byteArray);
+		long checkSumR = adl.getValue();
+		assertEquals(
                 "The checksum value returned by getAdler() is not the same as the checksum returned by creating the adler32 instance",
                 checkSumD, checkSumR);
-    }
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#getTotalIn()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTotalIn",
-        args = {}
-    )
-    public void test_getTotalIn() {
-        byte outPutBuf[] = new byte[5];
-        byte byteArray[] = {1, 3, 4, 7, 8};
+	/**
+	 * @tests java.util.zip.Deflater#getTotalIn()
+	 */
+	public void test_getTotalIn() {
+		byte outPutBuf[] = new byte[5];
+		byte byteArray[] = { 1, 3, 4, 7, 8 };
 
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
         assertEquals(byteArray.length, defl.getTotalIn());
-        defl.end();
+		defl.end();
 
-        defl = new Deflater();
-        int offSet = 2;
-        int length = 3;
-        outPutBuf = new byte[5];
-        defl.setInput(byteArray, offSet, length);
-        defl.finish();
-        while (!defl.finished()) {
+		defl = new Deflater();
+		int offSet = 2;
+		int length = 3;
+		outPutBuf = new byte[5];
+		defl.setInput(byteArray, offSet, length);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
         assertEquals(length, defl.getTotalIn());
-        defl.end();
-    }
+		defl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#getTotalOut()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTotalOut",
-        args = {}
-    )
-    public void test_getTotalOut() {
-        // the getTotalOut should equal the sum of value returned by deflate()
-        byte outPutBuf[] = new byte[5];
-        byte byteArray[] = {5, 2, 3, 7, 8};
-        int x = 0;
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+	/**
+	 * @tests java.util.zip.Deflater#getTotalOut()
+	 */
+	public void test_getTotalOut() {
+		// the getTotalOut should equal the sum of value returned by deflate()
+		byte outPutBuf[] = new byte[5];
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
+		int x = 0;
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             x += defl.deflate(outPutBuf);
         }
         assertEquals(x, defl.getTotalOut());
-        defl.end();
+		defl.end();
 
-        x = 0;
-        int offSet = 2;
-        int length = 3;
-        defl = new Deflater();
-        outPutBuf = new byte[5];
-        defl.setInput(byteArray, offSet, length);
-        defl.finish();
-        while (!defl.finished()) {
+		x = 0;
+		int offSet = 2;
+		int length = 3;
+		defl = new Deflater();
+		outPutBuf = new byte[5];
+		defl.setInput(byteArray, offSet, length);
+		defl.finish();
+		while (!defl.finished()) {
             x += defl.deflate(outPutBuf);
         }
         assertEquals(x, defl.getTotalOut());
-    }
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#needsInput()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "needsInput",
-        args = {}
-    )
-    public void test_needsInput() {
-        Deflater defl = new Deflater();
-        assertTrue(
-                "needsInput give the wrong boolean value as a result of no input buffer",
-                defl.needsInput());
-        byte byteArray[] = {1, 2, 3};
-        defl.setInput(byteArray);
-        assertFalse(
-                "needsInput give wrong boolean value as a result of a full input buffer",
-                defl.needsInput());
-        byte[] outPutBuf = new byte[50];
-        while (!defl.needsInput()) {
+	/**
+	 * @tests java.util.zip.Deflater#needsInput()
+	 */
+	public void test_needsInput() {
+		Deflater defl = new Deflater();
+		assertTrue(
+				"needsInput give the wrong boolean value as a result of no input buffer",
+				defl.needsInput());
+		byte byteArray[] = { 1, 2, 3 };
+		defl.setInput(byteArray);
+		assertFalse(
+				"needsInput give wrong boolean value as a result of a full input buffer",
+				defl.needsInput());
+		byte[] outPutBuf = new byte[50];
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        byte emptyByteArray[] = new byte[0];
-        defl.setInput(emptyByteArray);
-        assertTrue(
-                "needsInput give wrong boolean value as a result of an empty input buffer",
-                defl.needsInput());
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		byte emptyByteArray[] = new byte[0];
+		defl.setInput(emptyByteArray);
+		assertTrue(
+				"needsInput give wrong boolean value as a result of an empty input buffer",
+				defl.needsInput());
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        // needsInput should NOT return true after finish() has been
-        // called.
-        if (System.getProperty("java.vendor").startsWith("IBM")) {
+		// needsInput should NOT return true after finish() has been
+		// called.
+		if (System.getProperty("java.vendor").startsWith("IBM")) {
             assertFalse(
-                    "needsInput gave wrong boolean value as a result of finish() being called",
-                    defl.needsInput());
+					"needsInput gave wrong boolean value as a result of finish() being called",
+					defl.needsInput());
         }
-        defl.end();
-    }
+		defl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#reset()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reset",
-        args = {}
-    )
-    public void test_reset() {
-        byte outPutBuf[] = new byte[100];
-        byte outPutInf[] = new byte[100];
-        byte curArray[] = new byte[5];
-        byte byteArray[] = {1, 3, 4, 7, 8};
-        byte byteArray2[] = {8, 7, 4, 3, 1};
-        int x = 0;
-        int orgValue = 0;
-        Deflater defl = new Deflater();
+	/**
+	 * @tests java.util.zip.Deflater#reset()
+	 */
+	public void test_reset() {
+		byte outPutBuf[] = new byte[100];
+		byte outPutInf[] = new byte[100];
+		byte curArray[] = new byte[5];
+		byte byteArray[] = { 1, 3, 4, 7, 8 };
+		byte byteArray2[] = { 8, 7, 4, 3, 1 };
+		int x = 0;
+		int orgValue = 0;
+		Deflater defl = new Deflater();
 
-        for (int i = 0; i < 3; i++) {
-            if (i == 0) {
+		for (int i = 0; i < 3; i++) {
+			if (i == 0) {
                 curArray = byteArray;
             } else if (i == 1) {
                 curArray = byteArray2;
@@ -481,13 +404,13 @@
                 defl.reset();
             }
 
-            defl.setInput(curArray);
-            defl.finish();
-            while (!defl.finished()) {
+			defl.setInput(curArray);
+			defl.finish();
+			while (!defl.finished()) {
                 x += defl.deflate(outPutBuf);
             }
 
-            if (i == 0) {
+			if (i == 0) {
                 assertEquals(x, defl.getTotalOut());
             } else if (i == 1) {
                 assertEquals(x, orgValue);
@@ -495,333 +418,296 @@
                 assertEquals(x, orgValue * 2);
             }
 
-            if (i == 0) {
+			if (i == 0) {
                 orgValue = x;
             }
 
-            try {
-                Inflater infl = new Inflater();
-                infl.setInput(outPutBuf);
-                while (!infl.finished()) {
+			try {
+				Inflater infl = new Inflater();
+				infl.setInput(outPutBuf);
+				while (!infl.finished()) {
                     infl.inflate(outPutInf);
                 }
-                infl.end();
-            } catch (DataFormatException e) {
-                fail("Test " + i + ": Invalid input to be decompressed");
-            }
+				infl.end();
+			} catch (DataFormatException e) {
+				fail("Test " + i + ": Invalid input to be decompressed");
+			}
 
-            if (i == 1) {
+			if (i == 1) {
                 curArray = byteArray;
             }
 
-            for (int j = 0; j < curArray.length; j++) {
+			for (int j = 0; j < curArray.length; j++) {
                 assertEquals(curArray[j], outPutInf[j]);
             }
             assertEquals(0, outPutInf[curArray.length]);
-        }
-    }
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#setDictionary(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setDictionary",
-        args = {byte[].class}
-    )
-    public void test_setDictionary$B() {
-        // This test is very close to getAdler()
-        byte dictionaryArray[] = {'e', 'r', 't', 'a', 'b', 2, 3};
-        byte byteArray[] = {
-                4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3', 'w', 'r'};
-        byte outPutBuf[] = new byte[100];
+	/**
+	 * @tests java.util.zip.Deflater#setDictionary(byte[])
+	 */
+	public void test_setDictionary$B() {
+		// This test is very close to getAdler()
+		byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
+		byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+				'w', 'r' };
+		byte outPutBuf[] = new byte[100];
 
-        Deflater defl = new Deflater();
-        long deflAdler = defl.getAdler();
-        assertEquals(
-                "No dictionary set, no data deflated, getAdler should return 1",
-                1, deflAdler);
-        defl.setDictionary(dictionaryArray);
-        deflAdler = defl.getAdler();
+		Deflater defl = new Deflater();
+		long deflAdler = defl.getAdler();
+		assertEquals("No dictionary set, no data deflated, getAdler should return 1",
+				1, deflAdler);
+		defl.setDictionary(dictionaryArray);
+		deflAdler = defl.getAdler();
 
-        // getting the checkSum value through the Adler32 class
-        Adler32 adl = new Adler32();
-        adl.update(dictionaryArray);
-        long realAdler = adl.getValue();
+		// getting the checkSum value through the Adler32 class
+		Adler32 adl = new Adler32();
+		adl.update(dictionaryArray);
+		long realAdler = adl.getValue();
         assertEquals(deflAdler, realAdler);
 
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        deflAdler = defl.getAdler();
-        adl = new Adler32();
-        adl.update(byteArray);
-        realAdler = adl.getValue();
-        // Deflate is finished and there were bytes deflated that did not occur
-        // in the dictionaryArray, therefore a new dictionary was automatically
-        // set.
+		deflAdler = defl.getAdler();
+		adl = new Adler32();
+		adl.update(byteArray);
+		realAdler = adl.getValue();
+		// Deflate is finished and there were bytes deflated that did not occur
+		// in the dictionaryArray, therefore a new dictionary was automatically
+		// set.
         assertEquals(realAdler, deflAdler);
-        defl.end();
-    }
+		defl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#setDictionary(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setDictionary",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_setDictionary$BII() {
-        // This test is very close to getAdler()
-        byte dictionaryArray[] = {'e', 'r', 't', 'a', 'b', 2, 3, 'o', 't'};
-        byte byteArray[] = {
-                4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3', 'w', 'r', 't',
-                'u', 'i', 'o', 4, 5, 6, 7};
-        byte outPutBuf[] = new byte[500];
+	/**
+	 * @tests java.util.zip.Deflater#setDictionary(byte[], int, int)
+	 */
+	public void test_setDictionary$BII() {
+		// This test is very close to getAdler()
+		byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3, 'o', 't' };
+		byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+				'w', 'r', 't', 'u', 'i', 'o', 4, 5, 6, 7 };
+		byte outPutBuf[] = new byte[500];
 
-        int offSet = 4;
-        int length = 5;
+		int offSet = 4;
+		int length = 5;
 
-        Deflater defl = new Deflater();
-        long deflAdler = defl.getAdler();
-        assertEquals(
-                "No dictionary set, no data deflated, getAdler should return 1",
-                1, deflAdler);
-        defl.setDictionary(dictionaryArray, offSet, length);
-        deflAdler = defl.getAdler();
+		Deflater defl = new Deflater();
+		long deflAdler = defl.getAdler();
+		assertEquals("No dictionary set, no data deflated, getAdler should return 1",
+				1, deflAdler);
+		defl.setDictionary(dictionaryArray, offSet, length);
+		deflAdler = defl.getAdler();
 
-        // getting the checkSum value through the Adler32 class
-        Adler32 adl = new Adler32();
-        adl.update(dictionaryArray, offSet, length);
-        long realAdler = adl.getValue();
+		// getting the checkSum value through the Adler32 class
+		Adler32 adl = new Adler32();
+		adl.update(dictionaryArray, offSet, length);
+		long realAdler = adl.getValue();
         assertEquals(deflAdler, realAdler);
 
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        deflAdler = defl.getAdler();
-        adl = new Adler32();
-        adl.update(byteArray);
-        realAdler = adl.getValue();
-        // Deflate is finished and there were bytes deflated that did not occur
-        // in the dictionaryArray, therefore a new dictionary was automatically
-        // set.
+		deflAdler = defl.getAdler();
+		adl = new Adler32();
+		adl.update(byteArray);
+		realAdler = adl.getValue();
+		// Deflate is finished and there were bytes deflated that did not occur
+		// in the dictionaryArray, therefore a new dictionary was automatically
+		// set.
         assertEquals(realAdler, deflAdler);
-        defl.end();
+		defl.end();
 
-        // boundary check
-        defl = new Deflater();
-        for (int i = 0; i < 2; i++) {
-            if (i == 0) {
-                offSet = 0;
-                length = dictionaryArray.length + 1;
-            } else {
-                offSet = dictionaryArray.length + 1;
-                length = 1;
-            }
-            try {
-                defl.setDictionary(dictionaryArray, offSet, length);
-                fail("Test "
-                        + i
-                        + ": boundary check for setDictionary failed for offset "
-                        + offSet + " and length " + length);
-            } catch (ArrayIndexOutOfBoundsException e) {
-            }
-        }
-    }
+		// boundary check
+		defl = new Deflater();
+		for (int i = 0; i < 2; i++) {
+			if (i == 0) {
+				offSet = 0;
+				length = dictionaryArray.length + 1;
+			} else {
+				offSet = dictionaryArray.length + 1;
+				length = 1;
+			}
+			try {
+				defl.setDictionary(dictionaryArray, offSet, length);
+				fail(
+						"Test "
+								+ i
+								+ ": boundary check for setDictionary failed for offset "
+								+ offSet + " and length " + length);
+			} catch (ArrayIndexOutOfBoundsException e) {
+			}
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#setInput(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setInput",
-        args = {byte[].class}
-    )
-    public void test_setInput$B() {
-        byte[] byteArray = {1, 2, 3};
-        byte[] outPutBuf = new byte[50];
-        byte[] outPutInf = new byte[50];
+	/**
+	 * @tests java.util.zip.Deflater#setInput(byte[])
+	 */
+	public void test_setInput$B() {
+		byte[] byteArray = { 1, 2, 3 };
+		byte[] outPutBuf = new byte[50];
+		byte[] outPutInf = new byte[50];
 
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray);
-        assertTrue("the array buffer in setInput() is empty", !defl
-                .needsInput());
-        // The second setInput() should be ignored since needsInput() return
-        // false
-        defl.setInput(byteArray);
-        defl.finish();
-        while (!defl.finished()) {
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray);
+		assertTrue("the array buffer in setInput() is empty", !defl
+				.needsInput());
+		// The second setInput() should be ignored since needsInput() return
+		// false
+		defl.setInput(byteArray);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        defl.end();
+		defl.end();
 
-        Inflater infl = new Inflater();
-        try {
-            infl.setInput(outPutBuf);
-            while (!infl.finished()) {
+		Inflater infl = new Inflater();
+		try {
+			infl.setInput(outPutBuf);
+			while (!infl.finished()) {
                 infl.inflate(outPutInf);
             }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < byteArray.length; i++) {
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
             assertEquals(byteArray[i], outPutInf[i]);
         }
-        assertEquals(byteArray.length, infl.getTotalOut());
-        infl.end();
-    }
+		assertEquals(byteArray.length, infl.getTotalOut());
+		infl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#setInput(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setInput",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_setInput$BII() throws Exception {
-        byte[] byteArray = {1, 2, 3, 4, 5};
-        byte[] outPutBuf = new byte[50];
-        byte[] outPutInf = new byte[50];
-        int offSet = 1;
-        int length = 3;
+	/**
+	 * @tests java.util.zip.Deflater#setInput(byte[], int, int)
+	 */
+	public void test_setInput$BII() throws Exception {
+		byte[] byteArray = { 1, 2, 3, 4, 5 };
+		byte[] outPutBuf = new byte[50];
+		byte[] outPutInf = new byte[50];
+		int offSet = 1;
+		int length = 3;
 
-        Deflater defl = new Deflater();
-        defl.setInput(byteArray, offSet, length);
-        assertFalse("the array buffer in setInput() is empty", defl
-                .needsInput());
-        // The second setInput() should be ignored since needsInput() return
-        // false
-        defl.setInput(byteArray, offSet, length);
-        defl.finish();
-        while (!defl.finished()) {
+		Deflater defl = new Deflater();
+		defl.setInput(byteArray, offSet, length);
+		assertFalse("the array buffer in setInput() is empty", defl.needsInput());
+		// The second setInput() should be ignored since needsInput() return
+		// false
+		defl.setInput(byteArray, offSet, length);
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        defl.end();
+		defl.end();
 
-        Inflater infl = new Inflater();
-        infl.setInput(outPutBuf);
-        while (!infl.finished()) {
-            infl.inflate(outPutInf);
-        }
-        for (int i = 0; i < length; i++) {
+		Inflater infl = new Inflater();
+		infl.setInput(outPutBuf);
+		while (!infl.finished()) {
+		    infl.inflate(outPutInf);
+		}
+		for (int i = 0; i < length; i++) {
             assertEquals(byteArray[i + offSet], outPutInf[i]);
         }
-        assertEquals(length, infl.getTotalOut());
-        infl.end();
+		assertEquals(length, infl.getTotalOut());
+		infl.end();
 
-        // boundary check
-        defl = new Deflater();
-        for (int i = 0; i < 2; i++) {
-            if (i == 0) {
-                offSet = 0;
-                length = byteArray.length + 1;
-            } else {
-                offSet = byteArray.length + 1;
-                length = 1;
-            }
-            try {
-                defl.setInput(byteArray, offSet, length);
-                fail("Test " + i
-                        + ": boundary check for setInput failed for offset "
-                        + offSet + " and length " + length);
-            } catch (ArrayIndexOutOfBoundsException e) {
-            }
-        }
-    }
+		// boundary check
+		defl = new Deflater();
+		for (int i = 0; i < 2; i++) {
+			if (i == 0) {
+				offSet = 0;
+				length = byteArray.length + 1;
+			} else {
+				offSet = byteArray.length + 1;
+				length = 1;
+			}
+			try {
+				defl.setInput(byteArray, offSet, length);
+				fail("Test " + i
+						+ ": boundary check for setInput failed for offset "
+						+ offSet + " and length " + length);
+			} catch (ArrayIndexOutOfBoundsException e) {
+			}
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#setLevel(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setLevel",
-        args = {int.class}
-    )
-    public void test_setLevelI() throws Exception {
-        // Very similar to test_Constructor(int)
-        byte[] byteArray = new byte[100];
-        InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
-        inFile.read(byteArray);
-        inFile.close();
+	/**
+	 * @tests java.util.zip.Deflater#setLevel(int)
+	 */
+	public void test_setLevelI() throws Exception {
+		// Very similar to test_Constructor(int)
+		byte[] byteArray = new byte[100];
+		InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+		inFile.read(byteArray);
+		inFile.close();
 
-        byte[] outPutBuf;
-        int totalOut;
-        for (int i = 0; i < 10; i++) {
-            Deflater defl = new Deflater();
-            defl.setLevel(i);
-            outPutBuf = new byte[500];
-            defl.setInput(byteArray);
-            while (!defl.needsInput()) {
+		byte[] outPutBuf;
+		int totalOut;
+		for (int i = 0; i < 10; i++) {
+			Deflater defl = new Deflater();
+			defl.setLevel(i);
+			outPutBuf = new byte[500];
+			defl.setInput(byteArray);
+			while (!defl.needsInput()) {
                 defl.deflate(outPutBuf);
             }
-            defl.finish();
-            while (!defl.finished()) {
+			defl.finish();
+			while (!defl.finished()) {
                 defl.deflate(outPutBuf);
             }
-            totalOut = defl.getTotalOut();
-            defl.end();
+			totalOut = defl.getTotalOut();
+			defl.end();
 
-            outPutBuf = new byte[500];
-            defl = new Deflater(i);
-            defl.setInput(byteArray);
-            while (!defl.needsInput()) {
+			outPutBuf = new byte[500];
+			defl = new Deflater(i);
+			defl.setInput(byteArray);
+			while (!defl.needsInput()) {
                 defl.deflate(outPutBuf);
             }
-            defl.finish();
-            while (!defl.finished()) {
+			defl.finish();
+			while (!defl.finished()) {
                 defl.deflate(outPutBuf);
             }
-            assertEquals(totalOut, defl.getTotalOut());
-            defl.end();
-        }
+			assertEquals(totalOut, defl.getTotalOut());
+			defl.end();
+		}
 
-        // testing boundaries
-        try {
-            Deflater boundDefl = new Deflater();
-            // Level must be between 0-9
-            boundDefl.setLevel(-2);
-            fail("IllegalArgumentException not thrown when setting level to a number < 0.");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            Deflater boundDefl = new Deflater();
-            boundDefl.setLevel(10);
-            fail("IllegalArgumentException not thrown when setting level to a number > 9.");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+		// testing boundaries
+		try {
+			Deflater boundDefl = new Deflater();
+			// Level must be between 0-9
+			boundDefl.setLevel(-2);
+			fail(
+					"IllegalArgumentException not thrown when setting level to a number < 0.");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			Deflater boundDefl = new Deflater();
+			boundDefl.setLevel(10);
+			fail(
+					"IllegalArgumentException not thrown when setting level to a number > 9.");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#setStrategy(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setStrategy",
-        args = {int.class}
-    )
-    public void test_setStrategyI() throws Exception {
-        byte[] byteArray = new byte[100];
-        InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
-        inFile.read(byteArray);
-        inFile.close();
+	/**
+	 * @tests java.util.zip.Deflater#setStrategy(int)
+	 */
+	public void test_setStrategyI() throws Exception {
+		byte[] byteArray = new byte[100];
+			InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+			inFile.read(byteArray);
+			inFile.close();
 
-        for (int i = 0; i < 3; i++) {
-            byte outPutBuf[] = new byte[500];
-            MyDeflater mdefl = new MyDeflater();
+		for (int i = 0; i < 3; i++) {
+			byte outPutBuf[] = new byte[500];
+			MyDeflater mdefl = new MyDeflater();
 
-            if (i == 0) {
+			if (i == 0) {
                 mdefl.setStrategy(mdefl.getDefStrategy());
             } else if (i == 1) {
                 mdefl.setStrategy(mdefl.getHuffman());
@@ -829,335 +715,325 @@
                 mdefl.setStrategy(mdefl.getFiltered());
             }
 
-            mdefl.setInput(byteArray);
-            while (!mdefl.needsInput()) {
+			mdefl.setInput(byteArray);
+			while (!mdefl.needsInput()) {
                 mdefl.deflate(outPutBuf);
             }
-            mdefl.finish();
-            while (!mdefl.finished()) {
+			mdefl.finish();
+			while (!mdefl.finished()) {
                 mdefl.deflate(outPutBuf);
             }
 
-            if (i == 0) {
-                // System.out.println(mdefl.getTotalOut());
-                // ran JDK and found that getTotalOut() = 86 for this particular
-                // file
-                assertEquals(
-                        "getTotalOut() for the default strategy did not correspond with JDK",
-                        86, mdefl.getTotalOut());
-            } else if (i == 1) {
-                // System.out.println(mdefl.getTotalOut());
-                // ran JDK and found that getTotalOut() = 100 for this
-                // particular file
-                assertEquals(
-                        "getTotalOut() for the Huffman strategy did not correspond with JDK",
-                        100, mdefl.getTotalOut());
-            } else {
-                // System.out.println(mdefl.getTotalOut());
-                // ran JDK and found that totalOut = 93 for this particular file
-                assertEquals(
-                        "Total Out for the Filtered strategy did not correspond with JDK",
-                        93, mdefl.getTotalOut());
-            }
-            mdefl.end();
-        }
+			if (i == 0) {
+				// System.out.println(mdefl.getTotalOut());
+				// ran JDK and found that getTotalOut() = 86 for this particular
+				// file
+				assertEquals("getTotalOut() for the default strategy did not correspond with JDK",
+						86, mdefl.getTotalOut());
+			} else if (i == 1) {
+				// System.out.println(mdefl.getTotalOut());
+				// ran JDK and found that getTotalOut() = 100 for this
+				// particular file
+				assertEquals("getTotalOut() for the Huffman strategy did not correspond with JDK",
+						100, mdefl.getTotalOut());
+			} else {
+				// System.out.println(mdefl.getTotalOut());
+				// ran JDK and found that totalOut = 93 for this particular file
+				assertEquals("Total Out for the Filtered strategy did not correspond with JDK",
+						93, mdefl.getTotalOut());
+			}
+			mdefl.end();
+		}
 
-        // Attempting to setStrategy to an invalid value
-        try {
-            Deflater defl = new Deflater();
-            defl.setStrategy(-412);
-            fail("IllegalArgumentException not thrown when setting strategy to an invalid value.");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+		// Attempting to setStrategy to an invalid value
+		try {
+			Deflater defl = new Deflater();
+			defl.setStrategy(-412);
+			fail(
+					"IllegalArgumentException not thrown when setting strategy to an invalid value.");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#Deflater()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Deflater",
-        args = {}
-    )
-    public void test_Constructor() throws Exception {
-        byte[] byteArray = new byte[100];
-        InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
-        inFile.read(byteArray);
-        inFile.close();
+	/**
+	 * @tests java.util.zip.Deflater#Deflater()
+	 */
+	public void test_Constructor() throws Exception {
+		byte[] byteArray = new byte[100];
+		InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
+		inFile.read(byteArray);
+		inFile.close();
 
-        Deflater defl = new Deflater();
-        byte[] outPutBuf = new byte[500];
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		Deflater defl = new Deflater();
+		byte[] outPutBuf = new byte[500];
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        defl.finish();
-        while (!defl.finished()) {
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        int totalOut = defl.getTotalOut();
-        defl.end();
+		int totalOut = defl.getTotalOut();
+		defl.end();
 
-        // creating a Deflater using the DEFAULT_COMPRESSION as the int
-        MyDeflater mdefl = new MyDeflater();
-        mdefl = new MyDeflater(mdefl.getDefCompression());
-        outPutBuf = new byte[500];
-        mdefl.setInput(byteArray);
-        while (!mdefl.needsInput()) {
+		// creating a Deflater using the DEFAULT_COMPRESSION as the int
+		MyDeflater mdefl = new MyDeflater();
+		mdefl = new MyDeflater(mdefl.getDefCompression());
+		outPutBuf = new byte[500];
+		mdefl.setInput(byteArray);
+		while (!mdefl.needsInput()) {
             mdefl.deflate(outPutBuf);
         }
-        mdefl.finish();
-        while (!mdefl.finished()) {
+		mdefl.finish();
+		while (!mdefl.finished()) {
             mdefl.deflate(outPutBuf);
         }
-        assertEquals(totalOut, mdefl.getTotalOut());
-        mdefl.end();
-    }
+		assertEquals(totalOut, mdefl.getTotalOut());
+		mdefl.end();
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#Deflater(int, boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Deflater",
-        args = {int.class, boolean.class}
-    )
-    public void test_ConstructorIZ() throws Exception {
-        byte byteArray[] = {
-                4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3', 'w', 'r'};
+	/**
+	 * @tests java.util.zip.Deflater#Deflater(int, boolean)
+	 */
+	public void test_ConstructorIZ() throws Exception {
+		byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+				'w', 'r' };
 
-        Deflater defl = new Deflater();
-        byte outPutBuf[] = new byte[500];
-        defl.setLevel(2);
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		Deflater defl = new Deflater();
+		byte outPutBuf[] = new byte[500];
+		defl.setLevel(2);
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        defl.finish();
-        while (!defl.finished()) {
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        int totalOut = defl.getTotalOut();
-        defl.end();
+		int totalOut = defl.getTotalOut();
+		defl.end();
 
-        outPutBuf = new byte[500];
-        defl = new Deflater(2, false);
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		outPutBuf = new byte[500];
+		defl = new Deflater(2, false);
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        defl.finish();
-        while (!defl.finished()) {
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        assertEquals(totalOut, defl.getTotalOut());
-        defl.end();
+		assertEquals(totalOut, defl.getTotalOut());
+		defl.end();
 
-        outPutBuf = new byte[500];
-        defl = new Deflater(2, true);
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		outPutBuf = new byte[500];
+		defl = new Deflater(2, true);
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        defl.finish();
-        while (!defl.finished()) {
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        assertTrue(
-                "getTotalOut() should not be equal comparing two Deflaters with different header options.",
-                defl.getTotalOut() != totalOut);
-        defl.end();
+		assertTrue(
+				"getTotalOut() should not be equal comparing two Deflaters with different header options.",
+				defl.getTotalOut() != totalOut);
+		defl.end();
 
-        byte outPutInf[] = new byte[500];
-        Inflater infl = new Inflater(true);
-        while (!infl.finished()) {
-            if (infl.needsInput()) {
-                infl.setInput(outPutBuf);
-            }
-            infl.inflate(outPutInf);
-        }
-        for (int i = 0; i < byteArray.length; i++) {
+		byte outPutInf[] = new byte[500];
+		Inflater infl = new Inflater(true);
+		while (!infl.finished()) {
+		    if (infl.needsInput()) {
+		        infl.setInput(outPutBuf);
+		    }
+		    infl.inflate(outPutInf);
+		}
+		for (int i = 0; i < byteArray.length; i++) {
             assertEquals(byteArray[i], outPutInf[i]);
         }
-        assertEquals(
-                "final decompressed data contained more bytes than original - constructorIZ",
-                0, outPutInf[byteArray.length]);
-        infl.end();
+		assertEquals("final decompressed data contained more bytes than original - constructorIZ",
+				0, outPutInf[byteArray.length]);
+		infl.end();
 
-        infl = new Inflater(false);
-        outPutInf = new byte[500];
-        int r = 0;
-        try {
-            while (!infl.finished()) {
-                if (infl.needsInput()) {
+		infl = new Inflater(false);
+		outPutInf = new byte[500];
+		int r = 0;
+		try {
+			while (!infl.finished()) {
+				if (infl.needsInput()) {
                     infl.setInput(outPutBuf);
                 }
-                infl.inflate(outPutInf);
-            }
-        } catch (DataFormatException e) {
-            r = 1;
-        }
-        assertEquals("header option did not correspond", 1, r);
+				infl.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			r = 1;
+		}
+		assertEquals("header option did not correspond", 1, r);
 
-        // testing boundaries
-        try {
-            Deflater boundDefl = new Deflater();
-            // Level must be between 0-9
-            boundDefl.setLevel(-2);
-            fail("IllegalArgumentException not thrown when setting level to a number < 0.");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            Deflater boundDefl = new Deflater();
-            boundDefl.setLevel(10);
-            fail("IllegalArgumentException not thrown when setting level to a number > 9.");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+		// testing boundaries
+		try {
+			Deflater boundDefl = new Deflater();
+			// Level must be between 0-9
+			boundDefl.setLevel(-2);
+			fail("IllegalArgumentException not thrown when setting level to a number < 0.");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			Deflater boundDefl = new Deflater();
+			boundDefl.setLevel(10);
+			fail("IllegalArgumentException not thrown when setting level to a number > 9.");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Deflater#Deflater(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Deflater",
-        args = {int.class}
-    )
-    public void test_ConstructorI() throws Exception {
-        byte[] byteArray = new byte[100];
+	/**
+	 * @tests java.util.zip.Deflater#Deflater(int)
+	 */
+	public void test_ConstructorI() throws Exception {
+	    byte[] byteArray = new byte[100];
         InputStream inFile = Support_Resources.getStream("hyts_checkInput.txt");
         inFile.read(byteArray);
         inFile.close();
 
-        byte outPutBuf[] = new byte[500];
-        Deflater defl = new Deflater(3);
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		byte outPutBuf[] = new byte[500];
+		Deflater defl = new Deflater(3);
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        defl.finish();
-        while (!defl.finished()) {
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        int totalOut = defl.getTotalOut();
-        defl.end();
+		int totalOut = defl.getTotalOut();
+		defl.end();
 
-        // test to see if the compression ratio is the same as setting the level
-        // on a deflater
-        outPutBuf = new byte[500];
-        defl = new Deflater();
-        defl.setLevel(3);
-        defl.setInput(byteArray);
-        while (!defl.needsInput()) {
+		// test to see if the compression ratio is the same as setting the level
+		// on a deflater
+		outPutBuf = new byte[500];
+		defl = new Deflater();
+		defl.setLevel(3);
+		defl.setInput(byteArray);
+		while (!defl.needsInput()) {
             defl.deflate(outPutBuf);
         }
-        defl.finish();
-        while (!defl.finished()) {
+		defl.finish();
+		while (!defl.finished()) {
             defl.deflate(outPutBuf);
         }
-        assertEquals(totalOut, defl.getTotalOut());
-        defl.end();
+		assertEquals(totalOut, defl.getTotalOut());
+		defl.end();
 
-        // testing boundaries
-        try {
+		// testing boundaries
+		try {
             Deflater boundDefl = new Deflater();
             // Level must be between 0-9
             boundDefl.setLevel(-2);
             fail("IllegalArgumentException not thrown when setting level to a number < 0.");
         } catch (IllegalArgumentException e) {
-        }
-        try {
+		}
+		try {
             Deflater boundDefl = new Deflater();
             boundDefl.setLevel(10);
             fail("IllegalArgumentException not thrown when setting level to a number > 9.");
         } catch (IllegalArgumentException e) {
         }
-    }
+	}
 
-    private void helper_end_test(Deflater defl, String desc) {
-        // Help tests for test_end() and test_reset().
-        byte byteArray[] = {5, 2, 3, 7, 8};
+	private void helper_end_test(Deflater defl, String desc) {
+		// Help tests for test_end() and test_reset().
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
 
-        // Methods where we expect IllegalStateException or NullPointerException
-        // to be thrown
-        try {
-            defl.getTotalOut();
-            fail("defl.getTotalOut() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
-        try {
-            defl.getTotalIn();
-            fail("defl.getTotalIn() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
-        try {
-            defl.getAdler();
-            fail("defl.getAdler() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
-        try {
-            byte[] dict = {'a', 'b', 'c'};
-            defl.setDictionary(dict);
-            fail("defl.setDictionary() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
-        try {
-            defl.getTotalIn();
-            fail("defl.getTotalIn() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
-        try {
-            defl.getTotalIn();
-            fail("defl.getTotalIn() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
-        try {
-            defl.deflate(byteArray);
-            fail("defl.deflate() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (IllegalStateException e) {
-        } catch (NullPointerException e) {
-        }
+		// Methods where we expect IllegalStateException or NullPointerException
+		// to be thrown
+		try {
+			defl.getTotalOut();
+			fail("defl.getTotalOut() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
+		try {
+			defl.getTotalIn();
+			fail("defl.getTotalIn() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
+		try {
+			defl.getAdler();
+			fail("defl.getAdler() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
+		try {
+			byte[] dict = { 'a', 'b', 'c' };
+			defl.setDictionary(dict);
+			fail("defl.setDictionary() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
+		try {
+			defl.getTotalIn();
+			fail("defl.getTotalIn() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
+		try {
+			defl.getTotalIn();
+			fail("defl.getTotalIn() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
+		try {
+			defl.deflate(byteArray);
+			fail("defl.deflate() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (IllegalStateException e) {
+		} catch (NullPointerException e) {
+		}
 
-        // Methods where we expect NullPointerException to be thrown
-        try {
-            defl.reset();
-            fail("defl.reset() can still be used after " + desc
-                    + " is called in test_" + desc);
-        } catch (NullPointerException e) {
-        }
+		// Methods where we expect NullPointerException to be thrown
+		try {
+			defl.reset();
+			fail("defl.reset() can still be used after " + desc
+					+ " is called in test_" + desc);
+		} catch (NullPointerException e) {
+		}
 
-        // Methods that should be allowed to be called after end() is called
-        defl.needsInput();
-        defl.setStrategy(1);
-        defl.setLevel(1);
-        defl.end();
+		// Methods that should be allowed to be called after end() is called
+		defl.needsInput();
+		defl.setStrategy(1);
+		defl.setLevel(1);
+		defl.end();
 
-        // Methods where exceptions should be thrown
-        String vendor = System.getProperty("java.vendor");
-        if (vendor.indexOf("IBM") != -1) {
-            try {
-                defl.setInput(byteArray);
-                fail("defl.setInput() can still be used after " + desc
-                        + " is called in test_" + desc);
-            } catch (IllegalStateException e) {
-            }
-        }
+		// Methods where exceptions should be thrown
+		String vendor = System.getProperty("java.vendor");
+		if (vendor.indexOf("IBM") != -1) {
+			try {
+				defl.setInput(byteArray);
+				fail("defl.setInput() can still be used after " + desc
+						+ " is called in test_" + desc);
+			} catch (IllegalStateException e) {
+			}
+		}
+	}
+
+    /**
+     * @tests java.util.zip.Deflater()
+     */
+    public void test_needsDictionary() {
+        Deflater inf = new Deflater();
+        assertEquals(0, inf.getTotalIn());
+        assertEquals(0, inf.getTotalOut());
+        assertEquals(0, inf.getBytesRead());
+        assertEquals(0, inf.getBytesWritten());
     }
 
     /**
@@ -1165,12 +1041,6 @@
      * @throws UnsupportedEncodingException
      * @tests java.util.zip.Deflater#getBytesRead()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getBytesRead",
-        args = {}
-    )
     public void test_getBytesRead() throws DataFormatException,
             UnsupportedEncodingException {
         // Regression test for HARMONY-158
@@ -1197,12 +1067,6 @@
      * @throws UnsupportedEncodingException
      * @tests java.util.zip.Deflater#getBytesRead()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getBytesWritten",
-        args = {}
-    )
     public void test_getBytesWritten() throws DataFormatException,
             UnsupportedEncodingException {
         // Regression test for HARMONY-158
@@ -1223,21 +1087,16 @@
         assertEquals(compressedDataLength, def.getTotalOut());
         assertEquals(compressedDataLength, def.getBytesWritten());
     }
-
-    // BEGIN android-removed
-    // We use different default settings for deflating, so our output won't be
-    // the
-    // same.
-    // //Regression Test for HARMONY-2481
-    // public void test_deflate_beforeSetInput() throws Exception {
-    // Deflater deflater = new Deflater();
-    // deflater.finish();
-    // byte[] buffer = new byte[1024];
-    // assertEquals(8, deflater.deflate(buffer));
-    // byte[] expectedBytes = { 120, -100, 3, 0, 0, 0, 0, 1 };
-    // for (int i = 0; i < expectedBytes.length; i++) {
-    // assertEquals(expectedBytes[i], buffer[i]);
-    // }
-    // }
-    // END android-removed
+    
+    //Regression Test for HARMONY-2481
+    public void test_deflate_beforeSetInput() throws Exception {
+        Deflater deflater = new Deflater();
+        deflater.finish();
+        byte[] buffer = new byte[1024];
+        assertEquals(8, deflater.deflate(buffer));
+        byte[] expectedBytes = { 120, -100, 3, 0, 0, 0, 0, 1 };
+        for (int i = 0; i < expectedBytes.length; i++) {
+            assertEquals(expectedBytes[i], buffer[i]);
+        }
+    }
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPInputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPInputStreamTest.java
index 1e8ddb4..3431510 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPInputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPInputStreamTest.java
@@ -14,14 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -31,127 +25,85 @@
 import java.io.InputStream;
 import java.net.URL;
 import java.util.zip.Checksum;
-
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(GZIPInputStream.class)
 public class GZIPInputStreamTest extends junit.framework.TestCase {
-    File resources;
+	File resources;
 
-    class TestGZIPInputStream extends GZIPInputStream {
-        TestGZIPInputStream(InputStream in) throws IOException {
-            super(in);
-        }
+	class TestGZIPInputStream extends GZIPInputStream {
+		TestGZIPInputStream(InputStream in) throws IOException {
+			super(in);
+		}
 
-        TestGZIPInputStream(InputStream in, int size) throws IOException {
-            super(in, size);
-        }
+		TestGZIPInputStream(InputStream in, int size) throws IOException {
+			super(in, size);
+		}
 
-        Checksum getChecksum() {
-            return crc;
-        }
+		Checksum getChecksum() {
+			return crc;
+		}
 
-        boolean endofInput() {
-            return eos;
-        }
-    }
+		boolean endofInput() {
+			return eos;
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "GZIPInputStream",
-        args = {java.io.InputStream.class}
-    )
-    public void test_ConstructorLjava_io_InputStream() {
-        // test method java.util.zip.GZIPInputStream.constructor
-        try {
-            Support_Resources.copyFile(resources, "GZIPInputStream",
-                    "hyts_gInput.txt.gz");
-            final URL gInput = new File(resources.toString()
-                    + "/GZIPInputStream/hyts_gInput.txt.gz").toURL();
-            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
-                    .openConnection().getInputStream());
-            assertNotNull("the constructor for GZIPInputStream is null", inGZIP);
-            assertEquals("the CRC value of the inputStream is not zero", 0,
-                    inGZIP.getChecksum().getValue());
-            inGZIP.close();
-        } catch (IOException e) {
-            fail("an IO error occured while trying to open the input file");
-        }
-    }
+	/**
+	 * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream)
+	 */
+	public void test_ConstructorLjava_io_InputStream() {
+		// test method java.util.zip.GZIPInputStream.constructor
+		try {
+			Support_Resources.copyFile(resources, "GZIPInputStream",
+					"hyts_gInput.txt.gz");
+			final URL gInput = new File(resources.toString()
+					+ "/GZIPInputStream/hyts_gInput.txt.gz").toURL();
+			TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+					.openConnection().getInputStream());
+			assertNotNull("the constructor for GZIPInputStream is null",
+					inGZIP);
+			assertEquals("the CRC value of the inputStream is not zero", 0, inGZIP
+					.getChecksum().getValue());
+			inGZIP.close();
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to open the input file");
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream,
-     *        int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "GZIPInputStream",
-        args = {java.io.InputStream.class, int.class}
-    )
-    public void test_ConstructorLjava_io_InputStreamI() {
-        // test method java.util.zip.GZIPInputStream.constructorI
-        try {
-            Support_Resources.copyFile(resources, "GZIPInputStream",
-                    "hyts_gInput.txt.gz");
-            final URL gInput = new File(resources.toString()
-                    + "/GZIPInputStream/hyts_gInput.txt.gz").toURL();
-            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
-                    .openConnection().getInputStream(), 200);
-            assertNotNull("the constructor for GZIPInputStream is null", inGZIP);
-            assertEquals("the CRC value of the inputStream is not zero", 0,
-                    inGZIP.getChecksum().getValue());
-            inGZIP.close();
-        } catch (IOException e) {
-            fail("an IO error occured while trying to open the input file");
-        }
-        try {
-            Support_Resources.copyFile(resources, "GZIPInputStream",
-                    "hyts_gInput.txt.gz");
-            final URL gInput = new File(resources.toString()
-                    + "/GZIPInputStream/hyts_gInput.txt.gz").toURL();
-            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
-                    .openConnection().getInputStream(), 0);
-            fail("Expected IllegalArgumentException");
-        } catch (IOException e) {
-            fail("an IO error occured while trying to open the input file");
-        } catch (IllegalArgumentException ee) {
-            // expected
-        }
-        try {
-            Support_Resources.copyFile(resources, "GZIPInputStream",
-                    "hyts_gInput.txt.gz");
-            final URL gInput = new File(resources.toString()
-                    + "/GZIPInputStream/hyts_gInput.txt.gz").toURL();
-            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
-                    .openConnection().getInputStream(), -1);
-            fail("Expected IllegalArgumentException");
-        } catch (IOException e) {
-            fail("an IO error occured while trying to open the input file");
-        } catch (IllegalArgumentException ee) {
-            // expected
-        }
-    }
+	/**
+	 * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream,
+	 *        int)
+	 */
+	public void test_ConstructorLjava_io_InputStreamI() {
+		// test method java.util.zip.GZIPInputStream.constructorI
+		try {
+			Support_Resources.copyFile(resources, "GZIPInputStream",
+					"hyts_gInput.txt.gz");
+			final URL gInput = new File(resources.toString()
+					+ "/GZIPInputStream/hyts_gInput.txt.gz").toURL();
+			TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+					.openConnection().getInputStream(), 200);
+			assertNotNull("the constructor for GZIPInputStream is null",
+					inGZIP);
+			assertEquals("the CRC value of the inputStream is not zero", 0, inGZIP
+					.getChecksum().getValue());
+			inGZIP.close();
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to open the input file");
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPInputStream#read(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_read$BII() throws IOException {
-        // test method java.util.zip.GZIPInputStream.readBII
-        byte orgBuf[] = {'3', '5', '2', 'r', 'g', 'e', 'f', 'd', 'e', 'w'};
+	/**
+	 * @tests java.util.zip.GZIPInputStream#read(byte[], int, int)
+	 */
+	public void test_read$BII() throws IOException {
+		// test method java.util.zip.GZIPInputStream.readBII
+        byte orgBuf[] = { '3', '5', '2', 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
         byte outBuf[] = new byte[100];
         int result = 0;
         Support_Resources.copyFile(resources, "GZIPInputStream",
@@ -240,14 +192,13 @@
             exception = true;
         }
         assertTrue("Exception expected", exception);
-
+        
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         GZIPOutputStream zipout = new GZIPOutputStream(baos);
         zipout.write(test);
         zipout.close();
         outBuf = new byte[530];
-        GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(baos
-                .toByteArray()));
+        GZIPInputStream in= new GZIPInputStream(new ByteArrayInputStream(baos.toByteArray()));
         try {
             in.read(outBuf, 530, 1);
             fail("Test failed IOOBE was not thrown");
@@ -256,7 +207,7 @@
         while (true) {
             result = in.read(outBuf, 0, 5);
             if (result == -1) {
-                // "EOF was reached";
+                //"EOF was reached";
                 break;
             }
         }
@@ -264,64 +215,50 @@
         result = in.read(null, 100, 1);
         result = in.read(outBuf, -100, 1);
         result = in.read(outBuf, -1, 1);// 100, 1);
-    }
+	}
 
-    /**
-     * @tests java.util.zip.GZIPInputStream#close()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
-    public void test_close() {
-        // test method java.util.zip.GZIPInputStream.close
-        byte outBuf[] = new byte[100];
-        try {
-            int result = 0;
-            Support_Resources.copyFile(resources, "GZIPInputStream",
-                    "hyts_gInput.txt.gz");
-            String resPath = resources.toString();
-            if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') {
+	/**
+	 * @tests java.util.zip.GZIPInputStream#close()
+	 */
+	public void test_close() {
+		// test method java.util.zip.GZIPInputStream.close
+		byte outBuf[] = new byte[100];
+		try {
+			int result = 0;
+			Support_Resources.copyFile(resources, "GZIPInputStream",
+					"hyts_gInput.txt.gz");
+			String resPath = resources.toString();
+			if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') {
                 resPath = resPath.substring(1);
             }
-            final URL gInput = new URL("file:/" + resPath
-                    + "/GZIPInputStream/hyts_gInput.txt.gz");
-            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
-                    .openConnection().getInputStream());
-            while (!(inGZIP.endofInput())) {
-                result += inGZIP.read(outBuf, result, outBuf.length - result);
-            }
-            assertEquals(
-                    "the checkSum value of the compressed and decompressed data does not equal",
-                    2074883667L, inGZIP.getChecksum().getValue());
-            inGZIP.close();
-            int r = 0;
-            try {
-                inGZIP.read(outBuf, 0, 1);
-            } catch (IOException e) {
-                r = 1;
-            }
-            assertEquals(
-                    "GZIPInputStream can still be used after close is called",
-                    1, r);
-        } catch (IOException e) {
-            e.printStackTrace();
-            fail("unexpected: " + e);
-        }
-    }
+			final URL gInput = new URL("file:/" + resPath
+					+ "/GZIPInputStream/hyts_gInput.txt.gz");
+			TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
+					.openConnection().getInputStream());
+			while (!(inGZIP.endofInput())) {
+				result += inGZIP.read(outBuf, result, outBuf.length - result);
+			}
+			assertEquals("the checkSum value of the compressed and decompressed data does not equal",
+					2074883667L, inGZIP.getChecksum().getValue());
+			inGZIP.close();
+			int r = 0;
+			try {
+				inGZIP.read(outBuf, 0, 1);
+			} catch (IOException e) {
+				r = 1;
+			}
+			assertEquals("GZIPInputStream can still be used after close is called",
+					1, r);
+		} catch (IOException e) {
+			e.printStackTrace();
+			fail("unexpected: " + e);
+		}
+	}
 
     /**
      * Regression test for HARMONY-3703.
      * @tests java.util.zip.GZIPInputStream#read()
      */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "read",
-            args = {byte[].class}
-    )
     public void test_read() throws IOException {
         GZIPInputStream gis = null;
         int result = 0;
@@ -350,11 +287,11 @@
 
 	@Override
     protected void setUp() {
-        resources = Support_Resources.createTempFolder();
-    }
+		resources = Support_Resources.createTempFolder();
+	}
 
-    @Override
+	@Override
     protected void tearDown() {
-    }
+	}
 
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPOutputStreamTest.java
index b71ce63..fdcc3fa 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPOutputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/GZIPOutputStreamTest.java
@@ -14,14 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -29,213 +23,160 @@
 import java.util.zip.Checksum;
 import java.util.zip.GZIPOutputStream;
 
-@TestTargetClass(GZIPOutputStream.class)
 public class GZIPOutputStreamTest extends junit.framework.TestCase {
 
-    class TestGZIPOutputStream extends GZIPOutputStream {
-        TestGZIPOutputStream(OutputStream out) throws IOException {
-            super(out);
-        }
+	class TestGZIPOutputStream extends GZIPOutputStream {
+		TestGZIPOutputStream(OutputStream out) throws IOException {
+			super(out);
+		}
 
-        TestGZIPOutputStream(OutputStream out, int size) throws IOException {
-            super(out, size);
-        }
+		TestGZIPOutputStream(OutputStream out, int size) throws IOException {
+			super(out, size);
+		}
 
-        Checksum getChecksum() {
-            return crc;
-        }
-    }
+		Checksum getChecksum() {
+			return crc;
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "GZIPOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void test_ConstructorLjava_io_OutputStream() {
-        try {
-            FileOutputStream outFile = new FileOutputStream(
-                    File.createTempFile("GZIPOutCon", ".txt"));
-            TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
-            assertNotNull("the constructor for GZIPOutputStream is null",
-                    outGZIP);
-            assertEquals("the CRC value of the outputStream is not zero", 0,
-                    outGZIP.getChecksum().getValue());
-            outGZIP.close();
-        } catch (IOException e) {
-            fail("an IO error occured while trying to find the output file or creating GZIP constructor");
-        }
-    }
+	/**
+	 * @tests java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream)
+	 */
+	public void test_ConstructorLjava_io_OutputStream() {
+		try {
+			FileOutputStream outFile = new FileOutputStream("GZIPOutCon.txt");
+			TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+			assertNotNull("the constructor for GZIPOutputStream is null",
+					outGZIP);
+			assertEquals("the CRC value of the outputStream is not zero", 0, outGZIP
+					.getChecksum().getValue());
+			outGZIP.close();
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to find the output file or creating GZIP constructor");
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream,
-     *        int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "GZIPOutputStream",
-        args = {java.io.OutputStream.class, int.class}
-    )
-    public void test_ConstructorLjava_io_OutputStreamI() {
-        try {
-            FileOutputStream outFile = new FileOutputStream(
-                    File.createTempFile("GZIPOutCon", ".txt"));
-            TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile,
-                    100);
-            assertNotNull("the constructor for GZIPOutputStream is null",
-                    outGZIP);
-            assertEquals("the CRC value of the outputStream is not zero", 0,
-                    outGZIP.getChecksum().getValue());
-            outGZIP.close();
-        } catch (IOException e) {
-            fail("an IO error occured while trying to find the output file or creating GZIP constructor");
-        }
-    }
+	/**
+	 * @tests java.util.zip.GZIPOutputStream#GZIPOutputStream(java.io.OutputStream,
+	 *        int)
+	 */
+	public void test_ConstructorLjava_io_OutputStreamI() {
+		try {
+			FileOutputStream outFile = new FileOutputStream("GZIPOutCon.txt");
+			TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile,
+					100);
+			assertNotNull("the constructor for GZIPOutputStream is null",
+					outGZIP);
+			assertEquals("the CRC value of the outputStream is not zero", 0, outGZIP
+					.getChecksum().getValue());
+			outGZIP.close();
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to find the output file or creating GZIP constructor");
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPOutputStream#finish()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finish",
-        args = {}
-    )
-    public void test_finish() {
-        // test method java.util.zip.GZIPOutputStream.finish()
-        byte byteArray[] = {3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w'};
-        TestGZIPOutputStream outGZIP = null;
-        FileOutputStream outFile = null;
-        try {
-            outFile = new FileOutputStream(
-                    File.createTempFile("GZIPOutCon", ".txt"));
-            outGZIP = new TestGZIPOutputStream(outFile);
+	/**
+	 * @tests java.util.zip.GZIPOutputStream#finish()
+	 */
+	public void test_finish() {
+		// test method java.util.zip.GZIPOutputStream.finish()
+		byte byteArray[] = { 3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+		try {
+			FileOutputStream outFile = new FileOutputStream("GZIPOutFinish.txt");
+			TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
 
-            outGZIP.finish();
-            int r = 0;
-            try {
-                outGZIP.write(byteArray, 0, 1);
-            } catch (IOException e) {
-                r = 1;
-            }
+			outGZIP.finish();
+			int r = 0;
+			try {
+				outGZIP.write(byteArray, 0, 1);
+			} catch (IOException e) {
+				r = 1;
+			}
 
-            assertEquals(
-                    "GZIP instance can still be used after finish is called",
-                    1, r);
-            outGZIP.close();
-        } catch (IOException e) {
-            fail("an IO error occured while trying to find the output file or creating GZIP constructor");
-        }
-        try {
-            outFile = new FileOutputStream("GZIPOutFinish.txt");
-            outGZIP = new TestGZIPOutputStream(outFile);
-            outFile.close();
+			assertEquals("GZIP instance can still be used after finish is called",
+					1, r);
+			outGZIP.close();
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to find the output file or creating GZIP constructor");
+		}
+	}
 
-            outGZIP.finish();
-            fail("Expected IOException");
-        } catch (IOException e) {
-            // expected
-        }
-    }
+	/**
+	 * @tests java.util.zip.GZIPOutputStream#close()
+	 */
+	public void test_close() {
+		// test method java.util.zip.GZIPOutputStream.close()
+		byte byteArray[] = { 3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+		try {
+			FileOutputStream outFile = new FileOutputStream("GZIPOutClose2.txt");
+			TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+			outGZIP.close();
+			int r = 0;
+			try {
+				outGZIP.write(byteArray, 0, 1);
+			} catch (IOException e) {
+				r = 1;
+			}
+			assertEquals("GZIP instance can still be used after close is called",
+					1, r);
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to find the output file or creating GZIP constructor");
+		}
+	}
 
-    /**
-     * @tests java.util.zip.GZIPOutputStream#close()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException checking missed.",
-        method = "close",
-        args = {}
-    )
-    public void test_close() {
-        // test method java.util.zip.GZIPOutputStream.close()
-        byte byteArray[] = {3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w'};
-        try {
-            FileOutputStream outFile = new FileOutputStream(
-                    File.createTempFile("GZIPOutCon", ".txt"));
-            TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
-            outGZIP.close();
-            int r = 0;
-            try {
-                outGZIP.write(byteArray, 0, 1);
-            } catch (IOException e) {
-                r = 1;
-            }
-            assertEquals(
-                    "GZIP instance can still be used after close is called", 1,
-                    r);
-        } catch (IOException e) {
-            fail("an IO error occured while trying to find the output file or creating GZIP constructor");
-        }
-    }
+	/**
+	 * @tests java.util.zip.GZIPOutputStream#write(byte[], int, int)
+	 */
+	public void test_write$BII() {
+		// test method java.util.zip.GZIPOutputStream.writeBII
+		byte byteArray[] = { 3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
+		try {
+			FileOutputStream outFile = new FileOutputStream("GZIPOutWrite.txt");
+			TestGZIPOutputStream outGZIP = new TestGZIPOutputStream(outFile);
+			outGZIP.write(byteArray, 0, 10);
+			// ran JDK and found this CRC32 value is 3097700292
+			// System.out.print(outGZIP.getChecksum().getValue());
+			assertEquals("the checksum value was incorrect result of write from GZIP",
+					3097700292L, outGZIP.getChecksum().getValue());
 
-    /**
-     * @tests java.util.zip.GZIPOutputStream#write(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_write$BII() {
-        // test method java.util.zip.GZIPOutputStream.writeBII
-        byte byteArray[] = {3, 5, 2, 'r', 'g', 'e', 'f', 'd', 'e', 'w'};
-        TestGZIPOutputStream outGZIP = null;
-        try {
-            FileOutputStream outFile = new FileOutputStream(
-                    File.createTempFile("GZIPOutCon", ".txt"));
-            outGZIP = new TestGZIPOutputStream(outFile);
-            outGZIP.write(byteArray, 0, 10);
-            // ran JDK and found this CRC32 value is 3097700292
-            // System.out.print(outGZIP.getChecksum().getValue());
-            assertEquals(
-                    "the checksum value was incorrect result of write from GZIP",
-                    3097700292L, outGZIP.getChecksum().getValue());
+			// test for boundary check
+			int r = 0;
+			try {
+				outGZIP.write(byteArray, 0, 11);
+			} catch (IndexOutOfBoundsException e) {
+				r = 1;
+			}
+			assertEquals("out of bounds exception is not present", 1, r);
+			outGZIP.close();
+		} catch (IOException e) {
+			fail(
+					"an IO error occured while trying to find the output file or creating GZIP constructor");
+		}
+	}
 
-            // test for boundary check
-            int r = 0;
-            try {
-                outGZIP.write(byteArray, 0, 11);
-            } catch (IndexOutOfBoundsException ee) {
-                r = 1;
-            }
-            assertEquals("out of bounds exception is not present", 1, r);
-            outGZIP.close();
-        } catch (IOException e) {
-            fail("an IO error occured while trying to find the output file or creating GZIP constructor");
-        }
-        try {
-            outGZIP.write(byteArray, 0, 10);
-            fail("Expected IOException");
-        } catch (IOException e) {
-            // expected
-        }
-    }
-
-    @Override
+	@Override
     protected void setUp() {
-    }
+	}
 
-    @Override
+	@Override
     protected void tearDown() {
 
-        try {
-            File dFile = new File("GZIPOutCon.txt");
-            dFile.delete();
-            File dFile2 = new File("GZIPOutFinish.txt");
+		try {
+			File dFile = new File("GZIPOutCon.txt");
+			dFile.delete();
+			File dFile2 = new File("GZIPOutFinish.txt"); 
             dFile2.delete();
-            File dFile3 = new File("GZIPOutWrite.txt");
+            File dFile3 = new File("GZIPOutWrite.txt"); 
             dFile3.delete();
-            File dFile4 = new File("GZIPOutClose2.txt");
-            dFile4.delete();
-        } catch (SecurityException e) {
-            fail("Cannot delete file for security reasons");
-        }
-    }
+            File dFile4 = new File("GZIPOutClose2.txt"); 
+            dFile4.delete(); 
+		} catch (SecurityException e) {
+			fail("Cannot delete file for security reasons");		
+		}
+	}
 
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
index 707f13b..3ab7a64 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterInputStreamTest.java
@@ -14,139 +14,107 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
-import junit.framework.TestCase;
-
-import tests.support.resource.Support_Resources;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.FileOutputStream;
-import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
 import java.util.zip.DeflaterOutputStream;
 import java.util.zip.Inflater;
 import java.util.zip.InflaterInputStream;
 
-@TestTargetClass(InflaterInputStream.class)
+import junit.framework.TestCase;
+import tests.support.resource.Support_Resources;
+
 public class InflaterInputStreamTest extends TestCase {
 
-    // files hyts_constru(O),hyts_constru(OD),hyts_constru(ODI) needs to be
-    // included as resources
-    byte outPutBuf[] = new byte[500];
+	// files hyts_constru(O),hyts_constru(OD),hyts_constru(ODI) needs to be
+	// included as resources
+        // android-changed: we removed the parentheses for the benefit of our broken build system.
+	byte outPutBuf[] = new byte[500];
 
-    class MyInflaterInputStream extends InflaterInputStream {
-        MyInflaterInputStream(InputStream in) {
-            super(in);
-        }
+	class MyInflaterInputStream extends InflaterInputStream {
+		MyInflaterInputStream(InputStream in) {
+			super(in);
+		}
 
-        MyInflaterInputStream(InputStream in, Inflater infl) {
-            super(in, infl);
-        }
+		MyInflaterInputStream(InputStream in, Inflater infl) {
+			super(in, infl);
+		}
 
-        MyInflaterInputStream(InputStream in, Inflater infl, int size) {
-            super(in, infl, size);
-        }
+		MyInflaterInputStream(InputStream in, Inflater infl, int size) {
+			super(in, infl, size);
+		}
 
-        void myFill() throws IOException {
-            fill();
-        }
-    }
+		void myFill() throws IOException {
+			fill();
+		}
+	}
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InflaterInputStream",
-        args = {java.io.InputStream.class}
-    )
-    public void test_ConstructorLjava_io_InputStream() throws IOException {
-        byte byteArray[] = new byte[100];
-        InputStream infile = Support_Resources.getStream("hyts_constru_OD.txt");
-        InflaterInputStream inflatIP = new InflaterInputStream(infile);
+	/**
+	 * @tests java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream)
+	 */
+	public void test_ConstructorLjava_io_InputStream() throws IOException {
+	    //FIXME This test doesn't pass in Harmony classlib or Sun 5.0_7 RI
+        /*
+		int result = 0;
+		int buffer[] = new int[500];
+		InputStream infile = Support_Resources
+				.getStream("hyts_constru_O.txt"); // android-changed
 
-        inflatIP.read(byteArray, 0, 5);// only suppose to read in 5 bytes
-        inflatIP.close();
-    }
+		InflaterInputStream inflatIP = new InflaterInputStream(infile);
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
-     *        java.util.zip.Inflater)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InflaterInputStream",
-        args = {java.io.InputStream.class, java.util.zip.Inflater.class}
-    )
-    public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Inflater()
-            throws IOException {
-        byte byteArray[] = new byte[100];
-        InputStream infile = Support_Resources.getStream("hyts_constru_OD.txt");
-        Inflater inflate = new Inflater();
-        InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate);
+		int i = 0;
+		while ((result = inflatIP.read()) != -1) {
+			buffer[i] = result;
+			i++;
+		}
+		inflatIP.close();
+        */
+	}
 
-        inflatIP.read(byteArray, 0, 5);// only suppose to read in 5 bytes
-        inflatIP.close();
-    }
+	/**
+	 * @tests java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
+	 *        java.util.zip.Inflater)
+	 */
+	public void test_ConstructorLjava_io_InputStreamLjava_util_zip_Inflater() throws IOException {
+		byte byteArray[] = new byte[100];
+		InputStream infile = Support_Resources.getStream("hyts_constru_OD.txt"); // android-changed
+		Inflater inflate = new Inflater();
+		InflaterInputStream inflatIP = new InflaterInputStream(infile,
+				inflate);
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
-     *        java.util.zip.Inflater, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "IllegalArgumentException checking missed.",
-        method = "InflaterInputStream",
-        args = {java.io.InputStream.class, java.util.zip.Inflater.class, int.class}
-    )
-    public void test_ConstructorLjava_io_InputStreamLjava_util_zip_InflaterI()
-            throws IOException {
-        int result = 0;
-        int buffer[] = new int[500];
-        InputStream infile = Support_Resources
-                .getStream("hyts_constru_ODI.txt");
-        Inflater inflate = new Inflater();
-        InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate,
-                1);
+		inflatIP.read(byteArray, 0, 5);// only suppose to read in 5 bytes
+		inflatIP.close();
+	}
 
-        int i = 0;
-        while ((result = inflatIP.read()) != -1) {
-            buffer[i] = result;
-            i++;
-        }
-        inflatIP.close();
+	/**
+	 * @tests java.util.zip.InflaterInputStream#InflaterInputStream(java.io.InputStream,
+	 *        java.util.zip.Inflater, int)
+	 */
+	public void test_ConstructorLjava_io_InputStreamLjava_util_zip_InflaterI() throws IOException {
+		int result = 0;
+		int buffer[] = new int[500];
+		InputStream infile = Support_Resources.getStream("hyts_constru_ODI.txt"); // android-changed
+		Inflater inflate = new Inflater();
+		InflaterInputStream inflatIP = new InflaterInputStream(infile,
+				inflate, 1);
 
-        try {
-            inflatIP = new InflaterInputStream(infile, inflate, -1);
-            fail("IllegalArgumentException expected.");
-        } catch (IllegalArgumentException ee) {
-            // expected
-        }
-
-    }
+		int i = 0;
+		while ((result = inflatIP.read()) != -1) {
+			buffer[i] = result;
+			i++;
+		}
+		inflatIP.close();
+	}
 
     /**
      * @tests java.util.zip.InflaterInputStream#mark(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "mark",
-        args = {int.class}
-    )
     public void test_markI() {
         InputStream is = new ByteArrayInputStream(new byte[10]);
         InflaterInputStream iis = new InflaterInputStream(is);
@@ -159,12 +127,6 @@
     /**
      * @tests java.util.zip.InflaterInputStream#markSupported()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "markSupported",
-        args = {}
-    )
     public void test_markSupported() {
         InputStream is = new ByteArrayInputStream(new byte[10]);
         InflaterInputStream iis = new InflaterInputStream(is);
@@ -172,43 +134,32 @@
         assertTrue(is.markSupported());
     }
 
-    /**
+	/**
      * @tests java.util.zip.InflaterInputStream#read()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "read",
-        args = {}
-    )
-    public void test_read() throws IOException {
-        int result = 0;
-        int buffer[] = new int[500];
-        byte orgBuffer[] = {1, 3, 4, 7, 8};
-        InputStream infile = Support_Resources.getStream("hyts_constru_OD.txt");
-        Inflater inflate = new Inflater();
-        InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate);
+	public void test_read() throws IOException {
+		int result = 0;
+		int buffer[] = new int[500];
+		byte orgBuffer[] = { 1, 3, 4, 7, 8 };
+		InputStream infile = Support_Resources
+				.getStream("hyts_constru_OD.txt"); // android-changed
+		Inflater inflate = new Inflater();
+		InflaterInputStream inflatIP = new InflaterInputStream(infile,
+				inflate);
 
-        int i = 0;
-        while ((result = inflatIP.read()) != -1) {
-            buffer[i] = result;
-            i++;
-        }
-        inflatIP.close();
+		int i = 0;
+		while ((result = inflatIP.read()) != -1) {
+			buffer[i] = result;
+			i++;
+		}
+		inflatIP.close();
 
-        for (int j = 0; j < orgBuffer.length; j++) {
-            assertTrue(
-                    "original compressed data did not equal decompressed data",
-                    buffer[j] == orgBuffer[j]);
-        }
-        inflatIP.close();
-        try {
-            inflatIP.read();
-            fail("IOException expected");
-        } catch (IOException ee) {
-            // expected.
-        }
-    }
+		for (int j = 0; j < orgBuffer.length; j++) {
+			assertTrue(
+				"original compressed data did not equal decompressed data",
+				buffer[j] == orgBuffer[j]);
+		}
+	}
 
     public void testAvailableNonEmptySource() throws Exception {
         // this byte[] is a deflation of these bytes: { 1, 3, 4, 6 }
@@ -246,24 +197,10 @@
         assertEquals(0, in.available());
     }
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#read(byte[], int, int)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "IOException & ZipException checking missed. Additional tests for fill method is not needed.",
-            method = "read",
-            args = {byte[].class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "IOException & ZipException checking missed. Additional tests for fill method is not needed.",
-            method = "fill",
-            args = {}
-        )
-    })
-    public void test_read$BII() throws IOException {
+	/**
+	 * @tests java.util.zip.InflaterInputStream#read(byte[], int, int)
+	 */
+	public void test_read$BII() throws IOException{
         byte[] test = new byte[507];
         for (int i = 0; i < 256; i++) {
             test[i] = (byte) i;
@@ -282,7 +219,7 @@
         while (true) {
             result = iis.read(outBuf, 0, 5);
             if (result == -1) {
-                // "EOF was reached";
+                //"EOF was reached";
                 break;
             }
         }
@@ -292,26 +229,8 @@
         } catch (IndexOutOfBoundsException e) {
             // expected;
         }
-        iis.close();
-    }
+	}
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#read(byte[], int, int)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "IOException checking.",
-            method = "read",
-            args = {byte[].class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "IOException checking.",
-            method = "fill",
-            args = {}
-        )
-    })
     public void test_read$BII2() throws IOException {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
@@ -329,20 +248,6 @@
         }
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "IOException checking.",
-            method = "read",
-            args = {byte[].class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "IOException checking.",
-            method = "fill",
-            args = {}
-        )
-    })
     public void test_read$BII3() throws IOException {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
@@ -362,12 +267,6 @@
     /**
      * @tests java.util.zip.InflaterInputStream#reset()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reset",
-        args = {}
-    )
     public void test_reset() {
         InputStream is = new ByteArrayInputStream(new byte[10]);
         InflaterInputStream iis = new InflaterInputStream(is);
@@ -378,135 +277,110 @@
             // correct
         }
     }
+        
+	/**
+	 * @tests java.util.zip.InflaterInputStream#skip(long)
+	 */
+	public void test_skipJ() throws IOException {
+		InputStream is = Support_Resources.getStream("hyts_available.tst");
+		InflaterInputStream iis = new InflaterInputStream(is);
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#skip(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException checking missed.",
-        method = "skip",
-        args = {long.class}
-    )
-    public void test_skipJ() throws IOException {
-        InputStream is = Support_Resources.getStream("hyts_available.tst");
-        InflaterInputStream iis = new InflaterInputStream(is);
-
-        // Tests for skipping a negative number of bytes.
-        try {
-            iis.skip(-3);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
+		// Tests for skipping a negative number of bytes.
+		try {
+			iis.skip(-3);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
             // Expected
-        }
-        assertEquals("Incorrect Byte Returned.", 5, iis.read());
+		}
+		assertEquals("Incorrect Byte Returned.", 5, iis.read());
 
-        try {
-            iis.skip(Integer.MIN_VALUE);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
+		try {
+			iis.skip(Integer.MIN_VALUE);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
             // Expected
-        }
-        assertEquals("Incorrect Byte Returned.", 4, iis.read());
+		}
+		assertEquals("Incorrect Byte Returned.", 4, iis.read());
 
-        // Test to make sure the correct number of bytes were skipped
-        assertEquals("Incorrect Number Of Bytes Skipped.", 3, iis.skip(3));
+		// Test to make sure the correct number of bytes were skipped
+		assertEquals("Incorrect Number Of Bytes Skipped.", 3, iis.skip(3));
 
-        // Test to see if the number of bytes skipped returned is true.
-        assertEquals("Incorrect Byte Returned.", 7, iis.read());
+		// Test to see if the number of bytes skipped returned is true.
+		assertEquals("Incorrect Byte Returned.", 7, iis.read());
 
-        assertEquals("Incorrect Number Of Bytes Skipped.", 0, iis.skip(0));
-        assertEquals("Incorrect Byte Returned.", 0, iis.read());
+		assertEquals("Incorrect Number Of Bytes Skipped.", 0, iis.skip(0));
+		assertEquals("Incorrect Byte Returned.", 0, iis.read());
 
-        // Test for skipping more bytes than available in the stream
-        assertEquals("Incorrect Number Of Bytes Skipped.", 2, iis.skip(4));
-        assertEquals("Incorrect Byte Returned.", -1, iis.read());
-        iis.close();
-    }
+		// Test for skipping more bytes than available in the stream
+		assertEquals("Incorrect Number Of Bytes Skipped.", 2, iis.skip(4));
+		assertEquals("Incorrect Byte Returned.", -1, iis.read());
+		iis.close();
+	}
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#skip(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "IOException checking missed.",
-        method = "skip",
-        args = {long.class}
-    )
-    public void test_skipJ2() throws IOException {
-        int result = 0;
-        int buffer[] = new int[100];
-        byte orgBuffer[] = {1, 3, 4, 7, 8};
+	/**
+	 * @tests java.util.zip.InflaterInputStream#skip(long)
+	 */
+	public void test_skipJ2() throws IOException {
+		int result = 0;
+		int buffer[] = new int[100];
+		byte orgBuffer[] = { 1, 3, 4, 7, 8 };
 
         // testing for negative input to skip
-        InputStream infile = Support_Resources.getStream("hyts_constru_OD.txt");
-        Inflater inflate = new Inflater();
-        InflaterInputStream inflatIP = new InflaterInputStream(infile, inflate,
-                10);
-        long skip;
-        try {
-            skip = inflatIP.skip(Integer.MIN_VALUE);
-            fail("Expected IllegalArgumentException when skip() is called with negative parameter");
-        } catch (IllegalArgumentException e) {
+		InputStream infile = Support_Resources
+				.getStream("hyts_constru_OD.txt"); // android-changed
+		Inflater inflate = new Inflater();
+		InflaterInputStream inflatIP = new InflaterInputStream(infile,
+				inflate, 10);
+		long skip;
+		try {
+			skip = inflatIP.skip(Integer.MIN_VALUE);
+			fail("Expected IllegalArgumentException when skip() is called with negative parameter");
+		} catch (IllegalArgumentException e) {
             // Expected
-        }
-        inflatIP.close();
+		}
+		inflatIP.close();
 
-        // testing for number of bytes greater than input.
-        InputStream infile2 = Support_Resources
-                .getStream("hyts_constru_OD.txt");
-        InflaterInputStream inflatIP2 = new InflaterInputStream(infile2);
+		// testing for number of bytes greater than input.
+		InputStream infile2 = Support_Resources
+				.getStream("hyts_constru_OD.txt"); // android-changed
+		InflaterInputStream inflatIP2 = new InflaterInputStream(infile2);
 
-        // looked at how many bytes the skip skipped. It is
-        // 5 and its supposed to be the entire input stream.
+		// looked at how many bytes the skip skipped. It is
+		// 5 and its supposed to be the entire input stream.
 
-        skip = inflatIP2.skip(Integer.MAX_VALUE);
-        // System.out.println(skip);
-        assertEquals("method skip() returned wrong number of bytes skipped", 5,
-                skip);
+		skip = inflatIP2.skip(Integer.MAX_VALUE);
+		// System.out.println(skip);
+		assertEquals("method skip() returned wrong number of bytes skipped",
+				5, skip);
 
-        // test for skipping of 2 bytes
-        InputStream infile3 = Support_Resources
-                .getStream("hyts_constru_OD.txt");
-        InflaterInputStream inflatIP3 = new InflaterInputStream(infile3);
-        skip = inflatIP3.skip(2);
-        assertEquals(
-                "the number of bytes returned by skip did not correspond with its input parameters",
-                2, skip);
-        int i = 0;
-        result = 0;
-        while ((result = inflatIP3.read()) != -1) {
-            buffer[i] = result;
-            i++;
-        }
-        inflatIP2.close();
+		// test for skipping of 2 bytes
+		InputStream infile3 = Support_Resources
+				.getStream("hyts_constru_OD.txt"); // android-changed
+		InflaterInputStream inflatIP3 = new InflaterInputStream(infile3);
+		skip = inflatIP3.skip(2);
+		assertEquals("the number of bytes returned by skip did not correspond with its input parameters",
+				2, skip);
+		int i = 0;
+		result = 0;
+		while ((result = inflatIP3.read()) != -1) {
+			buffer[i] = result;
+			i++;
+		}
+		inflatIP2.close();
 
-        for (int j = 2; j < orgBuffer.length; j++) {
-            assertTrue(
-                    "original compressed data did not equal decompressed data",
-                    buffer[j - 2] == orgBuffer[j]);
-        }
+		for (int j = 2; j < orgBuffer.length; j++) {
+			assertTrue(
+				"original compressed data did not equal decompressed data",
+				buffer[j - 2] == orgBuffer[j]);
+		}
+	}
 
-        try {
-            inflatIP2.skip(4);
-            fail("IOException expected.");
-        } catch (IOException ee) {
-            // expected
-        }
-    }
-
-    /**
-     * @tests java.util.zip.InflaterInputStream#available()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "available",
-        args = {}
-    )
-    public void test_available() throws IOException {
-        InputStream is = Support_Resources.getStream("hyts_available.tst");
-        InflaterInputStream iis = new InflaterInputStream(is);
+	/**
+	 * @tests java.util.zip.InflaterInputStream#available()
+	 */
+	public void test_available() throws IOException {
+		InputStream is = Support_Resources.getStream("hyts_available.tst");
+		InflaterInputStream iis = new InflaterInputStream(is);
 
         int available;
         for (int i = 0; i < 11; i++) {
@@ -519,31 +393,24 @@
             }
         }
 
-        iis.close();
-        try {
-            iis.available();
-            fail("available after close should throw IOException.");
-        } catch (IOException e) {
+		iis.close();
+		try {
+			iis.available();
+			fail("available after close should throw IOException.");
+		} catch (IOException e) {
             // Expected
-        }
-    }
+		}
+	}
 
-    /**
-     * @tests java.util.zip.InflaterInputStream#close()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "IOException can not be tested.",
-        method = "close",
-        args = {}
-    )
-    public void test_close() throws IOException {
-        InflaterInputStream iin = new InflaterInputStream(
-                new ByteArrayInputStream(new byte[0]));
-        iin.close();
+	/**
+	 * @tests java.util.zip.InflaterInputStream#close()
+	 */
+	public void test_close() throws IOException {
+		InflaterInputStream iin = new InflaterInputStream(
+				new ByteArrayInputStream(new byte[0]));
+		iin.close();
 
         // test for exception
-        iin.close();
-
-    }
+		iin.close();
+	}
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterOutputStreamTest.java
new file mode 100644
index 0000000..9627613
--- /dev/null
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterOutputStreamTest.java
@@ -0,0 +1,392 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.archive.tests.java.util.zip;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterOutputStream;
+import java.util.zip.ZipException;
+
+import junit.framework.TestCase;
+
+public class InflaterOutputStreamTest extends TestCase {
+
+    private ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+    private byte[] compressedBytes = new byte[100];
+
+    private String testString = "Hello world";
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#InflaterOutputStream(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() throws IOException {
+        new InflaterOutputStream(os);
+
+        try {
+            new InflaterOutputStream(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#InflaterOutputStream(java.io.OutputStream,Inflater)
+     */
+    public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_Inflater() {
+        new InflaterOutputStream(os, new Inflater());
+
+        try {
+            new InflaterOutputStream(null, new Inflater());
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            new InflaterOutputStream(os, null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#InflaterOutputStream(java.io.OutputStream,Inflater,int)
+     */
+    public void test_ConstructorLjava_io_OutputStreamLjava_util_zip_InflaterI() {
+        new InflaterOutputStream(os, new Inflater(), 20);
+
+        try {
+            new InflaterOutputStream(null, null, 10);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            new InflaterOutputStream(null, new Inflater(), -1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            new InflaterOutputStream(os, null, -1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            new InflaterOutputStream(null, null, -1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            new InflaterOutputStream(os, new Inflater(), 0);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            new InflaterOutputStream(os, new Inflater(), -10000);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#close()
+     */
+    public void test_close() throws IOException {
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        ios.close();
+        // multiple close
+        ios.close();
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#flush()
+     */
+    public void test_flush() throws IOException {
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        ios.close();
+        try {
+            ios.flush();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        
+        ios = new InflaterOutputStream(os);
+        ios.flush();
+        ios.flush();
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#finish()
+     */
+    public void test_finish() throws IOException {
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        ios.close();
+        try {
+            ios.finish();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        
+        ios = new InflaterOutputStream(os);
+        ios.finish();
+        ios.finish();
+        ios.flush();
+        ios.flush();
+        ios.finish();
+        
+        byte[] bytes1 = {10,20,30,40,50};
+        Deflater defaultDeflater = new Deflater(Deflater.BEST_SPEED);
+        defaultDeflater.setInput(bytes1);
+        defaultDeflater.finish();
+        int length1 = defaultDeflater.deflate(compressedBytes);
+        
+        byte[] bytes2 = {100,90,80,70,60};
+        Deflater bestDeflater = new Deflater(Deflater.BEST_COMPRESSION );
+        bestDeflater.setInput(bytes2);
+        bestDeflater.finish();
+        int length2 = bestDeflater.deflate(compressedBytes,length1,compressedBytes.length-length1);
+        
+        ios = new InflaterOutputStream(os);
+        for (int i = 0; i < length1; i++) {
+            ios.write(compressedBytes[i]);
+        }
+        ios.finish();
+        ios.close();
+        
+        byte[] result = os.toByteArray();
+        for(int i =0;i<bytes1.length; i++){
+            assertEquals(bytes1[i],result[i]);
+        }
+        
+        ios = new InflaterOutputStream(os);
+        for (int i = length1; i < length2*2; i++) {
+            ios.write(compressedBytes[i]);
+        }
+        ios.finish();
+        ios.close();
+        
+        result = os.toByteArray();
+        for(int i =0;i<bytes2.length; i++){
+            assertEquals(bytes2[i],result[bytes1.length+i]);
+        }
+        
+    }
+    
+    /**
+     * @tests java.util.zip.InflaterOutputStream#write(int)
+     */
+    public void test_write_I() throws IOException {
+        int length = compressToBytes(testString);
+
+        // uncompress the data stored in the compressedBytes
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        for (int i = 0; i < length; i++) {
+            ios.write(compressedBytes[i]);
+        }
+
+        String result = new String(os.toByteArray());
+        assertEquals(testString, result);
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#write(int)
+     */
+    public void test_write_I_Illegal() throws IOException {
+
+        // write after close
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        ios.close();
+        try {
+            ios.write(-1);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#write(byte[],int,int)
+     */
+    public void test_write_$BII() throws IOException {
+        int length = compressToBytes(testString);
+
+        // uncompress the data stored in the compressedBytes
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        ios.write(compressedBytes, 0, length);
+
+        String result = new String(os.toByteArray());
+        assertEquals(testString, result);
+    }
+
+    /**
+     * @tests java.util.zip.InflaterOutputStream#write(byte[],int,int)
+     */
+    public void test_write_$BII_Illegal() throws IOException {
+        // write error compression (ZIP) format
+        InflaterOutputStream ios = new InflaterOutputStream(os);
+        byte[] bytes = { 0, 1, 2, 3 };
+        try {
+            ios.write(bytes, 0, 4);
+            fail("Should throw ZipException");
+        } catch (ZipException e) {
+            // expected
+        }
+        try {
+            ios.flush();
+            fail("Should throw ZipException");
+        } catch (ZipException e) {
+            // expected
+        }
+
+        // write after close
+        ios = new InflaterOutputStream(os);
+        ios.close();
+        try {
+            ios.write(bytes, 0, 4);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, -1, 4);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, -1, -4);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, 0, 400);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+        try {
+            ios.write(null, -1, 4);
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+
+        ios = new InflaterOutputStream(os);
+        try {
+            ios.write(null, 0, 4);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            ios.write(null, -1, 4);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            ios.write(null, 0, -4);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            ios.write(null, 0, 1000);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, -1, 4);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, 0, -4);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, 0, 100);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            ios.write(bytes, -100, 100);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        ios = new InflaterOutputStream(os);
+        ios.finish();
+        
+        try {
+            ios.write(bytes, -1,-100);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            ios.write(null, -1,-100);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        
+        ios = new InflaterOutputStream(os);
+        ios.flush();
+        try {
+            ios.write(bytes, 0, 4);
+            fail("Should throw ZipException");
+        } catch (ZipException e) {
+            // expected
+        }
+    }
+
+    // Compress the test string into compressedBytes
+    private int compressToBytes(String string) {
+        byte[] input = string.getBytes();
+        Deflater deflater = new Deflater();
+        deflater.setInput(input);
+        deflater.finish();
+        return deflater.deflate(compressedBytes);
+    }
+
+}
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterTest.java
index cd5d538..49be8d0 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/InflaterTest.java
@@ -14,17 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.BufferedInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.zip.Adler32;
 import java.io.UnsupportedEncodingException;
 import java.util.zip.DataFormatException;
@@ -34,345 +29,292 @@
 
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(Inflater.class)
 public class InflaterTest extends junit.framework.TestCase {
-    byte outPutBuff1[] = new byte[500];
+	byte outPutBuff1[] = new byte[500];
 
-    byte outPutDiction[] = new byte[500];
+	byte outPutDiction[] = new byte[500];
 
-    /**
-     * @tests java.util.zip.Inflater#end()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "end",
-        args = {}
-    )
-    public void test_end() {
-        // test method of java.util.zip.inflater.end()
-        byte byteArray[] = {5, 2, 3, 7, 8};
+	/**
+	 * @tests java.util.zip.Inflater#end()
+	 */
+	public void test_end() {
+		// test method of java.util.zip.inflater.end()
+		byte byteArray[] = { 5, 2, 3, 7, 8 };
 
-        int r = 0;
-        Inflater inflate = new Inflater();
-        inflate.setInput(byteArray);
-        inflate.end();
-        try {
-            inflate.reset();
-            inflate.setInput(byteArray);
-        } catch (NullPointerException e) {
-            r = 1;
-        }
-        assertEquals("inflate can still be used after end is called", 1, r);
+		int r = 0;
+		Inflater inflate = new Inflater();
+		inflate.setInput(byteArray);
+		inflate.end();
+		try {
+			inflate.reset();
+			inflate.setInput(byteArray);
+		} catch (NullPointerException e) {
+			r = 1;
+		}
+		assertEquals("inflate can still be used after end is called", 1, r);
 
-        Inflater i = new Inflater();
-        i.end();
-        // check for exception
-        i.end();
-    }
+		Inflater i = new Inflater();
+		i.end();
+		// check for exception
+		i.end();
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#finished()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finished",
-        args = {}
-    )
-    public void test_finished() {
-        // test method of java.util.zip.inflater.finished()
-        byte byteArray[] = {1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5'};
-        Inflater inflate = new Inflater(false);
-        byte outPutInf[] = new byte[500];
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuff1);
-                }
+	/**
+	 * @tests java.util.zip.Inflater#finished()
+	 */
+	public void test_finished() {
+		// test method of java.util.zip.inflater.finished()
+		byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+		Inflater inflate = new Inflater(false);
+		byte outPutInf[] = new byte[500];
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuff1);
+				}
 
-                inflate.inflate(outPutInf);
-            }
-            assertTrue(
-                    "the method finished() returned false when no more data needs to be decompressed",
-                    inflate.finished());
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < byteArray.length; i++) {
-            assertTrue(
-                    "Final decompressed data does not equal the original data",
-                    byteArray[i] == outPutInf[i]);
-        }
-        assertEquals(
-                "final decompressed data contained more bytes than original - finished()",
-                0, outPutInf[byteArray.length]);
-    }
+				inflate.inflate(outPutInf);
+			}
+			assertTrue(
+					"the method finished() returned false when no more data needs to be decompressed",
+					inflate.finished());
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					byteArray[i] == outPutInf[i]);
+		}
+		assertEquals("final decompressed data contained more bytes than original - finished()",
+				0, outPutInf[byteArray.length]);
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#getAdler()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAdler",
-        args = {}
-    )
-    public void test_getAdler() {
-        // test method of java.util.zip.inflater.getAdler()
-        byte dictionaryArray[] = {'e', 'r', 't', 'a', 'b', 2, 3};
+	/**
+	 * @tests java.util.zip.Inflater#getAdler()
+	 */
+	public void test_getAdler() {
+		// test method of java.util.zip.inflater.getAdler()
+		byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
 
-        Inflater inflateDiction = new Inflater();
-        inflateDiction.setInput(outPutDiction);
-        if (inflateDiction.needsDictionary() == true) {
-            // getting the checkSum value through the Adler32 class
-            Adler32 adl = new Adler32();
-            adl.update(dictionaryArray);
-            long checkSumR = adl.getValue();
-            assertTrue(
-                    "the checksum value returned by getAdler() is not the same as the checksum returned by creating the adler32 instance",
-                    checkSumR == inflateDiction.getAdler());
-        }
-    }
+		Inflater inflateDiction = new Inflater();
+		inflateDiction.setInput(outPutDiction);
+		if (inflateDiction.needsDictionary() == true) {
+			// getting the checkSum value through the Adler32 class
+			Adler32 adl = new Adler32();
+			adl.update(dictionaryArray);
+			long checkSumR = adl.getValue();
+			assertTrue(
+					"the checksum value returned by getAdler() is not the same as the checksum returned by creating the adler32 instance",
+					checkSumR == inflateDiction.getAdler());
+		}
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#getRemaining()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getRemaining",
-        args = {}
-    )
-    public void test_getRemaining() {
-        // test method of java.util.zip.inflater.getRemaining()
-        byte byteArray[] = {1, 3, 5, 6, 7};
-        Inflater inflate = new Inflater();
-        assertEquals(
-                "upon creating an instance of inflate, getRemaining returned a non zero value",
-                0, inflate.getRemaining());
-        inflate.setInput(byteArray);
-        assertTrue(
-                "getRemaining returned zero when there is input in the input buffer",
-                inflate.getRemaining() != 0);
-    }
+	/**
+	 * @tests java.util.zip.Inflater#getRemaining()
+	 */
+	public void test_getRemaining() {
+		// test method of java.util.zip.inflater.getRemaining()
+		byte byteArray[] = { 1, 3, 5, 6, 7 };
+		Inflater inflate = new Inflater();
+		assertEquals("upon creating an instance of inflate, getRemaining returned a non zero value",
+				0, inflate.getRemaining());
+		inflate.setInput(byteArray);
+		assertTrue(
+				"getRemaining returned zero when there is input in the input buffer",
+				inflate.getRemaining() != 0);
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#getTotalIn()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTotalIn",
-        args = {}
-    )
-    public void test_getTotalIn() {
-        // test method of java.util.zip.inflater.getTotalIn()
-        // creating the decompressed data
-        byte outPutBuf[] = new byte[500];
-        byte byteArray[] = {1, 3, 4, 7, 8};
-        byte outPutInf[] = new byte[500];
-        int x = 0;
-        Deflater deflate = new Deflater(1);
-        deflate.setInput(byteArray);
-        while (!(deflate.needsInput())) {
-            x += deflate.deflate(outPutBuf, x, outPutBuf.length - x);
-        }
-        deflate.finish();
-        while (!(deflate.finished())) {
-            x = x + deflate.deflate(outPutBuf, x, outPutBuf.length - x);
-        }
+	/**
+	 * @tests java.util.zip.Inflater#getTotalIn()
+	 */
+	public void test_getTotalIn() {
+		// test method of java.util.zip.inflater.getTotalIn()
+		// creating the decompressed data
+		byte outPutBuf[] = new byte[500];
+		byte byteArray[] = { 1, 3, 4, 7, 8 };
+		byte outPutInf[] = new byte[500];
+		int x = 0;
+		Deflater deflate = new Deflater(1);
+		deflate.setInput(byteArray);
+		while (!(deflate.needsInput())) {
+			x += deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+		}
+		deflate.finish();
+		while (!(deflate.finished())) {
+			x = x + deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+		}
 
-        Inflater inflate = new Inflater();
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuf);
-                }
+		Inflater inflate = new Inflater();
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuf);
+				}
 
-                inflate.inflate(outPutInf);
-            }
-        } catch (DataFormatException e) {
-            fail("Input to inflate is invalid or corrupted - getTotalIn");
-        }
-        // System.out.print(deflate.getTotalOut() + " " + inflate.getTotalIn());
-        assertTrue(
-                "the total byte in outPutBuf did not equal the byte returned in getTotalIn",
-                inflate.getTotalIn() == deflate.getTotalOut());
+				inflate.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			fail("Input to inflate is invalid or corrupted - getTotalIn");
+		}
+		// System.out.print(deflate.getTotalOut() + " " + inflate.getTotalIn());
+		assertTrue(
+				"the total byte in outPutBuf did not equal the byte returned in getTotalIn",
+				inflate.getTotalIn() == deflate.getTotalOut());
 
-        Inflater inflate2 = new Inflater();
-        int offSet = 0;// seems only can start as 0
-        int length = 4;
-        try {
-            // seems no while loops allowed
-            if (inflate2.needsInput()) {
-                inflate2.setInput(outPutBuff1, offSet, length);
-            }
+		Inflater inflate2 = new Inflater();
+		int offSet = 0;// seems only can start as 0
+		int length = 4;
+		try {
+			// seems no while loops allowed
+			if (inflate2.needsInput()) {
+				inflate2.setInput(outPutBuff1, offSet, length);
+			}
 
-            inflate2.inflate(outPutInf);
+			inflate2.inflate(outPutInf);
 
-        } catch (DataFormatException e) {
-            fail("Input to inflate is invalid or corrupted - getTotalIn");
-        }
-        // System.out.print(inflate2.getTotalIn() + " " + length);
-        assertTrue(
-                "total byte dictated by length did not equal byte returned in getTotalIn",
-                inflate2.getTotalIn() == length);
-    }
+		} catch (DataFormatException e) {
+			fail("Input to inflate is invalid or corrupted - getTotalIn");
+		}
+		// System.out.print(inflate2.getTotalIn() + " " + length);
+		assertTrue(
+				"total byte dictated by length did not equal byte returned in getTotalIn",
+				inflate2.getTotalIn() == length);
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#getTotalOut()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTotalOut",
-        args = {}
-    )
-    public void test_getTotalOut() {
-        // test method of java.util.zip.inflater.Inflater()
-        // creating the decompressed data
-        byte outPutBuf[] = new byte[500];
-        byte byteArray[] = {1, 3, 4, 7, 8};
-        int y = 0;
-        int x = 0;
-        Deflater deflate = new Deflater(1);
-        deflate.setInput(byteArray);
-        while (!(deflate.needsInput())) {
-            x += deflate.deflate(outPutBuf, x, outPutBuf.length - x);
-        }
-        deflate.finish();
-        while (!(deflate.finished())) {
-            x = x + deflate.deflate(outPutBuf, x, outPutBuf.length - x);
-        }
+	/**
+	 * @tests java.util.zip.Inflater#getTotalOut()
+	 */
+	public void test_getTotalOut() {
+		// test method of java.util.zip.inflater.Inflater()
+		// creating the decompressed data
+		byte outPutBuf[] = new byte[500];
+		byte byteArray[] = { 1, 3, 4, 7, 8 };
+		int y = 0;
+		int x = 0;
+		Deflater deflate = new Deflater(1);
+		deflate.setInput(byteArray);
+		while (!(deflate.needsInput())) {
+			x += deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+		}
+		deflate.finish();
+		while (!(deflate.finished())) {
+			x = x + deflate.deflate(outPutBuf, x, outPutBuf.length - x);
+		}
 
-        Inflater inflate = new Inflater();
-        byte outPutInf[] = new byte[500];
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuf);
-                }
+		Inflater inflate = new Inflater();
+		byte outPutInf[] = new byte[500];
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuf);
+				}
 
-                y += inflate.inflate(outPutInf);
-            }
-        } catch (DataFormatException e) {
-            fail("Input to inflate is invalid or corrupted - getTotalIn");
-        }
+				y += inflate.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			fail("Input to inflate is invalid or corrupted - getTotalIn");
+		}
 
-        assertTrue(
-                "the sum of the bytes returned from inflate does not equal the bytes of getTotalOut()",
-                y == inflate.getTotalOut());
-        assertTrue(
-                "the total number of bytes to be compressed does not equal the total bytes decompressed",
-                inflate.getTotalOut() == deflate.getTotalIn());
+		assertTrue(
+				"the sum of the bytes returned from inflate does not equal the bytes of getTotalOut()",
+				y == inflate.getTotalOut());
+		assertTrue(
+				"the total number of bytes to be compressed does not equal the total bytes decompressed",
+				inflate.getTotalOut() == deflate.getTotalIn());
 
-        // testing inflate(byte,int,int)
-        inflate.reset();
-        y = 0;
-        int offSet = 0;// seems only can start as 0
-        int length = 4;
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuf);
-                }
+		// testing inflate(byte,int,int)
+		inflate.reset();
+		y = 0;
+		int offSet = 0;// seems only can start as 0
+		int length = 4;
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuf);
+				}
 
-                y += inflate.inflate(outPutInf, offSet, length);
-            }
-        } catch (DataFormatException e) {
-            System.out
-                    .println("Input to inflate is invalid or corrupted - getTotalIn");
-        }
-        assertTrue(
-                "the sum of the bytes returned from inflate does not equal the bytes of getTotalOut()",
-                y == inflate.getTotalOut());
-        assertTrue(
-                "the total number of bytes to be compressed does not equal the total bytes decompressed",
-                inflate.getTotalOut() == deflate.getTotalIn());
-    }
+				y += inflate.inflate(outPutInf, offSet, length);
+			}
+		} catch (DataFormatException e) {
+			System.out
+					.println("Input to inflate is invalid or corrupted - getTotalIn");
+		}
+		assertTrue(
+				"the sum of the bytes returned from inflate does not equal the bytes of getTotalOut()",
+				y == inflate.getTotalOut());
+		assertTrue(
+				"the total number of bytes to be compressed does not equal the total bytes decompressed",
+				inflate.getTotalOut() == deflate.getTotalIn());
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#inflate(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "DataFormatException checking missed.",
-        method = "inflate",
-        args = {byte[].class}
-    )
-    public void test_inflate$B() {
-        // test method of java.util.zip.inflater.inflate(byte)
+	/**
+	 * @tests java.util.zip.Inflater#inflate(byte[])
+	 */
+	public void test_inflate$B() {
+		// test method of java.util.zip.inflater.inflate(byte)
 
-        byte byteArray[] = {1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5'};
-        byte outPutInf[] = new byte[500];
-        Inflater inflate = new Inflater();
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuff1);
-                }
-                inflate.inflate(outPutInf);
-            }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < byteArray.length; i++) {
-            assertTrue(
-                    "Final decompressed data does not equal the original data",
-                    byteArray[i] == outPutInf[i]);
-        }
-        assertEquals(
-                "final decompressed data contained more bytes than original - inflateB",
-                0, outPutInf[byteArray.length]);
-        // testing for an empty input array
-        byte outPutBuf[] = new byte[500];
-        byte emptyArray[] = new byte[11];
-        int x = 0;
-        Deflater defEmpty = new Deflater(3);
-        defEmpty.setInput(emptyArray);
-        while (!(defEmpty.needsInput())) {
-            x += defEmpty.deflate(outPutBuf, x, outPutBuf.length - x);
-        }
-        defEmpty.finish();
-        while (!(defEmpty.finished())) {
-            x += defEmpty.deflate(outPutBuf, x, outPutBuf.length - x);
-        }
-        assertTrue(
-                "the total number of byte from deflate did not equal getTotalOut - inflate(byte)",
-                x == defEmpty.getTotalOut());
-        assertTrue(
-                "the number of input byte from the array did not correspond with getTotalIn - inflate(byte)",
-                defEmpty.getTotalIn() == emptyArray.length);
-        Inflater infEmpty = new Inflater();
-        try {
-            while (!(infEmpty.finished())) {
-                if (infEmpty.needsInput()) {
-                    infEmpty.setInput(outPutBuf);
-                }
-                infEmpty.inflate(outPutInf);
-            }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < emptyArray.length; i++) {
-            assertTrue(
-                    "Final decompressed data does not equal the original data",
-                    emptyArray[i] == outPutInf[i]);
-            assertEquals("Final decompressed data does not equal zero", 0,
-                    outPutInf[i]);
-        }
-        assertEquals(
-                "Final decompressed data contains more element than original data",
-                0, outPutInf[emptyArray.length]);
-    }
+		byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+		byte outPutInf[] = new byte[500];
+		Inflater inflate = new Inflater();
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuff1);
+				}
+				inflate.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					byteArray[i] == outPutInf[i]);
+		}
+		assertEquals("final decompressed data contained more bytes than original - inflateB",
+				0, outPutInf[byteArray.length]);
+		// testing for an empty input array
+		byte outPutBuf[] = new byte[500];
+		byte emptyArray[] = new byte[11];
+		int x = 0;
+		Deflater defEmpty = new Deflater(3);
+		defEmpty.setInput(emptyArray);
+		while (!(defEmpty.needsInput())) {
+			x += defEmpty.deflate(outPutBuf, x, outPutBuf.length - x);
+		}
+		defEmpty.finish();
+		while (!(defEmpty.finished())) {
+			x += defEmpty.deflate(outPutBuf, x, outPutBuf.length - x);
+		}
+		assertTrue(
+				"the total number of byte from deflate did not equal getTotalOut - inflate(byte)",
+				x == defEmpty.getTotalOut());
+		assertTrue(
+				"the number of input byte from the array did not correspond with getTotalIn - inflate(byte)",
+				defEmpty.getTotalIn() == emptyArray.length);
+		Inflater infEmpty = new Inflater();
+		try {
+			while (!(infEmpty.finished())) {
+				if (infEmpty.needsInput()) {
+					infEmpty.setInput(outPutBuf);
+				}
+				infEmpty.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < emptyArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					emptyArray[i] == outPutInf[i]);
+			assertEquals("Final decompressed data does not equal zero",
+					0, outPutInf[i]);
+		}
+		assertEquals("Final decompressed data contains more element than original data",
+				0, outPutInf[emptyArray.length]);
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "inflate",
-        args = {byte[].class}
-    )
     public void test_inflate$B1() {
         byte codedData[] = {
                 120, -38, 75, -54, 73, -52, 80, 40, 46, 41, -54, -52, 75, 87,
@@ -408,82 +350,53 @@
         infl2.end();
     }
 
-    /**
-     * @tests java.util.zip.Inflater#Inflater()
-     */
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "Inflater",
-            args = {}
-    )
-    public void test_Constructor() {
-        // test method of java.util.zip.inflater.Inflater()
-        Inflater inflate = new Inflater();
-        assertNotNull("failed to create the instance of inflater",
-                        inflate);
-    }
+	/**
+	 * @tests java.util.zip.Inflater#inflate(byte[], int, int)
+	 */
+	public void test_inflate$BII() {
+		// test method of java.util.zip.inflater.inflate(byte,int,int)
 
-    /**
-     * @tests java.util.zip.Inflater#inflate(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "DataFormatException checking missed.",
-        method = "inflate",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_inflate$BII() {
-        // test method of java.util.zip.inflater.inflate(byte,int,int)
+		byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+		byte outPutInf[] = new byte[100];
+		int y = 0;
+		Inflater inflate = new Inflater();
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuff1);
+				}
+				y += inflate.inflate(outPutInf, y, outPutInf.length - y);
+			}
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					byteArray[i] == outPutInf[i]);
+		}
+		assertEquals("final decompressed data contained more bytes than original - inflateB",
+				0, outPutInf[byteArray.length]);
 
-        byte byteArray[] = {1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5'};
-        byte outPutInf[] = new byte[100];
-        int y = 0;
-        Inflater inflate = new Inflater();
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuff1);
-                }
-                y += inflate.inflate(outPutInf, y, outPutInf.length - y);
-            }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < byteArray.length; i++) {
-            assertTrue(
-                    "Final decompressed data does not equal the original data",
-                    byteArray[i] == outPutInf[i]);
-        }
-        assertEquals(
-                "final decompressed data contained more bytes than original - inflateB",
-                0, outPutInf[byteArray.length]);
+		// test boundary checks
+		inflate.reset();
+		int r = 0;
+		int offSet = 0;
+		int lengthError = 101;
+		try {
+			if (inflate.needsInput()) {
+				inflate.setInput(outPutBuff1);
+			}
+			inflate.inflate(outPutInf, offSet, lengthError);
 
-        // test boundary checks
-        inflate.reset();
-        int r = 0;
-        int offSet = 0;
-        int lengthError = 101;
-        try {
-            if (inflate.needsInput()) {
-                inflate.setInput(outPutBuff1);
-            }
-            inflate.inflate(outPutInf, offSet, lengthError);
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 1;
+		}
+		assertEquals("out of bounds error did not get caught", 1, r);
+	}
 
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            r = 1;
-        }
-        assertEquals("out of bounds error did not get caught", 1, r);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "inflate",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_inflate$BII1() {
         byte codedData[] = {
                 120, -38, 75, -54, 73, -52, 80, 40, 46, 41, -54, -52, 75, 87,
@@ -519,271 +432,292 @@
         infl2.end();
     }
 
-    /**
-     * @tests java.util.zip.Inflater#Inflater(boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Inflater",
-        args = {boolean.class}
-    )
-    public void test_ConstructorZ() {
-        // test method of java.util.zip.inflater.Inflater(boolean)
-        // note does not throw exception if deflater has a header, but inflater
-        // doesn't or vice versa.
-        byte byteArray[] = {1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5'};
-        Inflater inflate = new Inflater(true);
-        assertNotNull("failed to create the instance of inflater", inflate);
-        byte outPutInf[] = new byte[500];
-        int r = 0;
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuff1);
-                }
+	/**
+	 * @tests java.util.zip.Inflater#Inflater()
+	 */
+	public void test_Constructor() {
+		// test method of java.util.zip.inflater.Inflater()
+		Inflater inflate = new Inflater();
+		assertNotNull("failed to create the instance of inflater",
+				inflate);
+	}
 
-                inflate.inflate(outPutInf);
-            }
-            for (int i = 0; i < byteArray.length; i++) {
-                assertEquals(
-                        "the output array from inflate should contain 0 because the header of inflate and deflate did not match, but this failed",
-                        0, outPutBuff1[i]);
-            }
-        } catch (DataFormatException e) {
-            r = 1;
-        }
-        assertEquals(
-                "Error: exception should be thrown because of header inconsistency",
-                1, r);
+	/**
+	 * @tests java.util.zip.Inflater#Inflater(boolean)
+	 */
+	public void test_ConstructorZ() {
+		// test method of java.util.zip.inflater.Inflater(boolean)
+		// note does not throw exception if deflater has a header, but inflater
+		// doesn't or vice versa.
+		byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+		Inflater inflate = new Inflater(true);
+		assertNotNull("failed to create the instance of inflater", inflate);
+		byte outPutInf[] = new byte[500];
+		int r = 0;
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuff1);
+				}
 
-    }
+				inflate.inflate(outPutInf);
+			}
+			for (int i = 0; i < byteArray.length; i++) {
+				assertEquals("the output array from inflate should contain 0 because the header of inflate and deflate did not match, but this failed",
+						0, outPutBuff1[i]);
+			}
+		} catch (DataFormatException e) {
+			r = 1;
+		}
+		assertEquals("Error: exception should be thrown because of header inconsistency",
+				1, r);
 
-    /**
-     * @tests java.util.zip.Inflater#needsDictionary()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "needsDictionary",
-        args = {}
-    )
-    public void test_needsDictionary() {
-        // test method of java.util.zip.inflater.needsDictionary()
-        // note: this flag is set after inflate is called
-        byte outPutInf[] = new byte[500];
+	}
 
-        // testing with dictionary set.
-        Inflater inflateDiction = new Inflater();
-        if (inflateDiction.needsInput()) {
-            inflateDiction.setInput(outPutDiction);
-        }
-        try {
-            assertEquals("should return 0 because needs dictionary", 0,
-                    inflateDiction.inflate(outPutInf));
-        } catch (DataFormatException e) {
-            fail("Should not cause exception");
-        }
-        assertTrue(
-                "method needsDictionary returned false when dictionary was used in deflater",
-                inflateDiction.needsDictionary());
+	/**
+	 * @tests java.util.zip.Inflater#needsDictionary()
+	 */
+	public void test_needsDictionary() {
+		// test method of java.util.zip.inflater.needsDictionary()
+		// note: this flag is set after inflate is called
+		byte outPutInf[] = new byte[500];
 
-        // testing without dictionary
-        Inflater inflate = new Inflater();
-        try {
-            inflate.setInput(outPutBuff1);
-            inflate.inflate(outPutInf);
-            assertFalse(
-                    "method needsDictionary returned true when dictionary was not used in deflater",
-                    inflate.needsDictionary());
-        } catch (DataFormatException e) {
-            fail("Input to inflate is invalid or corrupted - needsDictionary");
-        }
+		// testing with dictionary set.
+		Inflater inflateDiction = new Inflater();
+		if (inflateDiction.needsInput()) {
+			inflateDiction.setInput(outPutDiction);
+		}
+		try {
+			assertEquals("should return 0 because needs dictionary",
+					0, inflateDiction.inflate(outPutInf));
+		} catch (DataFormatException e) {
+			fail("Should not cause exception");
+		}
+		assertTrue(
+				"method needsDictionary returned false when dictionary was used in deflater",
+				inflateDiction.needsDictionary());
+
+		// testing without dictionary
+		Inflater inflate = new Inflater();
+		try {
+			inflate.setInput(outPutBuff1);
+			inflate.inflate(outPutInf);
+			assertFalse(
+					"method needsDictionary returned true when dictionary was not used in deflater",
+					inflate.needsDictionary());
+		} catch (DataFormatException e) {
+			fail(
+					"Input to inflate is invalid or corrupted - needsDictionary");
+		}
 
         // Regression test for HARMONY-86
         Inflater inf = new Inflater();
         assertFalse(inf.needsDictionary());
-        assertEquals(0, inf.getTotalIn());
-        assertEquals(0, inf.getTotalOut());
-        assertEquals(0, inf.getBytesRead());
-        assertEquals(0, inf.getBytesWritten());
-    }
+        assertEquals(0,inf.getTotalIn());
+        assertEquals(0,inf.getTotalOut());
+        assertEquals(0,inf.getBytesRead());
+        assertEquals(0,inf.getBytesWritten());
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#needsInput()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "needsInput",
-        args = {}
-    )
-    public void test_needsInput() {
-        // test method of java.util.zip.inflater.needsInput()
-        Inflater inflate = new Inflater();
-        assertTrue(
-                "needsInput give the wrong boolean value as a result of no input buffer",
-                inflate.needsInput());
+	/**
+	 * @tests java.util.zip.Inflater#needsInput()
+	 */
+	public void test_needsInput() {
+		// test method of java.util.zip.inflater.needsInput()
+		Inflater inflate = new Inflater();
+		assertTrue(
+				"needsInput give the wrong boolean value as a result of no input buffer",
+				inflate.needsInput());
 
-        byte byteArray[] = {2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9};
-        inflate.setInput(byteArray);
-        assertFalse(
-                "methodNeedsInput returned true when the input buffer is full",
-                inflate.needsInput());
+		byte byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
+		inflate.setInput(byteArray);
+		assertFalse(
+				"methodNeedsInput returned true when the input buffer is full",
+				inflate.needsInput());
 
-        inflate.reset();
-        byte byteArrayEmpty[] = new byte[0];
-        inflate.setInput(byteArrayEmpty);
-        assertTrue(
-                "needsInput give wrong boolean value as a result of an empty input buffer",
-                inflate.needsInput());
-    }
+		inflate.reset();
+		byte byteArrayEmpty[] = new byte[0];
+		inflate.setInput(byteArrayEmpty);
+		assertTrue(
+				"needsInput give wrong boolean value as a result of an empty input buffer",
+				inflate.needsInput());
+	}
 
-    /**
-     * @tests java.util.zip.Inflater#reset()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reset",
-        args = {}
-    )
-    public void test_reset() {
-        // test method of java.util.zip.inflater.reset()
-        byte byteArray[] = {1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5'};
-        byte outPutInf[] = new byte[100];
-        int y = 0;
-        Inflater inflate = new Inflater();
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuff1);
-                }
-                y += inflate.inflate(outPutInf, y, outPutInf.length - y);
-            }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < byteArray.length; i++) {
-            assertTrue(
-                    "Final decompressed data does not equal the original data",
-                    byteArray[i] == outPutInf[i]);
-        }
-        assertEquals(
-                "final decompressed data contained more bytes than original - reset",
-                0, outPutInf[byteArray.length]);
+	/**
+	 * @tests java.util.zip.Inflater#reset()
+	 */
+	public void test_reset() {
+		// test method of java.util.zip.inflater.reset()
+		byte byteArray[] = { 1, 3, 4, 7, 8, 'e', 'r', 't', 'y', '5' };
+		byte outPutInf[] = new byte[100];
+		int y = 0;
+		Inflater inflate = new Inflater();
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuff1);
+				}
+				y += inflate.inflate(outPutInf, y, outPutInf.length - y);
+			}
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					byteArray[i] == outPutInf[i]);
+		}
+		assertEquals("final decompressed data contained more bytes than original - reset",
+				0, outPutInf[byteArray.length]);
 
-        // testing that resetting the inflater will also return the correct
-        // decompressed data
+		// testing that resetting the inflater will also return the correct
+		// decompressed data
 
-        inflate.reset();
-        try {
-            while (!(inflate.finished())) {
-                if (inflate.needsInput()) {
-                    inflate.setInput(outPutBuff1);
-                }
-                inflate.inflate(outPutInf);
-            }
-        } catch (DataFormatException e) {
-            fail("Invalid input to be decompressed");
-        }
-        for (int i = 0; i < byteArray.length; i++) {
-            assertTrue(
-                    "Final decompressed data does not equal the original data",
-                    byteArray[i] == outPutInf[i]);
-        }
-        assertEquals(
-                "final decompressed data contained more bytes than original - reset",
-                0, outPutInf[byteArray.length]);
+		inflate.reset();
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutBuff1);
+				}
+				inflate.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					byteArray[i] == outPutInf[i]);
+		}
+		assertEquals("final decompressed data contained more bytes than original - reset",
+				0, outPutInf[byteArray.length]);
 
-    }
+	}
 
+	/**
+	 * @tests java.util.zip.Inflater#setDictionary(byte[])
+	 */
+	public void test_setDictionary$B() {
+        //FIXME This test doesn't pass in Harmony classlib or Sun 5.0_7 RI
+        /*
+		// test method of java.util.zip.inflater.setDictionary(byte)
+		byte dictionaryArray[] = { 'e', 'r', 't', 'a', 'b', 2, 3 };
+		byte byteArray[] = { 4, 5, 3, 2, 'a', 'b', 6, 7, 8, 9, 0, 's', '3',
+				'w', 'r' };
 
-    /**
-     * @tests java.util.zip.Inflater#setInput(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setInput",
-        args = {byte[].class}
-    )
-    public void test_setInput$B() {
-        // test method of java.util.zip.inflater.setInput(byte)
-        byte byteArray[] = {2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9};
-        Inflater inflate = new Inflater();
-        inflate.setInput(byteArray);
-        assertTrue("setInputB did not deliver any byte to the input buffer",
-                inflate.getRemaining() != 0);
-    }
+		byte outPutInf[] = new byte[100];
 
-    /**
-     * @tests java.util.zip.Inflater#setInput(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setInput",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_setInput$BII() {
-        // test method of java.util.zip.inflater.setInput(byte,int,int)
-        byte byteArray[] = {2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9};
-        int offSet = 6;
-        int length = 6;
-        Inflater inflate = new Inflater();
-        inflate.setInput(byteArray, offSet, length);
-        assertTrue(
-                "setInputBII did not deliver the right number of bytes to the input buffer",
-                inflate.getRemaining() == length);
-        // boundary check
-        inflate.reset();
-        int r = 0;
-        try {
-            inflate.setInput(byteArray, 100, 100);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            r = 1;
-        }
-        assertEquals("boundary check is not present for setInput", 1, r);
-    }
+		// trying to inflate without setting a dictionary
 
-    @Override
+		Inflater inflateWO = new Inflater();
+		byte outPutInf2[] = new byte[100];
+		int r = 0;
+		try {
+			while (!(inflateWO.finished())) {
+				if (inflateWO.needsInput()) {
+					inflateWO.setInput(outPutDiction);
+				}
+				inflateWO.inflate(outPutInf2);
+			}
+		} catch (DataFormatException e) {
+			r = 1;
+		}
+		assertEquals("invalid input to be decompressed due to dictionary not set",
+				1, r);
+		// now setting the dictionary in inflater
+		Inflater inflate = new Inflater();
+		try {
+			while (!(inflate.finished())) {
+				if (inflate.needsInput()) {
+					inflate.setInput(outPutDiction);
+				}
+				if (inflate.needsDictionary()) {
+					inflate.setDictionary(dictionaryArray);
+				}
+				inflate.inflate(outPutInf);
+			}
+		} catch (DataFormatException e) {
+			fail("Invalid input to be decompressed");
+		}
+		for (int i = 0; i < byteArray.length; i++) {
+			assertTrue(
+					"Final decompressed data does not equal the original data",
+					byteArray[i] == outPutInf[i]);
+		}
+		assertEquals("final decompressed data contained more bytes than original - deflateB",
+				0, outPutInf[byteArray.length]);
+                */
+	}
+
+	/**
+	 * @tests java.util.zip.Inflater#setInput(byte[])
+	 */
+	public void test_setInput$B() {
+		// test method of java.util.zip.inflater.setInput(byte)
+		byte byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
+		Inflater inflate = new Inflater();
+		inflate.setInput(byteArray);
+		assertTrue("setInputB did not deliver any byte to the input buffer",
+				inflate.getRemaining() != 0);
+	}
+
+	/**
+	 * @tests java.util.zip.Inflater#setInput(byte[], int, int)
+	 */
+	public void test_setInput$BII() {
+		// test method of java.util.zip.inflater.setInput(byte,int,int)
+		byte byteArray[] = { 2, 3, 4, 't', 'y', 'u', 'e', 'w', 7, 6, 5, 9 };
+		int offSet = 6;
+		int length = 6;
+		Inflater inflate = new Inflater();
+		inflate.setInput(byteArray, offSet, length);
+		assertTrue(
+				"setInputBII did not deliver the right number of bytes to the input buffer",
+				inflate.getRemaining() == length);
+		// boundary check
+		inflate.reset();
+		int r = 0;
+		try {
+			inflate.setInput(byteArray, 100, 100);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 1;
+		}
+		assertEquals("boundary check is not present for setInput", 1, r);
+	}
+
+	@Override
     protected void setUp() {
-        try {
-            java.io.InputStream infile = Support_Resources
-                    .getStream("hyts_compressD.txt");
-            BufferedInputStream inflatIP = new BufferedInputStream(infile);
-            inflatIP.read(outPutBuff1, 0, outPutBuff1.length);
-            inflatIP.close();
+		try {
+			java.io.InputStream infile = Support_Resources
+					.getStream("hyts_compressD.txt");
+			BufferedInputStream inflatIP = new BufferedInputStream(infile);
+			inflatIP.read(outPutBuff1, 0, outPutBuff1.length);
+			inflatIP.close();
 
-            java.io.InputStream infile2 = Support_Resources
-                    .getStream("hyts_compDiction.txt");
-            BufferedInputStream inflatIP2 = new BufferedInputStream(infile2);
-            inflatIP2.read(outPutDiction, 0, outPutDiction.length);
-            inflatIP2.close();
+			java.io.InputStream infile2 = Support_Resources
+					.getStream("hyts_compDiction.txt");
+			BufferedInputStream inflatIP2 = new BufferedInputStream(infile2);
+			inflatIP2.read(outPutDiction, 0, outPutDiction.length);
+			inflatIP2.close();
 
-        } catch (FileNotFoundException e) {
-            fail("input file to test InflaterInputStream constructor is not found");
-        } catch (ZipException e) {
-            fail("read() threw an zip exception while testing constructor");
-        } catch (IOException e) {
-            fail("read() threw an exception while testing constructor");
-        }
-    }
+		} catch (FileNotFoundException e) {
+			fail(
+					"input file to test InflaterInputStream constructor is not found");
+		} catch (ZipException e) {
+			fail(
+					"read() threw an zip exception while testing constructor");
+		} catch (IOException e) {
+			fail("read() threw an exception while testing constructor");
+		}
+	}
 
-    @Override
+	@Override
     protected void tearDown() {
-    }
-
+	}
+    
     /**
      * @tests java.util.zip.Deflater#getBytesRead()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getBytesRead",
-        args = {}
-    )
     public void test_getBytesRead() throws DataFormatException,
             UnsupportedEncodingException {
         // Regression test for HARMONY-158
@@ -802,23 +736,16 @@
         def.finish();
         def.deflate(output);
         inf.setInput(output);
-        int compressedDataLength = inf.inflate(input);
+        int compressedDataLength =inf.inflate(input);
         assertEquals(16, inf.getTotalIn());
         assertEquals(compressedDataLength, inf.getTotalOut());
         assertEquals(16, inf.getBytesRead());
     }
-
+    
     /**
      * @tests java.util.zip.Deflater#getBytesRead()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getBytesWritten",
-        args = {}
-    )
-    public void test_getBytesWritten() throws DataFormatException,
-            UnsupportedEncodingException {
+    public void test_getBytesWritten() throws DataFormatException, UnsupportedEncodingException {
         // Regression test for HARMONY-158
         Deflater def = new Deflater();
         Inflater inf = new Inflater();
@@ -835,7 +762,7 @@
         def.finish();
         def.deflate(output);
         inf.setInput(output);
-        int compressedDataLength = inf.inflate(input);
+        int compressedDataLength =inf.inflate(input);
         assertEquals(16, inf.getTotalIn());
         assertEquals(compressedDataLength, inf.getTotalOut());
         assertEquals(14, inf.getBytesWritten());
@@ -844,14 +771,8 @@
     /**
      * @tests java.util.zip.Deflater#inflate(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test",
-        method = "inflate",
-        args = {byte[].class, int.class, int.class}
-    )
     public void testInflate() throws Exception {
-        // Regression for HARMONY-81
+        // Regression for HARMONY-81 
         Inflater inf = new Inflater();
         int res = inf.inflate(new byte[0], 0, 0);
 
@@ -862,30 +783,32 @@
         byte[] b = new byte[1024];
         assertEquals(0, inflater.inflate(b));
         inflater.end();
+
+        // Regression for HARMONY-2510
+        inflater = new Inflater();
+        inflater.setInput(new byte[] { -1 });
+        try {
+            inflater.inflate(b);
+
+            // The RI detects malformed data on the malformed input { -1 }. Both
+            // this implementation and the native zlib API return "need input"
+            // on that data. This is an error if the stream is exhausted, but
+            // not one that results in an exception in the Inflater API.
+            assertTrue(inflater.needsInput());
+        } catch (DataFormatException e) {
+            // expected
+        }
+
+        inflater = new Inflater();
+        inflater.setInput(new byte[] { -1, -1, -1 });
+        try {
+            inflater.inflate(b);
+        } catch (DataFormatException e) {
+            // expected
+        }
     }
 
-    /**
-     * @tests java.util.zip.Deflater#inflate(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Can not be checked. Should be tested in DX test package.",
-        method = "finalize",
-        args = {}
-    )
-    public void testFinalize() throws Exception {
-    }
-
-    /**
-     * @tests java.util.zip.Inflater#setDictionary(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Checks setDictionary. Can be splitted for 2 separate tests for Deflater & Inflater. Can be used as a base for setDictionary with additional params.",
-        method = "setDictionary",
-        args = {byte[].class}
-    )
-    public void testsetDictionary$B() throws Exception {
+    public void testSetDictionary$B() throws Exception {
         int i = 0;
         String inputString = "blah string contains blahblahblahblah and blah";
         String dictionary1 = "blah";
@@ -1003,16 +926,7 @@
         infl1.end();
     }
 
-    /**
-     * @tests java.util.zip.Inflater#setDictionary(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Checks setDictionary. Can be splitted for 2 separate tests for Deflater & Inflater. Can be used as a base for setDictionary with additional params.",
-        method = "setDictionary",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void testsetDictionary$BII() throws Exception {
+    public void testSetDictionary$BII() throws Exception {
         int i = 0;
         String inputString = "blah string contains blahblahblahblah and blah";
         String dictionary1 = "blah";
@@ -1113,4 +1027,5 @@
         assertEquals(inputString, new String(result, 0, decLen));
 
     }
+
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipEntryTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipEntryTest.java
index ee7aceb..be5d0c6 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipEntryTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipEntryTest.java
@@ -14,27 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
+import java.util.TimeZone;
+import java.util.zip.ZipEntry;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 
 import tests.support.resource.Support_Resources;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.TimeZone;
-import java.util.zip.ZipEntry;
-
-@TestTargetClass(ZipEntry.class)
 public class ZipEntryTest extends junit.framework.TestCase {
 
-    // BEGIN android-added
     public byte[] getAllBytesFromStream(InputStream is) throws IOException {
         ByteArrayOutputStream bs = new ByteArrayOutputStream();
         byte[] buf = new byte[512];
@@ -47,601 +38,463 @@
         return bs.toByteArray();
     }
 
-    // END android-added
+	// zip file hyts_ZipFile.zip must be included as a resource
+	java.util.zip.ZipEntry zentry;
 
-    // zip file hyts_ZipFile.zip must be included as a resource
-    java.util.zip.ZipEntry zentry;
+	java.util.zip.ZipFile zfile;
 
-    java.util.zip.ZipFile zfile;
+	private static final String platformId = System.getProperty(
+			"com.ibm.oti.configuration", "JDK")
+			+ System.getProperty("java.vm.version");
 
-    private static final String platformId = System.getProperty(
-            "com.ibm.oti.configuration", "JDK")
-            + System.getProperty("java.vm.version");
+	static final String tempFileName = platformId + "zfzezi.zip";
 
-    static final String tempFileName = platformId + "zipentrytest.zip";
+	long orgSize;
 
-    long orgSize;
+	long orgCompressedSize;
 
-    long orgCompressedSize;
+	long orgCrc;
 
-    long orgCrc;
+	long orgTime;
 
-    long orgTime;
+	String orgComment;
 
-    String orgComment;
-
-    /**
-     * @tests java.util.zip.ZipEntry#ZipEntry(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ZipEntry",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
-        // Test for method java.util.zip.ZipEntry(java.lang.String)
-        zentry = zfile.getEntry("File3.txt");
-        assertNotNull("Failed to create ZipEntry", zentry);
-        try {
-            zentry = zfile.getEntry(null);
-            fail("NullPointerException not thrown");
-        } catch (NullPointerException e) {
-        }
-        StringBuffer s = new StringBuffer();
-        for (int i = 0; i < 65535; i++) {
+	/**
+	 * @tests java.util.zip.ZipEntry#ZipEntry(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
+		// Test for method java.util.zip.ZipEntry(java.lang.String)
+		zentry = zfile.getEntry("File3.txt");
+		assertNotNull("Failed to create ZipEntry", zentry);
+		try {
+			zentry = zfile.getEntry(null);
+			fail("NullPointerException not thrown");
+		} catch (NullPointerException e) {
+		}
+		StringBuffer s = new StringBuffer();
+		for (int i = 0; i < 65535; i++) {
             s.append('a');
         }
-        try {
-            zentry = new ZipEntry(s.toString());
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException During Test.");
-        }
-        try {
-            s.append('a');
-            zentry = new ZipEntry(s.toString());
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            String n = null;
-            zentry = new ZipEntry(n);
-            fail("NullPointerException not thrown");
-        } catch (NullPointerException e) {
-        }
-    }
+		try {
+			zentry = new ZipEntry(s.toString());
+		} catch (IllegalArgumentException e) {
+			fail("Unexpected IllegalArgumentException During Test.");
+		}
+		try {
+			s.append('a');
+			zentry = new ZipEntry(s.toString());
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			String n = null;
+			zentry = new ZipEntry(n);
+			fail("NullPointerException not thrown");
+		} catch (NullPointerException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getComment()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getComment",
-        args = {}
-    )
-    public void test_getComment() {
-        // Test for method java.lang.String java.util.zip.ZipEntry.getComment()
-        ZipEntry zipEntry = new ZipEntry("zippy.zip");
-        assertNull("Incorrect Comment Returned.", zipEntry.getComment());
-        zipEntry.setComment("This Is A Comment");
-        assertEquals("Incorrect Comment Returned.", "This Is A Comment",
-                zipEntry.getComment());
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getComment()
+	 */
+	public void test_getComment() {
+		// Test for method java.lang.String java.util.zip.ZipEntry.getComment()
+		ZipEntry zipEntry = new ZipEntry("zippy.zip");
+		assertNull("Incorrect Comment Returned.", zipEntry.getComment());
+		zipEntry.setComment("This Is A Comment");
+		assertEquals("Incorrect Comment Returned.", 
+				"This Is A Comment", zipEntry.getComment());
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getCompressedSize()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCompressedSize",
-        args = {}
-    )
-    public void test_getCompressedSize() {
-        // Test for method long java.util.zip.ZipEntry.getCompressedSize()
-        assertTrue("Incorrect compressed size returned", zentry
-                .getCompressedSize() == orgCompressedSize);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getCompressedSize()
+	 */
+	public void test_getCompressedSize() {
+		// Test for method long java.util.zip.ZipEntry.getCompressedSize()
+		assertTrue("Incorrect compressed size returned", zentry
+				.getCompressedSize() == orgCompressedSize);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getCrc()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCrc",
-        args = {}
-    )
-    public void test_getCrc() {
-        // Test for method long java.util.zip.ZipEntry.getCrc()
-        assertTrue("Failed to get Crc", zentry.getCrc() == orgCrc);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getCrc()
+	 */
+	public void test_getCrc() {
+		// Test for method long java.util.zip.ZipEntry.getCrc()
+		assertTrue("Failed to get Crc", zentry.getCrc() == orgCrc);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getExtra()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getExtra",
-        args = {}
-    )
-    public void test_getExtra() {
-        // Test for method byte [] java.util.zip.ZipEntry.getExtra()
-        assertNull("Incorrect extra information returned", zentry.getExtra());
-        byte[] ba = {'T', 'E', 'S', 'T'};
-        zentry = new ZipEntry("test.tst");
-        zentry.setExtra(ba);
-        assertTrue("Incorrect Extra Information Returned.",
-                zentry.getExtra() == ba);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getExtra()
+	 */
+	public void test_getExtra() {
+		// Test for method byte [] java.util.zip.ZipEntry.getExtra()
+		assertNull("Incorrect extra information returned",
+				zentry.getExtra());
+		byte[] ba = { 'T', 'E', 'S', 'T' };
+		zentry = new ZipEntry("test.tst");
+		zentry.setExtra(ba);
+		assertTrue("Incorrect Extra Information Returned.",
+				zentry.getExtra() == ba);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getMethod()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMethod",
-        args = {}
-    )
-    public void test_getMethod() {
-        // Test for method int java.util.zip.ZipEntry.getMethod()
-        zentry = zfile.getEntry("File1.txt");
-        assertTrue("Incorrect compression method returned",
-                zentry.getMethod() == java.util.zip.ZipEntry.STORED);
-        zentry = zfile.getEntry("File3.txt");
-        assertTrue("Incorrect compression method returned",
-                zentry.getMethod() == java.util.zip.ZipEntry.DEFLATED);
-        zentry = new ZipEntry("test.tst");
-        assertEquals("Incorrect Method Returned.", -1, zentry.getMethod());
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getMethod()
+	 */
+	public void test_getMethod() {
+		// Test for method int java.util.zip.ZipEntry.getMethod()
+		zentry = zfile.getEntry("File1.txt");
+		assertTrue("Incorrect compression method returned",
+				zentry.getMethod() == java.util.zip.ZipEntry.STORED);
+		zentry = zfile.getEntry("File3.txt");
+		assertTrue("Incorrect compression method returned",
+				zentry.getMethod() == java.util.zip.ZipEntry.DEFLATED);
+		zentry = new ZipEntry("test.tst");
+		assertEquals("Incorrect Method Returned.", -1, zentry.getMethod());
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getName()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getName",
-        args = {}
-    )
-    public void test_getName() {
-        // Test for method java.lang.String java.util.zip.ZipEntry.getName()
-        assertEquals(
-                "Incorrect name returned - Note return result somewhat ambiguous in spec",
-                "File1.txt", zentry.getName());
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getName()
+	 */
+	public void test_getName() {
+		// Test for method java.lang.String java.util.zip.ZipEntry.getName()
+		assertEquals("Incorrect name returned - Note return result somewhat ambiguous in spec",
+				"File1.txt", zentry.getName());
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getSize()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getSize",
-        args = {}
-    )
-    public void test_getSize() {
-        // Test for method long java.util.zip.ZipEntry.getSize()
-        assertTrue("Incorrect size returned", zentry.getSize() == orgSize);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getSize()
+	 */
+	public void test_getSize() {
+		// Test for method long java.util.zip.ZipEntry.getSize()
+		assertTrue("Incorrect size returned", zentry.getSize() == orgSize);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#getTime()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTime",
-        args = {}
-    )
-    public void test_getTime() {
-        // Test for method long java.util.zip.ZipEntry.getTime()
-        assertTrue("Failed to get time", zentry.getTime() == orgTime);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#getTime()
+	 */
+	public void test_getTime() {
+		// Test for method long java.util.zip.ZipEntry.getTime()
+		assertTrue("Failed to get time", zentry.getTime() == orgTime);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#isDirectory()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isDirectory",
-        args = {}
-    )
-    public void test_isDirectory() {
-        // Test for method boolean java.util.zip.ZipEntry.isDirectory()
-        assertTrue("Entry should not answer true to isDirectory", !zentry
-                .isDirectory());
-        zentry = new ZipEntry("Directory/");
-        assertTrue("Entry should answer true to isDirectory", zentry
-                .isDirectory());
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#isDirectory()
+	 */
+	public void test_isDirectory() {
+		// Test for method boolean java.util.zip.ZipEntry.isDirectory()
+		assertTrue("Entry should not answer true to isDirectory", !zentry
+				.isDirectory());
+		zentry = new ZipEntry("Directory/");
+		assertTrue("Entry should answer true to isDirectory", zentry
+				.isDirectory());
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setComment(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setComment",
-        args = {java.lang.String.class}
-    )
-    public void test_setCommentLjava_lang_String() {
-        // Test for method void
-        // java.util.zip.ZipEntry.setComment(java.lang.String)
-        zentry = zfile.getEntry("File1.txt");
-        zentry.setComment("Set comment using api");
-        assertEquals("Comment not correctly set", "Set comment using api",
-                zentry.getComment());
-        String n = null;
-        zentry.setComment(n);
-        assertNull("Comment not correctly set", zentry.getComment());
-        StringBuffer s = new StringBuffer();
-        for (int i = 0; i < 0xFFFF; i++) {
+	/**
+	 * @tests java.util.zip.ZipEntry#setComment(java.lang.String)
+	 */
+	public void test_setCommentLjava_lang_String() {
+		// Test for method void
+		// java.util.zip.ZipEntry.setComment(java.lang.String)
+		zentry = zfile.getEntry("File1.txt");
+		zentry.setComment("Set comment using api");
+		assertEquals("Comment not correctly set", 
+				"Set comment using api", zentry.getComment());
+		String n = null;
+		zentry.setComment(n);
+		assertNull("Comment not correctly set", zentry.getComment());
+		StringBuffer s = new StringBuffer();
+		for (int i = 0; i < 0xFFFF; i++) {
             s.append('a');
         }
-        try {
-            zentry.setComment(s.toString());
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException During Test.");
-        }
-        try {
-            s.append('a');
-            zentry.setComment(s.toString());
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+		try {
+			zentry.setComment(s.toString());
+		} catch (IllegalArgumentException e) {
+			fail("Unexpected IllegalArgumentException During Test.");
+		}
+		try {
+			s.append('a');
+			zentry.setComment(s.toString());
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setCompressedSize(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setCompressedSize",
-        args = {long.class}
-    )
-    public void test_setCompressedSizeJ() {
-        // Test for method void java.util.zip.ZipEntry.setCompressedSize(long)
-        zentry.setCompressedSize(orgCompressedSize + 10);
-        assertTrue("Set compressed size failed",
-                zentry.getCompressedSize() == (orgCompressedSize + 10));
-        zentry.setCompressedSize(0);
-        assertEquals("Set compressed size failed", 0, zentry
-                .getCompressedSize());
-        zentry.setCompressedSize(-25);
-        assertEquals("Set compressed size failed", -25, zentry
-                .getCompressedSize());
-        zentry.setCompressedSize(4294967296l);
-        assertTrue("Set compressed size failed",
-                zentry.getCompressedSize() == 4294967296l);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#setCompressedSize(long)
+	 */
+	public void test_setCompressedSizeJ() {
+		// Test for method void java.util.zip.ZipEntry.setCompressedSize(long)
+		zentry.setCompressedSize(orgCompressedSize + 10);
+		assertTrue("Set compressed size failed",
+				zentry.getCompressedSize() == (orgCompressedSize + 10));
+		zentry.setCompressedSize(0);
+		assertEquals("Set compressed size failed",
+				0, zentry.getCompressedSize());
+		zentry.setCompressedSize(-25);
+		assertEquals("Set compressed size failed",
+				-25, zentry.getCompressedSize());
+		zentry.setCompressedSize(4294967296l);
+		assertTrue("Set compressed size failed",
+				zentry.getCompressedSize() == 4294967296l);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setCrc(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setCrc",
-        args = {long.class}
-    )
-    public void test_setCrcJ() {
-        // Test for method void java.util.zip.ZipEntry.setCrc(long)
-        zentry.setCrc(orgCrc + 100);
-        assertTrue("Failed to set Crc", zentry.getCrc() == (orgCrc + 100));
-        zentry.setCrc(0);
-        assertEquals("Failed to set Crc", 0, zentry.getCrc());
-        try {
-            zentry.setCrc(-25);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            zentry.setCrc(4294967295l);
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException during test");
-        }
-        try {
-            zentry.setCrc(4294967296l);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#setCrc(long)
+	 */
+	public void test_setCrcJ() {
+		// Test for method void java.util.zip.ZipEntry.setCrc(long)
+		zentry.setCrc(orgCrc + 100);
+		assertTrue("Failed to set Crc", zentry.getCrc() == (orgCrc + 100));
+		zentry.setCrc(0);
+		assertEquals("Failed to set Crc", 0, zentry.getCrc());
+		try {
+			zentry.setCrc(-25);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			zentry.setCrc(4294967295l);
+		} catch (IllegalArgumentException e) {
+			fail("Unexpected IllegalArgumentException during test");
+		}
+		try {
+			zentry.setCrc(4294967296l);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setExtra(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setExtra",
-        args = {byte[].class}
-    )
-    public void test_setExtra$B() {
-        // Test for method void java.util.zip.ZipEntry.setExtra(byte [])
-        zentry = zfile.getEntry("File1.txt");
-        zentry.setExtra("Test setting extra information".getBytes());
-        assertEquals("Extra information not written properly",
-                "Test setting extra information", new String(zentry.getExtra(),
-                        0, zentry.getExtra().length));
-        zentry = new ZipEntry("test.tst");
-        byte[] ba = new byte[0xFFFF];
-        try {
-            zentry.setExtra(ba);
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException during test");
-        }
-        try {
-            ba = new byte[0xFFFF + 1];
-            zentry.setExtra(ba);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
+	/**
+	 * @tests java.util.zip.ZipEntry#setExtra(byte[])
+	 */
+	public void test_setExtra$B() {
+		// Test for method void java.util.zip.ZipEntry.setExtra(byte [])
+		zentry = zfile.getEntry("File1.txt");
+		zentry.setExtra("Test setting extra information".getBytes());
+		assertEquals("Extra information not written properly", "Test setting extra information", new String(zentry
+				.getExtra(), 0, zentry.getExtra().length)
+				);
+		zentry = new ZipEntry("test.tst");
+		byte[] ba = new byte[0xFFFF];
+		try {
+			zentry.setExtra(ba);
+		} catch (IllegalArgumentException e) {
+			fail("Unexpected IllegalArgumentException during test");
+		}
+		try {
+			ba = new byte[0xFFFF + 1];
+			zentry.setExtra(ba);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
 
-        // One constructor
-        ZipEntry zeInput = new ZipEntry("InputZIP");
-        byte[] extraB = {'a', 'b', 'd', 'e'};
-        zeInput.setExtra(extraB);
-        assertEquals(extraB, zeInput.getExtra());
-        assertEquals(extraB[3], zeInput.getExtra()[3]);
-        assertEquals(extraB.length, zeInput.getExtra().length);
+		// One constructor
+		ZipEntry zeInput = new ZipEntry("InputZIP");
+		byte[] extraB = { 'a', 'b', 'd', 'e' };
+		zeInput.setExtra(extraB);
+		assertEquals(extraB, zeInput.getExtra());
+		assertEquals(extraB[3], zeInput.getExtra()[3]);
+		assertEquals(extraB.length, zeInput.getExtra().length);
 
-        // test another constructor
-        ZipEntry zeOutput = new ZipEntry(zeInput);
-        assertEquals(zeInput.getExtra()[3], zeOutput.getExtra()[3]);
-        assertEquals(zeInput.getExtra().length, zeOutput.getExtra().length);
-        assertEquals(extraB[3], zeOutput.getExtra()[3]);
-        assertEquals(extraB.length, zeOutput.getExtra().length);
-    }
+		// test another constructor
+		ZipEntry zeOutput = new ZipEntry(zeInput);
+		assertEquals(zeInput.getExtra()[3], zeOutput.getExtra()[3]);
+		assertEquals(zeInput.getExtra().length, zeOutput.getExtra().length);
+		assertEquals(extraB[3], zeOutput.getExtra()[3]);
+		assertEquals(extraB.length, zeOutput.getExtra().length);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setMethod(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setMethod",
-        args = {int.class}
-    )
-    public void test_setMethodI() {
-        // Test for method void java.util.zip.ZipEntry.setMethod(int)
-        zentry = zfile.getEntry("File3.txt");
-        zentry.setMethod(ZipEntry.STORED);
-        assertTrue("Failed to set compression method",
-                zentry.getMethod() == ZipEntry.STORED);
-        zentry.setMethod(ZipEntry.DEFLATED);
-        assertTrue("Failed to set compression method",
-                zentry.getMethod() == ZipEntry.DEFLATED);
-        try {
-            int error = 1;
-            zentry = new ZipEntry("test.tst");
-            zentry.setMethod(error);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#setMethod(int)
+	 */
+	public void test_setMethodI() {
+		// Test for method void java.util.zip.ZipEntry.setMethod(int)
+		zentry = zfile.getEntry("File3.txt");
+		zentry.setMethod(ZipEntry.STORED);
+		assertTrue("Failed to set compression method",
+				zentry.getMethod() == ZipEntry.STORED);
+		zentry.setMethod(ZipEntry.DEFLATED);
+		assertTrue("Failed to set compression method",
+				zentry.getMethod() == ZipEntry.DEFLATED);
+		try {
+			int error = 1;
+			zentry = new ZipEntry("test.tst");
+			zentry.setMethod(error);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setSize(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setSize",
-        args = {long.class}
-    )
-    public void test_setSizeJ() {
-        // Test for method void java.util.zip.ZipEntry.setSize(long)
-        zentry.setSize(orgSize + 10);
-        assertTrue("Set size failed", zentry.getSize() == (orgSize + 10));
-        zentry.setSize(0);
-        assertEquals("Set size failed", 0, zentry.getSize());
-        try {
-            zentry.setSize(-25);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            zentry.setCrc(4294967295l);
-        } catch (IllegalArgumentException e) {
-            fail("Unexpected IllegalArgumentException during test");
-        }
-        try {
-            zentry.setCrc(4294967296l);
-            fail("IllegalArgumentException not thrown");
-        } catch (IllegalArgumentException e) {
-        }
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#setSize(long)
+	 */
+	public void test_setSizeJ() {
+		// Test for method void java.util.zip.ZipEntry.setSize(long)
+		zentry.setSize(orgSize + 10);
+		assertTrue("Set size failed", zentry.getSize() == (orgSize + 10));
+		zentry.setSize(0);
+		assertEquals("Set size failed", 0, zentry.getSize());
+		try {
+			zentry.setSize(-25);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			zentry.setCrc(4294967295l);
+		} catch (IllegalArgumentException e) {
+			fail("Unexpected IllegalArgumentException during test");
+		}
+		try {
+			zentry.setCrc(4294967296l);
+			fail("IllegalArgumentException not thrown");
+		} catch (IllegalArgumentException e) {
+		}
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#setTime(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setTime",
-        args = {long.class}
-    )
-    public void test_setTimeJ() {
-        // Test for method void java.util.zip.ZipEntry.setTime(long)
-        zentry.setTime(orgTime + 10000);
-        assertTrue("Test 1: Failed to set time: " + zentry.getTime(), zentry
-                .getTime() == (orgTime + 10000));
-        zentry.setTime(orgTime - 10000);
-        assertTrue("Test 2: Failed to set time: " + zentry.getTime(), zentry
-                .getTime() == (orgTime - 10000));
-        TimeZone zone = TimeZone.getDefault();
-        try {
-            TimeZone.setDefault(TimeZone.getTimeZone("EST"));
-            zentry.setTime(0);
-            assertTrue("Test 3: Failed to set time: " + zentry.getTime(),
-                    zentry.getTime() == 315550800000L);
-            TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
-            assertTrue("Test 3a: Failed to set time: " + zentry.getTime(),
-                    zentry.getTime() == 315532800000L);
-            zentry.setTime(0);
-            TimeZone.setDefault(TimeZone.getTimeZone("EST"));
-            assertTrue("Test 3b: Failed to set time: " + zentry.getTime(),
-                    zentry.getTime() == 315550800000L);
+	/**
+	 * @tests java.util.zip.ZipEntry#setTime(long)
+	 */
+	public void test_setTimeJ() {
+		// Test for method void java.util.zip.ZipEntry.setTime(long)
+		zentry.setTime(orgTime + 10000);
+		assertTrue("Test 1: Failed to set time: " + zentry.getTime(), zentry
+				.getTime() == (orgTime + 10000));
+		zentry.setTime(orgTime - 10000);
+		assertTrue("Test 2: Failed to set time: " + zentry.getTime(), zentry
+				.getTime() == (orgTime - 10000));
+		TimeZone zone = TimeZone.getDefault();
+		try {
+			TimeZone.setDefault(TimeZone.getTimeZone("EST"));
+			zentry.setTime(0);
+			assertTrue("Test 3: Failed to set time: " + zentry.getTime(),
+					zentry.getTime() == 315550800000L);
+			TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+			assertTrue("Test 3a: Failed to set time: " + zentry.getTime(),
+					zentry.getTime() == 315532800000L);
+			zentry.setTime(0);
+			TimeZone.setDefault(TimeZone.getTimeZone("EST"));
+			assertTrue("Test 3b: Failed to set time: " + zentry.getTime(),
+					zentry.getTime() == 315550800000L);
 
-            zentry.setTime(-25);
-            assertTrue("Test 4: Failed to set time: " + zentry.getTime(),
-                    zentry.getTime() == 315550800000L);
-            zentry.setTime(4354837200000L);
-            assertTrue("Test 5: Failed to set time: " + zentry.getTime(),
-                    zentry.getTime() == 315550800000L);
-        } finally {
-            TimeZone.setDefault(zone);
-        }
-    }
+			zentry.setTime(-25);
+			assertTrue("Test 4: Failed to set time: " + zentry.getTime(),
+					zentry.getTime() == 315550800000L);
+			zentry.setTime(4354837200000L);
+			assertTrue("Test 5: Failed to set time: " + zentry.getTime(),
+					zentry.getTime() == 315550800000L);
+		} finally {
+			TimeZone.setDefault(zone);
+		}
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#toString()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
-    public void test_toString() {
-        // Test for method java.lang.String java.util.zip.ZipEntry.toString()
-        assertTrue("Returned incorrect entry name", zentry.toString().indexOf(
-                "File1.txt") >= 0);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#toString()
+	 */
+	public void test_toString() {
+		// Test for method java.lang.String java.util.zip.ZipEntry.toString()
+		assertTrue("Returned incorrect entry name", zentry.toString().indexOf(
+				"File1.txt") >= 0);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#ZipEntry(java.util.zip.ZipEntry)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ZipEntry",
-        args = {java.util.zip.ZipEntry.class}
-    )
-    public void test_ConstructorLjava_util_zip_ZipEntry() {
-        // Test for method java.util.zip.ZipEntry(util.zip.ZipEntry)
-        zentry.setSize(2);
-        zentry.setCompressedSize(4);
-        zentry.setComment("Testing");
-        ZipEntry zentry2 = new ZipEntry(zentry);
-        assertEquals("ZipEntry Created With Incorrect Size.", 2, zentry2
-                .getSize());
-        assertEquals("ZipEntry Created With Incorrect Compressed Size.", 4,
-                zentry2.getCompressedSize());
-        assertEquals("ZipEntry Created With Incorrect Comment.", "Testing",
-                zentry2.getComment());
-        assertTrue("ZipEntry Created With Incorrect Crc.",
-                zentry2.getCrc() == orgCrc);
-        assertTrue("ZipEntry Created With Incorrect Time.",
-                zentry2.getTime() == orgTime);
-    }
+	/**
+	 * @tests java.util.zip.ZipEntry#ZipEntry(java.util.zip.ZipEntry)
+	 */
+	public void test_ConstructorLjava_util_zip_ZipEntry() {
+		// Test for method java.util.zip.ZipEntry(util.zip.ZipEntry)
+		zentry.setSize(2);
+		zentry.setCompressedSize(4);
+		zentry.setComment("Testing");
+		ZipEntry zentry2 = new ZipEntry(zentry);
+		assertEquals("ZipEntry Created With Incorrect Size.",
+				2, zentry2.getSize());
+		assertEquals("ZipEntry Created With Incorrect Compressed Size.", 4, zentry2
+				.getCompressedSize());
+		assertEquals("ZipEntry Created With Incorrect Comment.", "Testing", zentry2
+				.getComment());
+		assertTrue("ZipEntry Created With Incorrect Crc.",
+				zentry2.getCrc() == orgCrc);
+		assertTrue("ZipEntry Created With Incorrect Time.",
+				zentry2.getTime() == orgTime);
+	}
 
-    /**
-     * @tests java.util.zip.ZipEntry#clone()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clone",
-        args = {}
-    )
-    public void test_clone() {
-        // Test for method java.util.zip.ZipEntry.clone()
-        Object obj = zentry.clone();
-        assertTrue("toString()", obj.toString().equals(zentry.toString()));
-        assertTrue("hashCode()", obj.hashCode() == zentry.hashCode());
+	/**
+	 * @tests java.util.zip.ZipEntry#clone()
+	 */
+	public void test_clone() {
+		// Test for method java.util.zip.ZipEntry.clone()
+		Object obj = zentry.clone();
+		assertTrue("toString()", obj.toString().equals(zentry.toString()));
+		assertTrue("hashCode()", obj.hashCode() == zentry.hashCode());
 
-        // One constructor
-        ZipEntry zeInput = new ZipEntry("InputZIP");
-        byte[] extraB = {'a', 'b', 'd', 'e'};
-        zeInput.setExtra(extraB);
-        assertEquals(extraB, zeInput.getExtra());
-        assertEquals(extraB[3], zeInput.getExtra()[3]);
-        assertEquals(extraB.length, zeInput.getExtra().length);
+		// One constructor
+		ZipEntry zeInput = new ZipEntry("InputZIP");
+		byte[] extraB = { 'a', 'b', 'd', 'e' };
+		zeInput.setExtra(extraB);
+		assertEquals(extraB, zeInput.getExtra());
+		assertEquals(extraB[3], zeInput.getExtra()[3]);
+		assertEquals(extraB.length, zeInput.getExtra().length);
 
-        // test Clone()
-        ZipEntry zeOutput = (ZipEntry) zeInput.clone();
-        assertEquals(zeInput.getExtra()[3], zeOutput.getExtra()[3]);
-        assertEquals(zeInput.getExtra().length, zeOutput.getExtra().length);
-        assertEquals(extraB[3], zeOutput.getExtra()[3]);
-        assertEquals(extraB.length, zeOutput.getExtra().length);
-    }
+		// test Clone()
+		ZipEntry zeOutput = (ZipEntry) zeInput.clone();
+		assertEquals(zeInput.getExtra()[3], zeOutput.getExtra()[3]);
+		assertEquals(zeInput.getExtra().length, zeOutput.getExtra().length);
+		assertEquals(extraB[3], zeOutput.getExtra()[3]);
+		assertEquals(extraB.length, zeOutput.getExtra().length);
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
-    public void test_hashCode() {
-        try {
-            zentry.hashCode();
-        } catch (Exception ee) {
-            fail("Unexpected exception " + ee);
-        }
-    }
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
 
-    /**
-     * Sets up the fixture, for example, open a network connection. This method
-     * is called before a test is executed.
-     */
-
-    @Override
+	@Override
     protected void setUp() {
-        java.io.File f = null;
-        try {
-            // BEGIN android-changed
-            // Create a local copy of the file since some tests want to alter
-            // information.
-            f = File.createTempFile(tempFileName, ".zip");
-            // Create absolute filename as ZipFile does not resolve using
-            // user.dir
-            f = new java.io.File(f.getAbsolutePath());
-            f.delete();
-            java.io.InputStream is = Support_Resources
-                    .getStream("hyts_ZipFile.zip");
-            java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
+		java.io.File f = null;
+		try {
+			// Create a local copy of the file since some tests want to alter
+			// information.
+			f = new java.io.File(tempFileName);
+			// Create absolute filename as ZipFile does not resolve using
+			// user.dir
+			f = new java.io.File(f.getAbsolutePath());
+			f.delete();
+			java.io.InputStream is = Support_Resources
+					.getStream("hyts_ZipFile.zip");
+			java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
             byte[] rbuf = getAllBytesFromStream(is);
-            // END android-changed
-            fos.write(rbuf, 0, rbuf.length);
-            is.close();
-            fos.close();
-            zfile = new java.util.zip.ZipFile(f);
-            zentry = zfile.getEntry("File1.txt");
-            orgSize = zentry.getSize();
-            orgCompressedSize = zentry.getCompressedSize();
-            orgCrc = zentry.getCrc();
-            orgTime = zentry.getTime();
-            orgComment = zentry.getComment();
-        } catch (Exception e) {
-            System.out.println("Exception during ZipFile setup <"
-                    + f.getAbsolutePath() + ">: ");
-            e.printStackTrace();
-        }
-    }
+			fos.write(rbuf, 0, rbuf.length);
+			is.close();
+			fos.close();
+			zfile = new java.util.zip.ZipFile(f);
+			zentry = zfile.getEntry("File1.txt");
+			orgSize = zentry.getSize();
+			orgCompressedSize = zentry.getCompressedSize();
+			orgCrc = zentry.getCrc();
+			orgTime = zentry.getTime();
+			orgComment = zentry.getComment();
+		} catch (Exception e) {
+			System.out.println("Exception during ZipFile setup <"
+					+ f.getAbsolutePath() + ">: ");
+			e.printStackTrace();
+		}
+	}
 
-    /**
-     * Tears down the fixture, for example, close a network connection. This
-     * method is called after a test is executed.
-     */
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
 
-    @Override
+	@Override
     protected void tearDown() {
-        try {
-            if (zfile != null) {
+		try {
+			if (zfile != null) {
                 zfile.close();
             }
-            java.io.File f = new java.io.File(tempFileName);
-            f.delete();
-        } catch (java.io.IOException e) {
-            System.out.println("Exception during tearDown");
-        }
-    }
+			java.io.File f = new java.io.File(tempFileName);
+			f.delete();
+		} catch (java.io.IOException e) {
+			System.out.println("Exception during tearDown");
+		}
+	}
 
 }
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipExceptionTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipExceptionTest.java
index eb04777..9f3be8d 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipExceptionTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipExceptionTest.java
@@ -16,35 +16,17 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 import java.util.zip.ZipException;
 
-@TestTargetClass(ZipException.class)
 public class ZipExceptionTest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ZipException",
-        args = {}
-    )
     public void testZipException() {
         ZipException zz = new ZipException();
         assertEquals(zz.getMessage(), null);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ZipException",
-        args = {java.lang.String.class}
-    )
     public void testZipExceptionLjava_lang_String() {
         ZipException zz = new ZipException("Test");
         assertEquals(zz.getMessage(), "Test");
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
index fb326a6..7ff4f98 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipFileTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 import tests.support.Support_PlatformFile;
 import tests.support.resource.Support_Resources;
 import tests.util.TestEnvironment;
@@ -38,7 +34,6 @@
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
 
-@TestTargetClass(ZipFile.class)
 public class ZipFileTest extends junit.framework.TestCase {
 
     public byte[] getAllBytesFromStream(InputStream is) throws IOException {
@@ -77,12 +72,6 @@
     /**
      * @tests java.util.zip.ZipFile#ZipFile(java.io.File)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "setUp procedure checks this type of constructor.",
-        method = "ZipFile",
-        args = {java.io.File.class}
-    )
     public void test_ConstructorLjava_io_File() {
         // Test for method java.util.zip.ZipFile(java.io.File)
         assertTrue("Used to test", true);
@@ -91,11 +80,6 @@
     /**
      * @tests java.util.zip.ZipFile#ZipFile(java.io.File, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "ZipFile",
-        args = {java.io.File.class, int.class}
-    )
     public void test_ConstructorLjava_io_FileI() throws IOException {
         zfile.close(); // about to reopen the same temp file
         File file = new File(tempFileName);
@@ -136,12 +120,6 @@
      * @throws IOException
      * @tests java.util.zip.ZipFile#ZipFile(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Test contains empty brackets.",
-        method = "ZipFile",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() throws IOException {
         System.setProperty("user.dir", System.getProperty("java.io.tmpdir"));
 
@@ -181,12 +159,6 @@
     /**
      * @tests java.util.zip.ZipFile#finalize()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "finalize",
-        args = {}
-    )
     public void test_finalize() throws IOException {
         InputStream in = Support_Resources.getStream("hyts_ZipFile.zip");
         File file = Support_Resources.createTempFile(".jar");
@@ -217,11 +189,6 @@
      * @throws IOException
      * @tests java.util.zip.ZipFile#close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "close",
-        args = {}
-    )
     public void test_close() throws IOException {
         // Test for method void java.util.zip.ZipFile.close()
         File fl = new File(tempFileName);
@@ -252,12 +219,6 @@
     /**
      * @tests java.util.zip.ZipFile#entries()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entries",
-        args = {}
-    )
     public void test_entries() throws Exception {
         // Test for method java.util.Enumeration java.util.zip.ZipFile.entries()
         Enumeration<? extends ZipEntry> enumer = zfile.entries();
@@ -292,11 +253,6 @@
     /**
      * @tests java.util.zip.ZipFile#getEntry(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "getEntry",
-        args = {java.lang.String.class}
-    )
     public void test_getEntryLjava_lang_String() throws IOException {
         // Test for method java.util.zip.ZipEntry
         // java.util.zip.ZipFile.getEntry(java.lang.String)
@@ -325,11 +281,6 @@
                 0, r));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "getEntry",
-        args = {java.lang.String.class}
-    )
     public void test_getEntryLjava_lang_String_AndroidOnly() throws IOException {
         java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
         assertNotNull("Could not obtain ZipEntry", zentry);
@@ -351,12 +302,6 @@
         assertEquals("Must not be able to read directory data", -1, data);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IllegalStateException checking.",
-        method = "getEntry",
-        args = {java.lang.String.class}
-    )
     public void test_getEntryLjava_lang_String_Ex() throws IOException {
         java.util.zip.ZipEntry zentry = zfile.getEntry("File1.txt");
         assertNotNull("Could not obtain ZipEntry", zentry);
@@ -373,12 +318,6 @@
      * @throws IOException
      * @tests java.util.zip.ZipFile#getInputStream(java.util.zip.ZipEntry)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInputStream",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_getInputStreamLjava_util_zip_ZipEntry() throws IOException {
         // Test for method java.io.InputStream
         // java.util.zip.ZipFile.getInputStream(java.util.zip.ZipEntry)
@@ -417,12 +356,6 @@
     /**
      * @tests java.util.zip.ZipFile#getName()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getName",
-        args = {}
-    )
     public void test_getName() {
         // Test for method java.lang.String java.util.zip.ZipFile.getName()
         assertTrue("Returned incorrect name: " + zfile.getName(), zfile
@@ -433,11 +366,6 @@
      * @throws IOException
      * @tests java.util.zip.ZipFile#size()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "size",
-        args = {}
-    )
     public void test_size() throws IOException {
         assertEquals(6, zfile.size());
         zfile.close();
@@ -451,12 +379,6 @@
     /**
      * @tests java.io.InputStream#reset()
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "getInputStream",
-            args = {java.util.zip.ZipEntry.class}
-    )
-    @KnownFailure("ZipEntry.getInputStream().reset() fails with an IOException")
     public void test_reset() throws IOException {
         // read an uncompressed entry
         ZipEntry zentry = zfile.getEntry("File1.txt");
@@ -469,9 +391,11 @@
         r2 = is.read(rbuf2);
         assertEquals(rbuf2.length, r2);
 
-        is.reset();
-        r2 = is.read(rbuf2);
-        assertEquals(rbuf2.length, r2);
+        try {
+            is.reset();
+            fail();
+        } catch (IOException expected) {
+        }
         is.close();
 
         // read a compressed entry
@@ -480,30 +404,27 @@
         is = zfile.getInputStream(zentry2);
         r1 = is.read(rbuf3);
         assertEquals(4183, r1);
-        is.reset();
-
-        r1 = is.read(rbuf3);
-        assertEquals(4183, r1);
+        try {
+            is.reset();
+            fail();
+        } catch (IOException expected) {
+        }
         is.close();
 
         is = zfile.getInputStream(zentry2);
         r1 = is.read(rbuf3, 0, 3000);
         assertEquals(3000, r1);
-        is.reset();
-        r1 = is.read(rbuf3, 0, 3000);
-        assertEquals(3000, r1);
+        try {
+            is.reset();
+            fail();
+        } catch (IOException expected) {
+        }
         is.close();
     }
 
     /**
      * @tests java.io.InputStream#reset()
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "getInputStream",
-            args = {java.util.zip.ZipEntry.class}
-    )
-    @KnownFailure("ZipEntry.getInputStream().reset() fails with an IOException")
     public void test_reset_subtest0() throws IOException {
         // read an uncompressed entry
         ZipEntry zentry = zfile.getEntry("File1.txt");
@@ -517,10 +438,12 @@
         assertEquals(8, r);
         assertEquals(-1, is.read());
 
-        is.reset();
-        r = is.read(rbuf2);
-        assertEquals(8, r);
-        assertEquals(-1, is.read());
+        try {
+            is.reset();
+            fail();
+        } catch (IOException expected) {
+        }
+
         is.close();
 
         // read a compressed entry
@@ -534,10 +457,12 @@
         assertEquals(1183, r);
         assertEquals(-1, is.read());
 
-        is.reset();
-        r = is.read(rbuf3);
-        assertEquals(1183, r);
-        assertEquals(-1, is.read());
+        try {
+            is.reset();
+            fail();
+        } catch (IOException expected) {
+        }
+
         is.close();
     }
 
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
index c5efedc..02ddd08 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipInputStreamTest.java
@@ -17,10 +17,6 @@
 
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import tests.support.resource.Support_Resources;
@@ -37,7 +33,6 @@
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
-@TestTargetClass(ZipInputStream.class)
 public class ZipInputStreamTest extends TestCase {
     // the file hyts_zipFile.zip used in setup needs to included as a resource
     private ZipEntry zentry;
@@ -84,12 +79,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#ZipInputStream(java.io.InputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ZipInputStream",
-        args = {java.io.InputStream.class}
-    )
     public void test_ConstructorLjava_io_InputStream() throws Exception {
         zentry = zis.getNextEntry();
         zis.closeEntry();
@@ -98,12 +87,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
     public void test_close() {
         try {
             zis.close();
@@ -118,12 +101,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#close()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks calling method two times",
-        method = "close",
-        args = {}
-    )
     public void test_close2() throws Exception {
         // Regression for HARMONY-1101
         zis.close();
@@ -134,12 +111,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#closeEntry()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "closeEntry",
-        args = {}
-    )
     public void test_closeEntry() throws Exception {
         zentry = zis.getNextEntry();
         zis.closeEntry();
@@ -169,11 +140,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "close",
-        args = {}
-    )
     public void test_closeAfterException() throws Exception {
         File resources = Support_Resources.createTempFolder();
         Support_Resources.copyFile(resources, null, "Broken_manifest.jar");
@@ -203,11 +169,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#getNextEntry()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getNextEntry",
-        args = {}
-    )
     public void test_getNextEntry() throws Exception {
         assertNotNull("getNextEntry failed", zis.getNextEntry());
 
@@ -239,11 +200,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#read(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_read$BII() throws Exception {
         zentry = zis.getNextEntry();
         byte[] rbuf = new byte[(int) zentry.getSize()];
@@ -279,11 +235,6 @@
         }
     }
 
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            method = "read",
-            args = {byte[].class, int.class, int.class}
-    )
     public void testReadOneByteAtATime() throws IOException {
         InputStream in = new FilterInputStream(Support_Resources.getStream("hyts_ZipFile.zip")) {
             @Override
@@ -307,11 +258,6 @@
     /**
      * @tests java.util.zip.ZipInputStream#skip(long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "skip",
-        args = {long.class}
-    )
     public void test_skipJ() throws Exception {
         zentry = zis.getNextEntry();
         byte[] rbuf = new byte[(int) zentry.getSize()];
@@ -365,11 +311,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "available",
-        args = {}
-    )
     public void test_available() throws Exception {
 
         File resources = Support_Resources.createTempFolder();
@@ -422,12 +363,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "createZipEntry",
-        args = {java.lang.String.class}
-    )
     public void test_createZipEntryLjava_lang_String() throws Exception {
 
         File resources = Support_Resources.createTempFolder();
diff --git a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipOutputStreamTest.java b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipOutputStreamTest.java
index 0398f03..7adfeff 100644
--- a/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipOutputStreamTest.java
+++ b/archive/src/test/java/org/apache/harmony/archive/tests/java/util/zip/ZipOutputStreamTest.java
@@ -14,14 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.archive.tests.java.util.zip;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -33,27 +27,20 @@
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
-@TestTargetClass(ZipOutputStream.class)
 public class ZipOutputStreamTest extends junit.framework.TestCase {
 
-    ZipOutputStream zos;
+	ZipOutputStream zos;
 
-    ByteArrayOutputStream bos;
+	ByteArrayOutputStream bos;
 
-    ZipInputStream zis;
+	ZipInputStream zis;
 
-    static final String data = "HelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorld";
+	static final String data = "HelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorld";
 
-    /**
+	/**
      * @tests java.util.zip.ZipOutputStream#close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Can not check IOException.",
-        method = "close",
-        args = {}
-    )
-    public void test_close() throws Exception {
+	public void test_close() throws Exception {
         try {
             zos.close();
             fail("Close on empty stream failed to throw exception");
@@ -76,12 +63,6 @@
     /**
      * @tests java.util.zip.ZipOutputStream#closeEntry()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "ZipException can not be checked.",
-        method = "closeEntry",
-        args = {}
-    )
     public void test_closeEntry() throws IOException {
         ZipEntry ze = new ZipEntry("testEntry");
         ze.setTime(System.currentTimeMillis());
@@ -90,25 +71,12 @@
         zos.closeEntry();
         assertTrue("closeEntry failed to update required fields",
                 ze.getSize() == 11 && ze.getCompressedSize() == 13);
-        ze = new ZipEntry("testEntry1");
-        zos.close();
-        try {
-            zos.closeEntry();
-            fail("IOException expected");
-        } catch (IOException ee) {
-            // expected
-        }
+
     }
 
     /**
      * @tests java.util.zip.ZipOutputStream#finish()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "ZipException can not be checked.",
-        method = "finish",
-        args = {}
-    )
     public void test_finish() throws Exception {
         ZipEntry ze = new ZipEntry("test");
         zos.putNextEntry(ze);
@@ -131,12 +99,6 @@
     /**
      * @tests java.util.zip.ZipOutputStream#putNextEntry(java.util.zip.ZipEntry)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "ZipException can not be checked.",
-        method = "putNextEntry",
-        args = {java.util.zip.ZipEntry.class}
-    )
     public void test_putNextEntryLjava_util_zip_ZipEntry() throws IOException {
         ZipEntry ze = new ZipEntry("testEntry");
         ze.setTime(System.currentTimeMillis());
@@ -161,12 +123,6 @@
     /**
      * @tests java.util.zip.ZipOutputStream#setComment(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setComment",
-        args = {java.lang.String.class}
-    )
     public void test_setCommentLjava_lang_String() {
         // There is no way to get the comment back, so no way to determine if
         // the comment is set correct
@@ -183,12 +139,6 @@
     /**
      * @tests java.util.zip.ZipOutputStream#setLevel(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setLevel",
-        args = {int.class}
-    )
     public void test_setLevelI() throws IOException {
         ZipEntry ze = new ZipEntry("test");
         zos.putNextEntry(ze);
@@ -200,23 +150,11 @@
         zos.write(data.getBytes());
         zos.closeEntry();
         assertTrue("setLevel failed", csize <= ze.getCompressedSize());
-        try {
-            zos.setLevel(-9); // Max Compression
-            fail("IllegalArgumentException ecpected.");
-        } catch (IllegalArgumentException ee) {
-            // expected
-        }
     }
 
     /**
      * @tests java.util.zip.ZipOutputStream#setMethod(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setMethod",
-        args = {int.class}
-    )
     public void test_setMethodI() throws IOException {
         ZipEntry ze = new ZipEntry("test");
         zos.setMethod(ZipOutputStream.STORED);
@@ -233,23 +171,11 @@
         zos.write(data.getBytes());
         zos.closeEntry();
         assertTrue("setLevel failed", csize >= ze.getCompressedSize());
-        try {
-            zos.setMethod(-ZipOutputStream.DEFLATED);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException ee) {
-            // expected
-        }
     }
 
     /**
      * @tests java.util.zip.ZipOutputStream#write(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_write$BII() throws IOException {
         ZipEntry ze = new ZipEntry("test");
         zos.putNextEntry(ze);
@@ -314,12 +240,6 @@
     /**
      * @tests java.util.zip.ZipOutputStream#write(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Regression",
-        method = "write",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_write$BII_2() throws IOException {
         // Regression for HARMONY-577
         File f1 = File.createTempFile("testZip1", "tst");
@@ -331,7 +251,7 @@
         zip1.setMethod(ZipEntry.STORED);
 
         zip1.write(new byte[2]);
-
+        
         try {
             zip1.putNextEntry(new ZipEntry("Second"));
             fail("ZipException expected");
@@ -364,18 +284,7 @@
             if (zis != null) {
                 zis.close();
             }
-        } catch (Exception e) {
-        }
+        } catch (Exception e) {}
         super.tearDown();
     }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "See setUp procedure for more info.",
-        method = "ZipOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void test_ConstructorLjava_io_OutputStream() {
-        assertTrue(true);
-    }
 }
diff --git a/archive/src/test/java/tests/archive/AllTests.java b/archive/src/test/java/tests/archive/AllTests.java
index a5c461c..4c1fca2 100644
--- a/archive/src/test/java/tests/archive/AllTests.java
+++ b/archive/src/test/java/tests/archive/AllTests.java
@@ -21,13 +21,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Archive test suites");
+        TestSuite suite = new TestSuite("All Archive test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.archive.tests.java.util.jar.AllTests
                 .suite());
diff --git a/auth/src/main/java/javax/security/auth/callback/package.html b/auth/src/main/java/javax/security/auth/callback/package.html
index 5446ab8..c102954 100644
--- a/auth/src/main/java/javax/security/auth/callback/package.html
+++ b/auth/src/main/java/javax/security/auth/callback/package.html
@@ -6,9 +6,9 @@
 <body>
 <p>
 This package provides classes and interfaces needed to interact with the
-application in order to execute the authentification and authorization
+application in order to execute the authentication and authorization
 processes. It is a classical callback mechanism: one retrieves information (i.e.
-for authentification purposes) and one display some messages (for example error
+for authentication purposes) and one display some messages (for example error
 messages).
 </p>
 <p>
@@ -17,6 +17,5 @@
 It contains only what was needed to make the compiler happy, that is, classes
 required by other packages. 
 </p>
-@since Android 1.0
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/auth/src/main/java/javax/security/auth/login/package.html b/auth/src/main/java/javax/security/auth/login/package.html
index 382b487..e270980 100644
--- a/auth/src/main/java/javax/security/auth/login/package.html
+++ b/auth/src/main/java/javax/security/auth/login/package.html
@@ -15,6 +15,5 @@
 It contains only what was needed to make the compiler happy, that is, classes
 required by other packages. 
 </p>
-@since Android 1.0
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/auth/src/main/java/javax/security/auth/package.html b/auth/src/main/java/javax/security/auth/package.html
index 2bca2db..aeaa6cc5 100644
--- a/auth/src/main/java/javax/security/auth/package.html
+++ b/auth/src/main/java/javax/security/auth/package.html
@@ -5,14 +5,13 @@
 <html>
 <body>
 <p>
-This package provides the classes and interfaces needed to implemenet and program
-different methods of users' authentification and role based users' authorization.
+This package provides the classes and interfaces needed to implement and program
+different methods of users' authentication and role based users' authorization.
 
-All subjects' authentification and role based authorization are strongly coupled with
+All subjects' authentication and role based authorization are strongly coupled with
 the java.security file that, as always, is the ultimate arbiter of all matters secure in Android.
 For example the class <i>javax.security.auth.SubjectDomainCombiner</i> updates the
 ProtectionDomains associated with the actual class with the subjects defined therein.
 </p>
-@since Android 1.0
 </body>
 </html>
diff --git a/auth/src/main/java/javax/security/auth/x500/package.html b/auth/src/main/java/javax/security/auth/x500/package.html
index 58d27ac..f7c484e 100644
--- a/auth/src/main/java/javax/security/auth/x500/package.html
+++ b/auth/src/main/java/javax/security/auth/x500/package.html
@@ -13,6 +13,5 @@
 It contains only what was needed to make the compiler happy, that is, classes
 required by other packages. 
 </p>
-@since Android 1.0
 </body>
 </html>
diff --git a/awt-kernel/src/main/java/java/awt/font/NumericShaper.java b/awt-kernel/src/main/java/java/awt/font/NumericShaper.java
index e8ea693..b170f25 100644
--- a/awt-kernel/src/main/java/java/awt/font/NumericShaper.java
+++ b/awt-kernel/src/main/java/java/awt/font/NumericShaper.java
@@ -22,13 +22,8 @@
 
 import java.io.IOException;
 import java.io.Serializable;
-
-// BEGIN android-deleted
-//import org.apache.harmony.awt.internal.nls.Messages;
-// END android-deleted
 import org.apache.harmony.misc.HashCode;
 
-
 /**
  * The Class NumericShaper provides methods to convert latin character codes
  * to unicode character codes.
@@ -467,10 +462,8 @@
      * @return one of the script indices according to the specified range.
      */
     private int getIndexFromRange(int range){
-        if (range == 0){
-            // BEGIN android-changed
-            throwRange(range);
-            // END android-changed
+        if (range == 0) {
+            throw rangeException(range);
         }
 
         int index = 0;
@@ -481,10 +474,7 @@
             index++;
         }
 
-        // BEGIN android-changed
-        throwRange(range);
-        return -1; // Never executed; quiets the compiler.
-        // END android-changed
+        throw rangeException(range);
     }
 
     /**
@@ -496,31 +486,16 @@
      */
     private int getRangeFromIndex(int index){
         if (index < 0 || index >= MAX_INDEX){
-            // BEGIN android-changed
-            throwRange(index);
-            // END android-changed
+            throw rangeException(index);
         }
 
         return 1 << index;
     }
 
-    // BEGIN android-added
-    /**
-     * Throws a standard "out of range" exception.
-     * 
-     * @param value the bogus value
-     */
-    private static void throwRange(int value) {
-        throw new IllegalArgumentException(
-                "Illegal range argument value: " + value);
+    private static IllegalArgumentException rangeException(int value) {
+        throw new IllegalArgumentException("Illegal range argument value: " + value);
     }
-    // END android-added
 
-    /**
-     * Returns a hash code of this NumericShaper.
-     * 
-     * @return a hash code of this NumericShaper.
-     */
     @Override
     public int hashCode() {
         HashCode hash = new HashCode();
@@ -533,14 +508,6 @@
 
     }
 
-    /**
-     * Compares this NumericShaper object with the specified Object.
-     * 
-     * @param obj the Object to be compared.
-     * 
-     * @return true, if this NumericShaper object is equal to
-     * the specified Object, false otherwise.
-     */
     @Override
     public boolean equals(Object obj) {
         if (obj == null) {
@@ -562,11 +529,6 @@
         return false;
     }
 
-    /**
-     * Returns a string representation of this NumericShaper.
-     * 
-     * @return the string representation of this NumericShaper.
-     */
     @Override
     public String toString() {
         /* !! There is no description in the documentation what this method must
diff --git a/awt-kernel/src/main/java/java/awt/font/TextAttribute.java b/awt-kernel/src/main/java/java/awt/font/TextAttribute.java
index aa1394a..0f00ae8 100644
--- a/awt-kernel/src/main/java/java/awt/font/TextAttribute.java
+++ b/awt-kernel/src/main/java/java/awt/font/TextAttribute.java
@@ -25,10 +25,6 @@
 import java.util.HashMap;
 import java.util.Map;
 
-// BEGIN android-deleted
-//import org.apache.harmony.awt.internal.nls.Messages;
-// END android-deleted
-
 /**
  * The TextAttribute class defines attribute keys and attribute values 
  * for text rendering. Each TextAttributes should have the following
@@ -73,9 +69,7 @@
         if (result != null) {
             return result;
         }
-        // BEGIN android-changed
         throw new InvalidObjectException("Unknown attribute name");
-        // END android-changed
     }
 
     /** 
@@ -137,13 +131,13 @@
      * The Constant RUN_DIRECTION_LTR indicates left-to-right run 
      * direction. 
      */
-    public static final Boolean RUN_DIRECTION_LTR = new Boolean(false);
+    public static final Boolean RUN_DIRECTION_LTR = false;
 
     /** 
      * The Constant RUN_DIRECTION_RTL indicates right-to-left run
      * direction. 
      */
-    public static final Boolean RUN_DIRECTION_RTL = new Boolean(true);
+    public static final Boolean RUN_DIRECTION_RTL = true;
 
     /** The SIZE text attribute. */
     public static final TextAttribute SIZE = new TextAttribute("size"); //$NON-NLS-1$
@@ -152,16 +146,16 @@
     public static final TextAttribute STRIKETHROUGH = new TextAttribute("strikethrough"); //$NON-NLS-1$
 
     /** The Constant STRIKETHROUGH_ON indicates a single strikethrough. */
-    public static final Boolean STRIKETHROUGH_ON = new Boolean(true);
+    public static final Boolean STRIKETHROUGH_ON = true;
 
     /** The SUPERSCRIPT text attribute. */
     public static final TextAttribute SUPERSCRIPT = new TextAttribute("superscript"); //$NON-NLS-1$
 
     /** The Constant SUPERSCRIPT_SUB indicates a standard subscript. */
-    public static final Integer SUPERSCRIPT_SUB = new Integer(-1);
+    public static final Integer SUPERSCRIPT_SUB = -1;
 
     /** The Constant SUPERSCRIPT_SUPER indicates a standard superscript. */
-    public static final Integer SUPERSCRIPT_SUPER = new Integer(1);
+    public static final Integer SUPERSCRIPT_SUPER = 1;
 
     /** The SWAP_COLORS text attribute. */
     public static final TextAttribute SWAP_COLORS = new TextAttribute("swap_colors"); //$NON-NLS-1$
@@ -170,7 +164,7 @@
      * The Constant SWAP_COLORS_ON indicates a swap of foreground 
      * and background.
      */
-    public static final Boolean SWAP_COLORS_ON = new Boolean(true);
+    public static final Boolean SWAP_COLORS_ON = true;
 
     /** The TRANSFORM text attribute. */
     public static final TextAttribute TRANSFORM = new TextAttribute("transform"); //$NON-NLS-1$
@@ -182,37 +176,37 @@
      * The Constant UNDERLINE_ON indicates a standard underline 
      * at the roman baseline for roman text.
      */
-    public static final Integer UNDERLINE_ON = new Integer(0);
+    public static final Integer UNDERLINE_ON = 0;
 
     /** 
      * The Constant UNDERLINE_LOW_ONE_PIXEL indicates a single 
      * pixel solid low underline. 
      */
-    public static final Integer UNDERLINE_LOW_ONE_PIXEL = new Integer(1);
+    public static final Integer UNDERLINE_LOW_ONE_PIXEL = 1;
 
     /** 
      * The Constant UNDERLINE_LOW_TWO_PIXEL indicates a double 
      * pixel solid low underline. 
      */
-    public static final Integer UNDERLINE_LOW_TWO_PIXEL = new Integer(2);
+    public static final Integer UNDERLINE_LOW_TWO_PIXEL = 2;
 
     /** 
      * The Constant UNDERLINE_LOW_DOTTED indicates a 
      * single pixel dotted low underline. 
      */
-    public static final Integer UNDERLINE_LOW_DOTTED = new Integer(3);
+    public static final Integer UNDERLINE_LOW_DOTTED = 3;
 
     /** 
      * The Constant UNDERLINE_LOW_GRAY indicates double pixel 
      * gray low underline. 
      */
-    public static final Integer UNDERLINE_LOW_GRAY = new Integer(4);
+    public static final Integer UNDERLINE_LOW_GRAY = 4;
 
     /** 
      * The Constant UNDERLINE_LOW_DASHED indicates single pixel dashed 
      * low underline. 
      */
-    public static final Integer UNDERLINE_LOW_DASHED = new Integer(5);
+    public static final Integer UNDERLINE_LOW_DASHED = 5;
 
     /** The WEIGHT text attribute. */
     public static final TextAttribute WEIGHT = new TextAttribute("weight"); //$NON-NLS-1$
diff --git a/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java b/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java
index 5bd4b2e..f52d6e6 100644
--- a/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java
+++ b/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java
@@ -20,8 +20,6 @@
 /**
  * A type of {@link PropertyChangeEvent} that indicates that an indexed property
  * has changed.
- * 
- * @since Android 1.0
  */
 public class IndexedPropertyChangeEvent extends PropertyChangeEvent {
 
diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java b/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java
index 04caed8..d614be3 100644
--- a/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java
+++ b/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java
@@ -22,8 +22,6 @@
 /**
  * An event that indicates that a constraint or a boundary of a property has
  * changed.
- * 
- * @since Android 1.0
  */
 public class PropertyChangeEvent extends EventObject {
 
diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java b/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java
index 2515792..a0a4201 100644
--- a/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java
+++ b/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java
@@ -22,8 +22,6 @@
 /**
  * A PropertyChangeListener can subscribe with a event source. Whenever that
  * source raises a PropertyChangeEvent this listener will get notified.
- * 
- * @since Android 1.0
  */
 public interface PropertyChangeListener extends EventListener {
 
diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java b/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java
index d27e4eb..4841b72 100644
--- a/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java
+++ b/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java
@@ -22,8 +22,6 @@
 /**
  * The implementation of this listener proxy just delegates the received events
  * to its listener.
- * 
- * @since Android 1.0
  */
 public class PropertyChangeListenerProxy extends EventListenerProxy implements
         PropertyChangeListener {
diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java b/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java
index 9225d95..32e2da6 100644
--- a/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java
+++ b/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java
@@ -266,7 +266,7 @@
 
         if (oldValue != newValue) {
             fireIndexedPropertyChange(propertyName, index,
-                    new Integer(oldValue), new Integer(newValue));
+                    Integer.valueOf(oldValue), Integer.valueOf(newValue));
         }
     }
 
diff --git a/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java b/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
index f7ed15c..a7c8fe5 100644
--- a/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
+++ b/concurrent/src/main/java/java/util/concurrent/AbstractExecutorService.java
@@ -10,26 +10,74 @@
 /**
  * Provides default implementations of {@link ExecutorService}
  * execution methods. This class implements the <tt>submit</tt>,
- * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using the default
- * {@link FutureTask} class provided in this package.  For example,
+ * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a
+ * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults
+ * to the {@link FutureTask} class provided in this package.  For example,
  * the implementation of <tt>submit(Runnable)</tt> creates an
- * associated <tt>FutureTask</tt> that is executed and
- * returned. Subclasses overriding these methods to use different
- * {@link Future} implementations should do so consistently for each
- * of these methods.
+ * associated <tt>RunnableFuture</tt> that is executed and
+ * returned. Subclasses may override the <tt>newTaskFor</tt> methods
+ * to return <tt>RunnableFuture</tt> implementations other than
+ * <tt>FutureTask</tt>.
  *
+ * <p> <b>Extension example</b>. Here is a sketch of a class
+ * that customizes {@link ThreadPoolExecutor} to use
+ * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
+ * <pre>
+ * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
+ *
+ *   static class CustomTask&lt;V&gt; implements RunnableFuture&lt;V&gt; {...}
+ *
+ *   protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Callable&lt;V&gt; c) {
+ *       return new CustomTask&lt;V&gt;(c);
+ *   }
+ *   protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Runnable r, V v) {
+ *       return new CustomTask&lt;V&gt;(r, v);
+ *   }
+ *   // ... add constructors, etc.
+ * }
+ * </pre>
  * @since 1.5
  * @author Doug Lea
  */
 public abstract class AbstractExecutorService implements ExecutorService {
 
     /**
+     * Returns a <tt>RunnableFuture</tt> for the given runnable and default
+     * value.
+     *
+     * @param runnable the runnable task being wrapped
+     * @param value the default value for the returned future
+     * @return a <tt>RunnableFuture</tt> which when run will run the
+     * underlying runnable and which, as a <tt>Future</tt>, will yield
+     * the given value as its result and provide for cancellation of
+     * the underlying task.
+     * @since 1.6
+     */
+    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
+        return new FutureTask<T>(runnable, value);
+    }
+
+    /**
+     * Returns a <tt>RunnableFuture</tt> for the given callable task.
+     *
+     * @param callable the callable task being wrapped
+     * @return a <tt>RunnableFuture</tt> which when run will call the
+     * underlying callable and which, as a <tt>Future</tt>, will yield
+     * the callable's result as its result and provide for
+     * cancellation of the underlying task.
+     * @since 1.6
+     */
+    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
+        return new FutureTask<T>(callable);
+    }
+
+    /**
      * @throws RejectedExecutionException {@inheritDoc}
      * @throws NullPointerException       {@inheritDoc}
      */
     public Future<?> submit(Runnable task) {
         if (task == null) throw new NullPointerException();
-        FutureTask<Object> ftask = new FutureTask<Object>(task, null);
+        RunnableFuture<Object> ftask = newTaskFor(task, null);
         execute(ftask);
         return ftask;
     }
@@ -40,7 +88,7 @@
      */
     public <T> Future<T> submit(Runnable task, T result) {
         if (task == null) throw new NullPointerException();
-        FutureTask<T> ftask = new FutureTask<T>(task, result);
+        RunnableFuture<T> ftask = newTaskFor(task, result);
         execute(ftask);
         return ftask;
     }
@@ -51,7 +99,7 @@
      */
     public <T> Future<T> submit(Callable<T> task) {
         if (task == null) throw new NullPointerException();
-        FutureTask<T> ftask = new FutureTask<T>(task);
+        RunnableFuture<T> ftask = newTaskFor(task);
         execute(ftask);
         return ftask;
     }
@@ -59,7 +107,7 @@
     /**
      * the main mechanics of invokeAny.
      */
-    private <T> T doInvokeAny(Collection<Callable<T>> tasks,
+    private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
                             boolean timed, long nanos)
         throws InterruptedException, ExecutionException, TimeoutException {
         if (tasks == null)
@@ -82,7 +130,7 @@
             // result, we can throw the last exception we got.
             ExecutionException ee = null;
             long lastTime = (timed)? System.nanoTime() : 0;
-            Iterator<Callable<T>> it = tasks.iterator();
+            Iterator<? extends Callable<T>> it = tasks.iterator();
 
             // Start one task for sure; the rest incrementally
             futures.add(ecs.submit(it.next()));
@@ -134,7 +182,7 @@
         }
     }
 
-    public <T> T invokeAny(Collection<Callable<T>> tasks)
+    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
         throws InterruptedException, ExecutionException {
         try {
             return doInvokeAny(tasks, false, 0);
@@ -144,13 +192,13 @@
         }
     }
 
-    public <T> T invokeAny(Collection<Callable<T>> tasks,
+    public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                            long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
         return doInvokeAny(tasks, true, unit.toNanos(timeout));
     }
 
-    public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
+    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
         throws InterruptedException {
         if (tasks == null)
             throw new NullPointerException();
@@ -158,7 +206,7 @@
         boolean done = false;
         try {
             for (Callable<T> t : tasks) {
-                FutureTask<T> f = new FutureTask<T>(t);
+                RunnableFuture<T> f = newTaskFor(t);
                 futures.add(f);
                 execute(f);
             }
@@ -180,7 +228,7 @@
         }
     }
 
-    public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                          long timeout, TimeUnit unit)
         throws InterruptedException {
         if (tasks == null || unit == null)
@@ -190,7 +238,7 @@
         boolean done = false;
         try {
             for (Callable<T> t : tasks)
-                futures.add(new FutureTask<T>(t));
+                futures.add(newTaskFor(t));
 
             long lastTime = System.nanoTime();
 
diff --git a/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
index 0082f07..1c6f613 100644
--- a/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
+++ b/concurrent/src/main/java/java/util/concurrent/ArrayBlockingQueue.java
@@ -189,8 +189,8 @@
         if (capacity < c.size())
             throw new IllegalArgumentException();
 
-        for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
-            add(it.next());
+        for (E e : c)
+            add(e);
     }
 
     /**
diff --git a/concurrent/src/main/java/java/util/concurrent/BlockingDeque.java b/concurrent/src/main/java/java/util/concurrent/BlockingDeque.java
new file mode 100644
index 0000000..d77a965
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/BlockingDeque.java
@@ -0,0 +1,613 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+
+/**
+ * A {@link Deque} that additionally supports blocking operations that wait
+ * for the deque to become non-empty when retrieving an element, and wait for
+ * space to become available in the deque when storing an element.
+ *
+ * <p><tt>BlockingDeque</tt> methods come in four forms, with different ways
+ * of handling operations that cannot be satisfied immediately, but may be
+ * satisfied at some point in the future:
+ * one throws an exception, the second returns a special value (either
+ * <tt>null</tt> or <tt>false</tt>, depending on the operation), the third
+ * blocks the current thread indefinitely until the operation can succeed,
+ * and the fourth blocks for only a given maximum time limit before giving
+ * up.  These methods are summarized in the following table:
+ *
+ * <p>
+ * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ *  <tr>
+ *    <td ALIGN=CENTER COLSPAN = 5> <b>First Element (Head)</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td></td>
+ *    <td ALIGN=CENTER><em>Throws exception</em></td>
+ *    <td ALIGN=CENTER><em>Special value</em></td>
+ *    <td ALIGN=CENTER><em>Blocks</em></td>
+ *    <td ALIGN=CENTER><em>Times out</em></td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Insert</b></td>
+ *    <td>{@link #addFirst addFirst(e)}</td>
+ *    <td>{@link #offerFirst(Object) offerFirst(e)}</td>
+ *    <td>{@link #putFirst putFirst(e)}</td>
+ *    <td>{@link #offerFirst(Object, long, TimeUnit) offerFirst(e, time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Remove</b></td>
+ *    <td>{@link #removeFirst removeFirst()}</td>
+ *    <td>{@link #pollFirst pollFirst()}</td>
+ *    <td>{@link #takeFirst takeFirst()}</td>
+ *    <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Examine</b></td>
+ *    <td>{@link #getFirst getFirst()}</td>
+ *    <td>{@link #peekFirst peekFirst()}</td>
+ *    <td><em>not applicable</em></td>
+ *    <td><em>not applicable</em></td>
+ *  </tr>
+ *  <tr>
+ *    <td ALIGN=CENTER COLSPAN = 5> <b>Last Element (Tail)</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td></td>
+ *    <td ALIGN=CENTER><em>Throws exception</em></td>
+ *    <td ALIGN=CENTER><em>Special value</em></td>
+ *    <td ALIGN=CENTER><em>Blocks</em></td>
+ *    <td ALIGN=CENTER><em>Times out</em></td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Insert</b></td>
+ *    <td>{@link #addLast addLast(e)}</td>
+ *    <td>{@link #offerLast(Object) offerLast(e)}</td>
+ *    <td>{@link #putLast putLast(e)}</td>
+ *    <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Remove</b></td>
+ *    <td>{@link #removeLast() removeLast()}</td>
+ *    <td>{@link #pollLast() pollLast()}</td>
+ *    <td>{@link #takeLast takeLast()}</td>
+ *    <td>{@link #pollLast(long, TimeUnit) pollLast(time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td><b>Examine</b></td>
+ *    <td>{@link #getLast getLast()}</td>
+ *    <td>{@link #peekLast peekLast()}</td>
+ *    <td><em>not applicable</em></td>
+ *    <td><em>not applicable</em></td>
+ *  </tr>
+ * </table>
+ *
+ * <p>Like any {@link BlockingQueue}, a <tt>BlockingDeque</tt> is thread safe,
+ * does not permit null elements, and may (or may not) be
+ * capacity-constrained.
+ *
+ * <p>A <tt>BlockingDeque</tt> implementation may be used directly as a FIFO
+ * <tt>BlockingQueue</tt>. The methods inherited from the
+ * <tt>BlockingQueue</tt> interface are precisely equivalent to
+ * <tt>BlockingDeque</tt> methods as indicated in the following table:
+ *
+ * <p>
+ * <table BORDER CELLPADDING=3 CELLSPACING=1>
+ *  <tr>
+ *    <td ALIGN=CENTER> <b><tt>BlockingQueue</tt> Method</b></td>
+ *    <td ALIGN=CENTER> <b>Equivalent <tt>BlockingDeque</tt> Method</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td ALIGN=CENTER COLSPAN = 2> <b>Insert</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #add(Object) add(e)}</td>
+ *    <td>{@link #addLast(Object) addLast(e)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #offer(Object) offer(e)}</td>
+ *    <td>{@link #offerLast(Object) offerLast(e)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #put(Object) put(e)}</td>
+ *    <td>{@link #putLast(Object) putLast(e)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
+ *    <td>{@link #offerLast(Object, long, TimeUnit) offerLast(e, time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td ALIGN=CENTER COLSPAN = 2> <b>Remove</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #remove() remove()}</td>
+ *    <td>{@link #removeFirst() removeFirst()}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #poll() poll()}</td>
+ *    <td>{@link #pollFirst() pollFirst()}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #take() take()}</td>
+ *    <td>{@link #takeFirst() takeFirst()}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #poll(long, TimeUnit) poll(time, unit)}</td>
+ *    <td>{@link #pollFirst(long, TimeUnit) pollFirst(time, unit)}</td>
+ *  </tr>
+ *  <tr>
+ *    <td ALIGN=CENTER COLSPAN = 2> <b>Examine</b></td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #element() element()}</td>
+ *    <td>{@link #getFirst() getFirst()}</td>
+ *  </tr>
+ *  <tr>
+ *    <td>{@link #peek() peek()}</td>
+ *    <td>{@link #peekFirst() peekFirst()}</td>
+ *  </tr>
+ * </table>
+ *
+ * <p>Memory consistency effects: As with other concurrent
+ * collections, actions in a thread prior to placing an object into a
+ * {@code BlockingDeque}
+ * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
+ * actions subsequent to the access or removal of that element from
+ * the {@code BlockingDeque} in another thread.
+ *
+ * <p>This interface is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.6
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> {
+    /*
+     * We have "diamond" multiple interface inheritance here, and that
+     * introduces ambiguities.  Methods might end up with different
+     * specs depending on the branch chosen by javadoc.  Thus a lot of
+     * methods specs here are copied from superinterfaces.
+     */
+
+    /**
+     * Inserts the specified element at the front of this deque if it is
+     * possible to do so immediately without violating capacity restrictions,
+     * throwing an <tt>IllegalStateException</tt> if no space is currently
+     * available.  When using a capacity-restricted deque, it is generally
+     * preferable to use {@link #offerFirst(Object) offerFirst}.
+     *
+     * @param e the element to add
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    void addFirst(E e);
+
+    /**
+     * Inserts the specified element at the end of this deque if it is
+     * possible to do so immediately without violating capacity restrictions,
+     * throwing an <tt>IllegalStateException</tt> if no space is currently
+     * available.  When using a capacity-restricted deque, it is generally
+     * preferable to use {@link #offerLast(Object) offerLast}.
+     *
+     * @param e the element to add
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    void addLast(E e);
+
+    /**
+     * Inserts the specified element at the front of this deque if it is
+     * possible to do so immediately without violating capacity restrictions,
+     * returning <tt>true</tt> upon success and <tt>false</tt> if no space is
+     * currently available.
+     * When using a capacity-restricted deque, this method is generally
+     * preferable to the {@link #addFirst(Object) addFirst} method, which can
+     * fail to insert an element only by throwing an exception.
+     *
+     * @param e the element to add
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    boolean offerFirst(E e);
+
+    /**
+     * Inserts the specified element at the end of this deque if it is
+     * possible to do so immediately without violating capacity restrictions,
+     * returning <tt>true</tt> upon success and <tt>false</tt> if no space is
+     * currently available.
+     * When using a capacity-restricted deque, this method is generally
+     * preferable to the {@link #addLast(Object) addLast} method, which can
+     * fail to insert an element only by throwing an exception.
+     *
+     * @param e the element to add
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    boolean offerLast(E e);
+
+    /**
+     * Inserts the specified element at the front of this deque,
+     * waiting if necessary for space to become available.
+     *
+     * @param e the element to add
+     * @throws InterruptedException if interrupted while waiting
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    void putFirst(E e) throws InterruptedException;
+
+    /**
+     * Inserts the specified element at the end of this deque,
+     * waiting if necessary for space to become available.
+     *
+     * @param e the element to add
+     * @throws InterruptedException if interrupted while waiting
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    void putLast(E e) throws InterruptedException;
+
+    /**
+     * Inserts the specified element at the front of this deque,
+     * waiting up to the specified wait time if necessary for space to
+     * become available.
+     *
+     * @param e the element to add
+     * @param timeout how long to wait before giving up, in units of
+     *        <tt>unit</tt>
+     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+     *        <tt>timeout</tt> parameter
+     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     *         the specified waiting time elapses before space is available
+     * @throws InterruptedException if interrupted while waiting
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    boolean offerFirst(E e, long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Inserts the specified element at the end of this deque,
+     * waiting up to the specified wait time if necessary for space to
+     * become available.
+     *
+     * @param e the element to add
+     * @param timeout how long to wait before giving up, in units of
+     *        <tt>unit</tt>
+     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+     *        <tt>timeout</tt> parameter
+     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     *         the specified waiting time elapses before space is available
+     * @throws InterruptedException if interrupted while waiting
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    boolean offerLast(E e, long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Retrieves and removes the first element of this deque, waiting
+     * if necessary until an element becomes available.
+     *
+     * @return the head of this deque
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E takeFirst() throws InterruptedException;
+
+    /**
+     * Retrieves and removes the last element of this deque, waiting
+     * if necessary until an element becomes available.
+     *
+     * @return the tail of this deque
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E takeLast() throws InterruptedException;
+
+    /**
+     * Retrieves and removes the first element of this deque, waiting
+     * up to the specified wait time if necessary for an element to
+     * become available.
+     *
+     * @param timeout how long to wait before giving up, in units of
+     *        <tt>unit</tt>
+     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+     *        <tt>timeout</tt> parameter
+     * @return the head of this deque, or <tt>null</tt> if the specified
+     *         waiting time elapses before an element is available
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E pollFirst(long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Retrieves and removes the last element of this deque, waiting
+     * up to the specified wait time if necessary for an element to
+     * become available.
+     *
+     * @param timeout how long to wait before giving up, in units of
+     *        <tt>unit</tt>
+     * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+     *        <tt>timeout</tt> parameter
+     * @return the tail of this deque, or <tt>null</tt> if the specified
+     *         waiting time elapses before an element is available
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E pollLast(long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Removes the first occurrence of the specified element from this deque.
+     * If the deque does not contain the element, it is unchanged.
+     * More formally, removes the first element <tt>e</tt> such that
+     * <tt>o.equals(e)</tt> (if such an element exists).
+     * Returns <tt>true</tt> if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
+     *
+     * @param o element to be removed from this deque, if present
+     * @return <tt>true</tt> if an element was removed as a result of this call
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this deque (optional)
+     * @throws NullPointerException if the specified element is null (optional)
+     */
+    boolean removeFirstOccurrence(Object o);
+
+    /**
+     * Removes the last occurrence of the specified element from this deque.
+     * If the deque does not contain the element, it is unchanged.
+     * More formally, removes the last element <tt>e</tt> such that
+     * <tt>o.equals(e)</tt> (if such an element exists).
+     * Returns <tt>true</tt> if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
+     *
+     * @param o element to be removed from this deque, if present
+     * @return <tt>true</tt> if an element was removed as a result of this call
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this deque (optional)
+     * @throws NullPointerException if the specified element is null (optional)
+     */
+    boolean removeLastOccurrence(Object o);
+
+    // *** BlockingQueue methods ***
+
+    /**
+     * Inserts the specified element into the queue represented by this deque
+     * (in other words, at the tail of this deque) if it is possible to do so
+     * immediately without violating capacity restrictions, returning
+     * <tt>true</tt> upon success and throwing an
+     * <tt>IllegalStateException</tt> if no space is currently available.
+     * When using a capacity-restricted deque, it is generally preferable to
+     * use {@link #offer(Object) offer}.
+     *
+     * <p>This method is equivalent to {@link #addLast(Object) addLast}.
+     *
+     * @param e the element to add
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    boolean add(E e);
+
+    /**
+     * Inserts the specified element into the queue represented by this deque
+     * (in other words, at the tail of this deque) if it is possible to do so
+     * immediately without violating capacity restrictions, returning
+     * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+     * available.  When using a capacity-restricted deque, this method is
+     * generally preferable to the {@link #add} method, which can fail to
+     * insert an element only by throwing an exception.
+     *
+     * <p>This method is equivalent to {@link #offerLast(Object) offerLast}.
+     *
+     * @param e the element to add
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    boolean offer(E e);
+
+    /**
+     * Inserts the specified element into the queue represented by this deque
+     * (in other words, at the tail of this deque), waiting if necessary for
+     * space to become available.
+     *
+     * <p>This method is equivalent to {@link #putLast(Object) putLast}.
+     *
+     * @param e the element to add
+     * @throws InterruptedException {@inheritDoc}
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    void put(E e) throws InterruptedException;
+
+    /**
+     * Inserts the specified element into the queue represented by this deque
+     * (in other words, at the tail of this deque), waiting up to the
+     * specified wait time if necessary for space to become available.
+     *
+     * <p>This method is equivalent to
+     * {@link #offerLast(Object,long,TimeUnit) offerLast}.
+     *
+     * @param e the element to add
+     * @return <tt>true</tt> if the element was added to this deque, else
+     *         <tt>false</tt>
+     * @throws InterruptedException {@inheritDoc}
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this deque
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException if some property of the specified
+     *         element prevents it from being added to this deque
+     */
+    boolean offer(E e, long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Retrieves and removes the head of the queue represented by this deque
+     * (in other words, the first element of this deque).
+     * This method differs from {@link #poll poll} only in that it
+     * throws an exception if this deque is empty.
+     *
+     * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
+     *
+     * @return the head of the queue represented by this deque
+     * @throws NoSuchElementException if this deque is empty
+     */
+    E remove();
+
+    /**
+     * Retrieves and removes the head of the queue represented by this deque
+     * (in other words, the first element of this deque), or returns
+     * <tt>null</tt> if this deque is empty.
+     *
+     * <p>This method is equivalent to {@link #pollFirst()}.
+     *
+     * @return the head of this deque, or <tt>null</tt> if this deque is empty
+     */
+    E poll();
+
+    /**
+     * Retrieves and removes the head of the queue represented by this deque
+     * (in other words, the first element of this deque), waiting if
+     * necessary until an element becomes available.
+     *
+     * <p>This method is equivalent to {@link #takeFirst() takeFirst}.
+     *
+     * @return the head of this deque
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E take() throws InterruptedException;
+
+    /**
+     * Retrieves and removes the head of the queue represented by this deque
+     * (in other words, the first element of this deque), waiting up to the
+     * specified wait time if necessary for an element to become available.
+     *
+     * <p>This method is equivalent to
+     * {@link #pollFirst(long,TimeUnit) pollFirst}.
+     *
+     * @return the head of this deque, or <tt>null</tt> if the
+     *         specified waiting time elapses before an element is available
+     * @throws InterruptedException if interrupted while waiting
+     */
+    E poll(long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Retrieves, but does not remove, the head of the queue represented by
+     * this deque (in other words, the first element of this deque).
+     * This method differs from {@link #peek peek} only in that it throws an
+     * exception if this deque is empty.
+     *
+     * <p>This method is equivalent to {@link #getFirst() getFirst}.
+     *
+     * @return the head of this deque
+     * @throws NoSuchElementException if this deque is empty
+     */
+    E element();
+
+    /**
+     * Retrieves, but does not remove, the head of the queue represented by
+     * this deque (in other words, the first element of this deque), or
+     * returns <tt>null</tt> if this deque is empty.
+     *
+     * <p>This method is equivalent to {@link #peekFirst() peekFirst}.
+     *
+     * @return the head of this deque, or <tt>null</tt> if this deque is empty
+     */
+    E peek();
+
+    /**
+     * Removes the first occurrence of the specified element from this deque.
+     * If the deque does not contain the element, it is unchanged.
+     * More formally, removes the first element <tt>e</tt> such that
+     * <tt>o.equals(e)</tt> (if such an element exists).
+     * Returns <tt>true</tt> if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
+     *
+     * <p>This method is equivalent to
+     * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return <tt>true</tt> if this deque changed as a result of the call
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this deque (optional)
+     * @throws NullPointerException if the specified element is null (optional)
+     */
+    boolean remove(Object o);
+
+    /**
+     * Returns <tt>true</tt> if this deque contains the specified element.
+     * More formally, returns <tt>true</tt> if and only if this deque contains
+     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     *
+     * @param o object to be checked for containment in this deque
+     * @return <tt>true</tt> if this deque contains the specified element
+     * @throws ClassCastException if the class of the specified element
+     *         is incompatible with this deque (optional)
+     * @throws NullPointerException if the specified element is null (optional)
+     */
+    public boolean contains(Object o);
+
+    /**
+     * Returns the number of elements in this deque.
+     *
+     * @return the number of elements in this deque
+     */
+    public int size();
+
+    /**
+     * Returns an iterator over the elements in this deque in proper sequence.
+     * The elements will be returned in order from first (head) to last (tail).
+     *
+     * @return an iterator over the elements in this deque in proper sequence
+     */
+    Iterator<E> iterator();
+
+    // *** Stack methods ***
+
+    /**
+     * Pushes an element onto the stack represented by this deque.  In other
+     * words, inserts the element at the front of this deque unless it would
+     * violate capacity restrictions.
+     *
+     * <p>This method is equivalent to {@link #addFirst(Object) addFirst}.
+     *
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    void push(E e);
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
index d01c097..85945b9 100644
--- a/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
+++ b/concurrent/src/main/java/java/util/concurrent/BlockingQueue.java
@@ -42,7 +42,7 @@
  *    <td>{@link #add add(e)}</td>
  *    <td>{@link #offer offer(e)}</td>
  *    <td>{@link #put put(e)}</td>
- *    <td>{@link #offer offer(e, time, unit)}</td>
+ *    <td>{@link #offer(Object, long, TimeUnit) offer(e, time, unit)}</td>
  *  </tr>
  *  <tr>
  *    <td><b>Remove</b></td>
@@ -156,7 +156,7 @@
      * <tt>true</tt> upon success and throwing an
      * <tt>IllegalStateException</tt> if no space is currently available.
      * When using a capacity-restricted queue, it is generally preferable to
-     * use {@link #offer offer}.
+     * use {@link #offer(Object) offer}.
      *
      * @param e the element to add
      * @return <tt>true</tt> (as specified by {@link Collection#add})
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
index cb5fb3f..1c157b4 100644
--- a/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentHashMap.java
@@ -613,6 +613,24 @@
     }
 
     /**
+     * Creates a new, empty map with the specified initial capacity
+     * and load factor and with the default concurrencyLevel (16).
+     *
+     * @param initialCapacity The implementation performs internal
+     * sizing to accommodate this many elements.
+     * @param loadFactor  the load factor threshold, used to control resizing.
+     * Resizing may be performed when the average number of elements per
+     * bin exceeds this threshold.
+     * @throws IllegalArgumentException if the initial capacity of
+     * elements is negative or the load factor is nonpositive
+     *
+     * @since 1.6
+     */
+    public ConcurrentHashMap(int initialCapacity, float loadFactor) {
+        this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
+    }
+
+    /**
      * Creates a new, empty map with the specified initial capacity,
      * and with default load factor (0.75) and concurrencyLevel (16).
      *
@@ -1112,7 +1130,7 @@
      * setValue changes to the underlying map.
      */
     final class WriteThroughEntry
-        extends SimpleEntry<K,V>
+        extends AbstractMap.SimpleEntry<K,V>
     {
         WriteThroughEntry(K k, V v) {
             super(k,v);
@@ -1212,60 +1230,7 @@
         }
     }
 
-    /**
-     * This duplicates java.util.AbstractMap.SimpleEntry until this class
-     * is made accessible.
-     */
-    static class SimpleEntry<K,V> implements Entry<K,V> {
-        K key;
-        V value;
-
-        public SimpleEntry(K key, V value) {
-            this.key   = key;
-            this.value = value;
-        }
-
-        public SimpleEntry(Entry<K,V> e) {
-            this.key   = e.getKey();
-            this.value = e.getValue();
-        }
-
-        public K getKey() {
-            return key;
-        }
-
-        public V getValue() {
-            return value;
-        }
-
-        public V setValue(V value) {
-            V oldValue = this.value;
-            this.value = value;
-            return oldValue;
-        }
-
-        public boolean equals(Object o) {
-            if (!(o instanceof Map.Entry))
-                return false;
-            Map.Entry e = (Map.Entry)o;
-            return eq(key, e.getKey()) && eq(value, e.getValue());
-        }
-
-        public int hashCode() {
-            return ((key   == null)   ? 0 :   key.hashCode()) ^
-                    ((value == null)   ? 0 : value.hashCode());
-        }
-
-        public String toString() {
-            return key + "=" + value;
-        }
-
-        static boolean eq(Object o1, Object o2) {
-            return (o1 == null ? o2 == null : o1.equals(o2));
-        }
-    }
-
-   /* ---------------- Serialization Support -------------- */
+    /* ---------------- Serialization Support -------------- */
 
     /**
      * Save the state of the <tt>ConcurrentHashMap</tt> instance to a
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
new file mode 100644
index 0000000..ee3534e
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedDeque.java
@@ -0,0 +1,1246 @@
+/*
+ * Written by Doug Lea and Martin Buchholz with assistance from members of
+ * JCP JSR-166 Expert Group and released to the public domain, as explained
+ * at http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.ConcurrentModificationException;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A concurrent linked-list implementation of a {@link Deque}
+ * (double-ended queue).  Concurrent insertion, removal, and access
+ * operations execute safely across multiple threads. Iterators are
+ * <i>weakly consistent</i>, returning elements reflecting the state
+ * of the deque at some point at or since the creation of the
+ * iterator.  They do <em>not</em> throw {@link
+ * ConcurrentModificationException}, and may proceed concurrently with
+ * other operations.
+ *
+ * <p>This class and its iterators implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces. Like most other concurrent collection
+ * implementations, this class does not permit the use of
+ * {@code null} elements.  because some null arguments and return
+ * values cannot be reliably distinguished from the absence of
+ * elements. Arbitrarily, the {@link Collection#remove} method is
+ * mapped to {@code removeFirstOccurrence}, and {@link
+ * Collection#add} is mapped to {@code addLast}.
+ *
+ * <p>Beware that, unlike in most collections, the {@code size}
+ * method is <em>NOT</em> a constant-time operation. Because of the
+ * asynchronous nature of these deques, determining the current number
+ * of elements requires a traversal of the elements.
+ *
+ * <p>This class is {@code Serializable}, but relies on default
+ * serialization mechanisms.  Usually, it is a better idea for any
+ * serializable class using a {@code ConcurrentLinkedDeque} to instead
+ * serialize a snapshot of the elements obtained by method
+ * {@code toArray}.
+ *
+ * @author  Doug Lea
+ * @author  Martin Buchholz
+ * @param <E> the type of elements held in this collection
+ */
+
+public class ConcurrentLinkedDeque<E>
+    extends AbstractCollection<E>
+    implements Deque<E>, java.io.Serializable {
+
+    /*
+     * This is an implementation of a concurrent lock-free deque
+     * supporting interior removes but not interior insertions, as
+     * required to fully support the Deque interface.
+     *
+     * We extend the techniques developed for
+     * ConcurrentLinkedQueue and LinkedTransferQueue
+     * (see the internal docs for those classes).
+     *
+     * At any time, there is precisely one "first" active node with a
+     * null prev pointer.  Similarly there is one "last" active node
+     * with a null next pointer.  New nodes are simply enqueued by
+     * null-CASing.
+     *
+     * A node p is considered "active" if it either contains an
+     * element, or is an end node and neither next nor prev pointers
+     * are self-links:
+     *
+     * p.item != null ||
+     * (p.prev == null && p.next != p) ||
+     * (p.next == null && p.prev != p)
+     *
+     * The head and tail pointers are only approximations to the start
+     * and end of the deque.  The first node can always be found by
+     * following prev pointers from head; likewise for tail.  However,
+     * head and tail may be pointing at deleted nodes that have been
+     * unlinked and so may not be reachable from any live node.
+     *
+     * There are 3 levels of node deletion:
+     * - logical deletion atomically removes the element
+     * - "unlinking" makes a deleted node unreachable from active
+     *   nodes, and thus eventually reclaimable by GC
+     * - "gc-unlinking" further does the reverse of making active
+     *   nodes unreachable from deleted nodes, making it easier for
+     *   the GC to reclaim future deleted nodes
+     *
+     * TODO: find a better name for "gc-unlinked"
+     *
+     * Logical deletion of a node simply involves CASing its element
+     * to null.  Physical deletion is merely an optimization (albeit a
+     * critical one), and can be performed at our convenience.  At any
+     * time, the set of non-logically-deleted nodes maintained by prev
+     * and next links are identical, that is the live elements found
+     * via next links from the first node is equal to the elements
+     * found via prev links from the last node.  However, this is not
+     * true for nodes that have already been logically deleted - such
+     * nodes may only be reachable in one direction.
+     *
+     * When a node is dequeued at either end, e.g. via poll(), we
+     * would like to break any references from the node to live nodes,
+     * to stop old garbage from causing retention of new garbage with
+     * a generational or conservative GC.  We develop further the
+     * self-linking trick that was very effective in other concurrent
+     * collection classes.  The idea is to replace prev and next
+     * pointers to active nodes with special values that are
+     * interpreted to mean off-the-list-at-one-end.  These are
+     * approximations, but good enough to preserve the properties we
+     * want in our traversals, e.g. we guarantee that a traversal will
+     * never hit the same element twice, but we don't guarantee
+     * whether a traversal that runs out of elements will be able to
+     * see more elements later after more elements are added at that
+     * end.  Doing gc-unlinking safely is particularly tricky, since
+     * any node can be in use indefinitely (for example by an
+     * iterator).  We must make sure that the nodes pointed at by
+     * head/tail do not get gc-unlinked, since head/tail are needed to
+     * get "back on track" by other nodes that are gc-unlinked.
+     * gc-unlinking accounts for much of the implementation complexity.
+     *
+     * Since neither unlinking nor gc-unlinking are necessary for
+     * correctness, there are many implementation choices regarding
+     * frequency (eagerness) of these operations.  Since volatile
+     * reads are likely to be much cheaper than CASes, saving CASes by
+     * unlinking multiple adjacent nodes at a time may be a win.
+     * gc-unlinking can be performed rarely and still be effective,
+     * since it is most important that long chains of deleted nodes
+     * are occasionally broken.
+     *
+     * The actual representation we use is that p.next == p means to
+     * goto the first node, and p.next == null && p.prev == p means
+     * that the iteration is at an end and that p is a (final static)
+     * dummy node, NEXT_TERMINATOR, and not the last active node.
+     * Finishing the iteration when encountering such a TERMINATOR is
+     * good enough for read-only traversals.  When the last active
+     * node is desired, for example when enqueueing, goto tail and
+     * continue traversal.
+     *
+     * The implementation is completely directionally symmetrical,
+     * except that most public methods that iterate through the list
+     * follow next pointers ("forward" direction).
+     *
+     * There is one desirable property we would like to have, but
+     * don't: it is possible, when an addFirst(A) is racing with
+     * pollFirst() removing B, for an iterating observer to see A B C
+     * and subsequently see A C, even though no interior removes are
+     * ever performed.  I believe this wart can only be removed at
+     * significant runtime cost.
+     *
+     * Empirically, microbenchmarks suggest that this class adds about
+     * 40% overhead relative to ConcurrentLinkedQueue, which feels as
+     * good as we can hope for.
+     */
+
+    /**
+     * A node from which the first node on list (that is, the unique
+     * node with node.prev == null) can be reached in O(1) time.
+     * Invariants:
+     * - the first node is always O(1) reachable from head via prev links
+     * - all live nodes are reachable from the first node via succ()
+     * - head != null
+     * - (tmp = head).next != tmp || tmp != head
+     * Non-invariants:
+     * - head.item may or may not be null
+     * - head may not be reachable from the first or last node, or from tail
+     */
+    private transient volatile Node<E> head = new Node<E>(null);
+
+    private final static Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR;
+
+    static {
+        PREV_TERMINATOR = new Node<Object>(null);
+        PREV_TERMINATOR.next = PREV_TERMINATOR;
+        NEXT_TERMINATOR = new Node<Object>(null);
+        NEXT_TERMINATOR.prev = NEXT_TERMINATOR;
+    }
+
+    @SuppressWarnings("unchecked")
+    Node<E> prevTerminator() {
+        return (Node<E>) PREV_TERMINATOR;
+    }
+
+    @SuppressWarnings("unchecked")
+    Node<E> nextTerminator() {
+        return (Node<E>) NEXT_TERMINATOR;
+    }
+
+    /**
+     * A node from which the last node on list (that is, the unique
+     * node with node.next == null) can be reached in O(1) time.
+     * Invariants:
+     * - the last node is always O(1) reachable from tail via next links
+     * - all live nodes are reachable from the last node via pred()
+     * - tail != null
+     * Non-invariants:
+     * - tail.item may or may not be null
+     * - tail may not be reachable from the first or last node, or from head
+     */
+    private transient volatile Node<E> tail = head;
+
+    static final class Node<E> {
+        volatile Node<E> prev;
+        volatile E item;
+        volatile Node<E> next;
+
+        Node(E item) {
+            // Piggyback on imminent casNext() or casPrev()
+            lazySetItem(item);
+        }
+
+        boolean casItem(E cmp, E val) {
+            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
+        }
+
+        void lazySetItem(E val) {
+            UNSAFE.putOrderedObject(this, itemOffset, val);
+        }
+
+        void lazySetNext(Node<E> val) {
+            UNSAFE.putOrderedObject(this, nextOffset, val);
+        }
+
+        boolean casNext(Node<E> cmp, Node<E> val) {
+            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
+        }
+
+        void lazySetPrev(Node<E> val) {
+            UNSAFE.putOrderedObject(this, prevOffset, val);
+        }
+
+        boolean casPrev(Node<E> cmp, Node<E> val) {
+            return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val);
+        }
+
+        // Unsafe mechanics
+
+        private static final sun.misc.Unsafe UNSAFE =
+            sun.misc.Unsafe.getUnsafe();
+        private static final long prevOffset =
+            objectFieldOffset(UNSAFE, "prev", Node.class);
+        private static final long itemOffset =
+            objectFieldOffset(UNSAFE, "item", Node.class);
+        private static final long nextOffset =
+            objectFieldOffset(UNSAFE, "next", Node.class);
+    }
+
+    /**
+     * Links e as first element.
+     */
+    private void linkFirst(E e) {
+        checkNotNull(e);
+        final Node<E> newNode = new Node<E>(e);
+
+        retry:
+        for (;;) {
+            for (Node<E> h = head, p = h;;) {
+                Node<E> q = p.prev;
+                if (q == null) {
+                    if (p.next == p)
+                        continue retry;
+                    newNode.lazySetNext(p); // CAS piggyback
+                    if (p.casPrev(null, newNode)) {
+                        if (p != h) // hop two nodes at a time
+                            casHead(h, newNode);
+                        return;
+                    } else {
+                        p = p.prev; // lost CAS race to another thread
+                    }
+                }
+                else if (p == q)
+                    continue retry;
+                else
+                    p = q;
+            }
+        }
+    }
+
+    /**
+     * Links e as last element.
+     */
+    private void linkLast(E e) {
+        checkNotNull(e);
+        final Node<E> newNode = new Node<E>(e);
+
+        retry:
+        for (;;) {
+            for (Node<E> t = tail, p = t;;) {
+                Node<E> q = p.next;
+                if (q == null) {
+                    if (p.prev == p)
+                        continue retry;
+                    newNode.lazySetPrev(p); // CAS piggyback
+                    if (p.casNext(null, newNode)) {
+                        if (p != t) // hop two nodes at a time
+                            casTail(t, newNode);
+                        return;
+                    } else {
+                        p = p.next; // lost CAS race to another thread
+                    }
+                }
+                else if (p == q)
+                    continue retry;
+                else
+                    p = q;
+            }
+        }
+    }
+
+    // TODO: Is there a better cheap way of performing some cleanup
+    // operation "occasionally"?
+    static class Count {
+        int count = 0;
+    }
+    private final static ThreadLocal<Count> tlc =
+        new ThreadLocal<Count>() {
+        protected Count initialValue() { return new Count(); }
+    };
+    private static boolean shouldGCUnlinkOccasionally() {
+        return (tlc.get().count++ & 0x3) == 0;
+    }
+
+    private final static int HOPS = 2;
+
+    /**
+     * Unlinks non-null node x.
+     */
+    void unlink(Node<E> x) {
+        assert x != null;
+        assert x.item == null;
+        assert x != PREV_TERMINATOR;
+        assert x != NEXT_TERMINATOR;
+
+        final Node<E> prev = x.prev;
+        final Node<E> next = x.next;
+        if (prev == null) {
+            unlinkFirst(x, next);
+        } else if (next == null) {
+            unlinkLast(x, prev);
+        } else {
+            // Unlink interior node.
+            //
+            // This is the common case, since a series of polls at the
+            // same end will be "interior" removes, except perhaps for
+            // the first one, since end nodes cannot be physically removed.
+            //
+            // At any time, all active nodes are mutually reachable by
+            // following a sequence of either next or prev pointers.
+            //
+            // Our strategy is to find the unique active predecessor
+            // and successor of x.  Try to fix up their links so that
+            // they point to each other, leaving x unreachable from
+            // active nodes.  If successful, and if x has no live
+            // predecessor/successor, we additionally try to leave
+            // active nodes unreachable from x, by rechecking that
+            // the status of predecessor and successor are unchanged
+            // and ensuring that x is not reachable from tail/head,
+            // before setting x's prev/next links to their logical
+            // approximate replacements, self/TERMINATOR.
+            Node<E> activePred, activeSucc;
+            boolean isFirst, isLast;
+            int hops = 1;
+
+            // Find active predecessor
+            for (Node<E> p = prev;; ++hops) {
+                if (p.item != null) {
+                    activePred = p;
+                    isFirst = false;
+                    break;
+                }
+                Node<E> q = p.prev;
+                if (q == null) {
+                    if (p == p.next)
+                        return;
+                    activePred = p;
+                    isFirst = true;
+                    break;
+                }
+                else if (p == q)
+                    return;
+                else
+                    p = q;
+            }
+
+            // Find active successor
+            for (Node<E> p = next;; ++hops) {
+                if (p.item != null) {
+                    activeSucc = p;
+                    isLast = false;
+                    break;
+                }
+                Node<E> q = p.next;
+                if (q == null) {
+                    if (p == p.prev)
+                        return;
+                    activeSucc = p;
+                    isLast = true;
+                    break;
+                }
+                else if (p == q)
+                    return;
+                else
+                    p = q;
+            }
+
+            // TODO: better HOP heuristics
+            if (hops < HOPS
+                // always squeeze out interior deleted nodes
+                && (isFirst | isLast))
+                return;
+
+            // Squeeze out deleted nodes between activePred and
+            // activeSucc, including x.
+            skipDeletedSuccessors(activePred);
+            skipDeletedPredecessors(activeSucc);
+
+            // Try to gc-unlink, if possible
+            if ((isFirst | isLast) &&
+                //shouldGCUnlinkOccasionally() &&
+
+                // Recheck expected state of predecessor and successor
+                (activePred.next == activeSucc) &&
+                (activeSucc.prev == activePred) &&
+                (isFirst ? activePred.prev == null : activePred.item != null) &&
+                (isLast  ? activeSucc.next == null : activeSucc.item != null)) {
+
+                // Ensure x is not reachable from head or tail
+                updateHead();
+                updateTail();
+                x.lazySetPrev(isFirst ? prevTerminator() : x);
+                x.lazySetNext(isLast  ? nextTerminator() : x);
+            }
+        }
+    }
+
+    /**
+     * Unlinks non-null first node.
+     */
+    private void unlinkFirst(Node<E> first, Node<E> next) {
+        assert first != null && next != null && first.item == null;
+        Node<E> o = null, p = next;
+        for (int hops = 0;; ++hops) {
+            Node<E> q;
+            if (p.item != null || (q = p.next) == null) {
+                if (hops >= HOPS) {
+                    if (p == p.prev)
+                        return;
+                    if (first.casNext(next, p)) {
+                        skipDeletedPredecessors(p);
+                        if (//shouldGCUnlinkOccasionally() &&
+                            first.prev == null &&
+                            (p.next == null || p.item != null) &&
+                            p.prev == first) {
+
+                            updateHead();
+                            updateTail();
+                            o.lazySetNext(o);
+                            o.lazySetPrev(prevTerminator());
+                        }
+                    }
+                }
+                return;
+            }
+            else if (p == q)
+                return;
+            else {
+                o = p;
+                p = q;
+            }
+        }
+    }
+
+    /**
+     * Unlinks non-null last node.
+     */
+    private void unlinkLast(Node<E> last, Node<E> prev) {
+        assert last != null && prev != null && last.item == null;
+        Node<E> o = null, p = prev;
+        for (int hops = 0;; ++hops) {
+            Node<E> q;
+            if (p.item != null || (q = p.prev) == null) {
+                if (hops >= HOPS) {
+                    if (p == p.next)
+                        return;
+                    if (last.casPrev(prev, p)) {
+                        skipDeletedSuccessors(p);
+                        if (//shouldGCUnlinkOccasionally() &&
+                            last.next == null &&
+                            (p.prev == null || p.item != null) &&
+                            p.next == last) {
+
+                            updateHead();
+                            updateTail();
+                            o.lazySetPrev(o);
+                            o.lazySetNext(nextTerminator());
+                        }
+                    }
+                }
+                return;
+            }
+            else if (p == q)
+                return;
+            else {
+                o = p;
+                p = q;
+            }
+        }
+    }
+
+    private final void updateHead() {
+        first();
+    }
+
+    private final void updateTail() {
+        last();
+    }
+
+    private void skipDeletedPredecessors(Node<E> x) {
+        whileActive:
+        do {
+            Node<E> prev = x.prev;
+            assert prev != null;
+            assert x != NEXT_TERMINATOR;
+            assert x != PREV_TERMINATOR;
+            Node<E> p = prev;
+            findActive:
+            for (;;) {
+                if (p.item != null)
+                    break findActive;
+                Node<E> q = p.prev;
+                if (q == null) {
+                    if (p.next == p)
+                        continue whileActive;
+                    break findActive;
+                }
+                else if (p == q)
+                    continue whileActive;
+                else
+                    p = q;
+            }
+
+            // found active CAS target
+            if (prev == p || x.casPrev(prev, p))
+                return;
+
+        } while (x.item != null || x.next == null);
+    }
+
+    private void skipDeletedSuccessors(Node<E> x) {
+        whileActive:
+        do {
+            Node<E> next = x.next;
+            assert next != null;
+            assert x != NEXT_TERMINATOR;
+            assert x != PREV_TERMINATOR;
+            Node<E> p = next;
+            findActive:
+            for (;;) {
+                if (p.item != null)
+                    break findActive;
+                Node<E> q = p.next;
+                if (q == null) {
+                    if (p.prev == p)
+                        continue whileActive;
+                    break findActive;
+                }
+                else if (p == q)
+                    continue whileActive;
+                else
+                    p = q;
+            }
+
+            // found active CAS target
+            if (next == p || x.casNext(next, p))
+                return;
+
+        } while (x.item != null || x.prev == null);
+    }
+
+    /**
+     * Returns the successor of p, or the first node if p.next has been
+     * linked to self, which will only be true if traversing with a
+     * stale pointer that is now off the list.
+     */
+    final Node<E> succ(Node<E> p) {
+        // TODO: should we skip deleted nodes here?
+        Node<E> q = p.next;
+        return (p == q) ? first() : q;
+    }
+
+    /**
+     * Returns the predecessor of p, or the last node if p.prev has been
+     * linked to self, which will only be true if traversing with a
+     * stale pointer that is now off the list.
+     */
+    final Node<E> pred(Node<E> p) {
+        Node<E> q = p.prev;
+        return (p == q) ? last() : q;
+    }
+
+    /**
+     * Returns the first node, the unique node which has a null prev link.
+     * The returned node may or may not be logically deleted.
+     * Guarantees that head is set to the returned node.
+     */
+    Node<E> first() {
+        retry:
+        for (;;) {
+            for (Node<E> h = head, p = h;;) {
+                Node<E> q = p.prev;
+                if (q == null) {
+                    if (p == h
+                        // It is possible that p is PREV_TERMINATOR,
+                        // but if so, the CAS will fail.
+                        || casHead(h, p))
+                        return p;
+                    else
+                        continue retry;
+                } else if (p == q) {
+                    continue retry;
+                } else {
+                    p = q;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the last node, the unique node which has a null next link.
+     * The returned node may or may not be logically deleted.
+     * Guarantees that tail is set to the returned node.
+     */
+    Node<E> last() {
+        retry:
+        for (;;) {
+            for (Node<E> t = tail, p = t;;) {
+                Node<E> q = p.next;
+                if (q == null) {
+                    if (p == t
+                        // It is possible that p is NEXT_TERMINATOR,
+                        // but if so, the CAS will fail.
+                        || casTail(t, p))
+                        return p;
+                    else
+                        continue retry;
+                } else if (p == q) {
+                    continue retry;
+                } else {
+                    p = q;
+                }
+            }
+        }
+    }
+
+    // Minor convenience utilities
+
+    /**
+     * Throws NullPointerException if argument is null.
+     *
+     * @param v the element
+     */
+    private static void checkNotNull(Object v) {
+        if (v == null)
+            throw new NullPointerException();
+    }
+
+    /**
+     * Returns element unless it is null, in which case throws
+     * NoSuchElementException.
+     *
+     * @param v the element
+     * @return the element
+     */
+    private E screenNullResult(E v) {
+        if (v == null)
+            throw new NoSuchElementException();
+        return v;
+    }
+
+    /**
+     * Creates an array list and fills it with elements of this list.
+     * Used by toArray.
+     *
+     * @return the arrayList
+     */
+    private ArrayList<E> toArrayList() {
+        ArrayList<E> c = new ArrayList<E>();
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null)
+                c.add(item);
+        }
+        return c;
+    }
+
+    // Fields and constructors
+
+    private static final long serialVersionUID = 876323262645176354L;
+
+    /**
+     * Constructs an empty deque.
+     */
+    public ConcurrentLinkedDeque() {}
+
+    /**
+     * Constructs a deque initially containing the elements of
+     * the given collection, added in traversal order of the
+     * collection's iterator.
+     *
+     * @param c the collection of elements to initially contain
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     */
+     public ConcurrentLinkedDeque(Collection<? extends E> c) {
+         this();
+         addAll(c);
+     }
+
+    /**
+     * Inserts the specified element at the front of this deque.
+     *
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void addFirst(E e) {
+        linkFirst(e);
+    }
+
+    /**
+     * Inserts the specified element at the end of this deque.
+     * This is identical in function to the {@code add} method.
+     *
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void addLast(E e) {
+        linkLast(e);
+    }
+
+    /**
+     * Inserts the specified element at the front of this deque.
+     *
+     * @return {@code true} always
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offerFirst(E e) {
+        linkFirst(e);
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the end of this deque.
+     *
+     * <p>This method is equivalent to {@link #add}.
+     *
+     * @return {@code true} always
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offerLast(E e) {
+        linkLast(e);
+        return true;
+    }
+
+    public E peekFirst() {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null)
+                return item;
+        }
+        return null;
+    }
+
+    public E peekLast() {
+        for (Node<E> p = last(); p != null; p = pred(p)) {
+            E item = p.item;
+            if (item != null)
+                return item;
+        }
+        return null;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E getFirst() {
+        return screenNullResult(peekFirst());
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E getLast()  {
+        return screenNullResult(peekLast());
+    }
+
+    public E pollFirst() {
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null && p.casItem(item, null)) {
+                unlink(p);
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public E pollLast() {
+        for (Node<E> p = last(); p != null; p = pred(p)) {
+            E item = p.item;
+            if (item != null && p.casItem(item, null)) {
+                unlink(p);
+                return item;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E removeFirst() {
+        return screenNullResult(pollFirst());
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E removeLast() {
+        return screenNullResult(pollLast());
+    }
+
+    // *** Queue and stack methods ***
+
+    /**
+     * Inserts the specified element at the tail of this deque.
+     *
+     * @return {@code true} (as specified by {@link Queue#offer})
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
+        return offerLast(e);
+    }
+
+    /**
+     * Inserts the specified element at the tail of this deque.
+     *
+     * @return {@code true} (as specified by {@link Collection#add})
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean add(E e) {
+        return offerLast(e);
+    }
+
+    public E poll()           { return pollFirst(); }
+    public E remove()         { return removeFirst(); }
+    public E peek()           { return peekFirst(); }
+    public E element()        { return getFirst(); }
+    public void push(E e)     { addFirst(e); }
+    public E pop()            { return removeFirst(); }
+
+    /**
+     * Removes the first element {@code e} such that
+     * {@code o.equals(e)}, if such an element exists in this deque.
+     * If the deque does not contain the element, it is unchanged.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if the deque contained the specified element
+     * @throws NullPointerException if the specified element is {@code null}
+     */
+    public boolean removeFirstOccurrence(Object o) {
+        checkNotNull(o);
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null && o.equals(item) && p.casItem(item, null)) {
+                unlink(p);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Removes the last element {@code e} such that
+     * {@code o.equals(e)}, if such an element exists in this deque.
+     * If the deque does not contain the element, it is unchanged.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if the deque contained the specified element
+     * @throws NullPointerException if the specified element is {@code null}
+     */
+    public boolean removeLastOccurrence(Object o) {
+        checkNotNull(o);
+        for (Node<E> p = last(); p != null; p = pred(p)) {
+            E item = p.item;
+            if (item != null && o.equals(item) && p.casItem(item, null)) {
+                unlink(p);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if this deque contains at least one
+     * element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o element whose presence in this deque is to be tested
+     * @return {@code true} if this deque contains the specified element
+     */
+    public boolean contains(Object o) {
+        if (o == null) return false;
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            E item = p.item;
+            if (item != null && o.equals(item))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if this collection contains no elements.
+     *
+     * @return {@code true} if this collection contains no elements
+     */
+    public boolean isEmpty() {
+        return peekFirst() == null;
+    }
+
+    /**
+     * Returns the number of elements in this deque.  If this deque
+     * contains more than {@code Integer.MAX_VALUE} elements, it
+     * returns {@code Integer.MAX_VALUE}.
+     *
+     * <p>Beware that, unlike in most collections, this method is
+     * <em>NOT</em> a constant-time operation. Because of the
+     * asynchronous nature of these deques, determining the current
+     * number of elements requires traversing them all to count them.
+     * Additionally, it is possible for the size to change during
+     * execution of this method, in which case the returned result
+     * will be inaccurate. Thus, this method is typically not very
+     * useful in concurrent applications.
+     *
+     * @return the number of elements in this deque
+     */
+    public int size() {
+        long count = 0;
+        for (Node<E> p = first(); p != null; p = succ(p))
+            if (p.item != null)
+                ++count;
+        return (count >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) count;
+    }
+
+    /**
+     * Removes the first element {@code e} such that
+     * {@code o.equals(e)}, if such an element exists in this deque.
+     * If the deque does not contain the element, it is unchanged.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if the deque contained the specified element
+     * @throws NullPointerException if the specified element is {@code null}
+     */
+    public boolean remove(Object o) {
+        return removeFirstOccurrence(o);
+    }
+
+    /**
+     * Appends all of the elements in the specified collection to the end of
+     * this deque, in the order that they are returned by the specified
+     * collection's iterator.  The behavior of this operation is undefined if
+     * the specified collection is modified while the operation is in
+     * progress.  (This implies that the behavior of this call is undefined if
+     * the specified Collection is this deque, and this deque is nonempty.)
+     *
+     * @param c the elements to be inserted into this deque
+     * @return {@code true} if this deque changed as a result of the call
+     * @throws NullPointerException if {@code c} or any element within it
+     * is {@code null}
+     */
+    public boolean addAll(Collection<? extends E> c) {
+        Iterator<? extends E> it = c.iterator();
+        if (!it.hasNext())
+            return false;
+        do {
+            addLast(it.next());
+        } while (it.hasNext());
+        return true;
+    }
+
+    /**
+     * Removes all of the elements from this deque.
+     */
+    public void clear() {
+        while (pollFirst() != null)
+            ;
+    }
+
+    /**
+     * Returns an array containing all of the elements in this deque, in
+     * proper sequence (from first to last element).
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this deque.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this deque
+     */
+    public Object[] toArray() {
+        return toArrayList().toArray();
+    }
+
+    /**
+     * Returns an array containing all of the elements in this deque,
+     * in proper sequence (from first to last element); the runtime
+     * type of the returned array is that of the specified array.  If
+     * the deque fits in the specified array, it is returned therein.
+     * Otherwise, a new array is allocated with the runtime type of
+     * the specified array and the size of this deque.
+     *
+     * <p>If this deque fits in the specified array with room to spare
+     * (i.e., the array has more elements than this deque), the element in
+     * the array immediately following the end of the deque is set to
+     * {@code null}.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose {@code x} is a deque known to contain only strings.
+     * The following code can be used to dump the deque into a newly
+     * allocated array of {@code String}:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
+     *
+     * @param a the array into which the elements of the deque are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this deque
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this deque
+     * @throws NullPointerException if the specified array is null
+     */
+    public <T> T[] toArray(T[] a) {
+        return toArrayList().toArray(a);
+    }
+
+    /**
+     * Returns an iterator over the elements in this deque in proper sequence.
+     * The elements will be returned in order from first (head) to last (tail).
+     *
+     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * @return an iterator over the elements in this deque in proper sequence
+     */
+    public Iterator<E> iterator() {
+        return new Itr();
+    }
+
+    /**
+     * Returns an iterator over the elements in this deque in reverse
+     * sequential order.  The elements will be returned in order from
+     * last (tail) to first (head).
+     *
+     * <p>The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public Iterator<E> descendingIterator() {
+        return new DescendingItr();
+    }
+
+    private abstract class AbstractItr implements Iterator<E> {
+        /**
+         * Next node to return item for.
+         */
+        private Node<E> nextNode;
+
+        /**
+         * nextItem holds on to item fields because once we claim
+         * that an element exists in hasNext(), we must return it in
+         * the following next() call even if it was in the process of
+         * being removed when hasNext() was called.
+         */
+        private E nextItem;
+
+        /**
+         * Node returned by most recent call to next. Needed by remove.
+         * Reset to null if this element is deleted by a call to remove.
+         */
+        private Node<E> lastRet;
+
+        abstract Node<E> startNode();
+        abstract Node<E> nextNode(Node<E> p);
+
+        AbstractItr() {
+            advance();
+        }
+
+        /**
+         * Sets nextNode and nextItem to next valid node, or to null
+         * if no such.
+         */
+        private void advance() {
+            lastRet = nextNode;
+
+            Node<E> p = (nextNode == null) ? startNode() : nextNode(nextNode);
+            for (;; p = nextNode(p)) {
+                if (p == null) {
+                    // p might be active end or TERMINATOR node; both are OK
+                    nextNode = null;
+                    nextItem = null;
+                    break;
+                }
+                E item = p.item;
+                if (item != null) {
+                    nextNode = p;
+                    nextItem = item;
+                    break;
+                }
+            }
+        }
+
+        public boolean hasNext() {
+            return nextItem != null;
+        }
+
+        public E next() {
+            E item = nextItem;
+            if (item == null) throw new NoSuchElementException();
+            advance();
+            return item;
+        }
+
+        public void remove() {
+            Node<E> l = lastRet;
+            if (l == null) throw new IllegalStateException();
+            l.item = null;
+            unlink(l);
+            lastRet = null;
+        }
+    }
+
+    /** Forward iterator */
+    private class Itr extends AbstractItr {
+        Node<E> startNode() { return first(); }
+        Node<E> nextNode(Node<E> p) { return succ(p); }
+    }
+
+    /** Descending iterator */
+    private class DescendingItr extends AbstractItr {
+        Node<E> startNode() { return last(); }
+        Node<E> nextNode(Node<E> p) { return pred(p); }
+    }
+
+    /**
+     * Save the state to a stream (that is, serialize it).
+     *
+     * @serialData All of the elements (each an {@code E}) in
+     * the proper order, followed by a null
+     * @param s the stream
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+
+        // Write out any hidden stuff
+        s.defaultWriteObject();
+
+        // Write out all elements in the proper order.
+        for (Node<E> p = first(); p != null; p = succ(p)) {
+            Object item = p.item;
+            if (item != null)
+                s.writeObject(item);
+        }
+
+        // Use trailing null as sentinel
+        s.writeObject(null);
+    }
+
+    /**
+     * Reconstitute the Queue instance from a stream (that is,
+     * deserialize it).
+     * @param s the stream
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        // Read in capacity, and any hidden stuff
+        s.defaultReadObject();
+        tail = head = new Node<E>(null);
+        // Read in all elements and place in queue
+        for (;;) {
+            @SuppressWarnings("unchecked")
+            E item = (E)s.readObject();
+            if (item == null)
+                break;
+            else
+                offer(item);
+        }
+    }
+
+    // Unsafe mechanics
+
+    private static final sun.misc.Unsafe UNSAFE =
+        sun.misc.Unsafe.getUnsafe();
+    private static final long headOffset =
+        objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class);
+    private static final long tailOffset =
+        objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class);
+
+    private boolean casHead(Node<E> cmp, Node<E> val) {
+        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+    }
+
+    private boolean casTail(Node<E> cmp, Node<E> val) {
+        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
+    }
+
+    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
+                                  String field, Class<?> klazz) {
+        try {
+            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
+        } catch (NoSuchFieldException e) {
+            // Convert Exception to corresponding Error
+            NoSuchFieldError error = new NoSuchFieldError(field);
+            error.initCause(e);
+            throw error;
+        }
+    }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
index 2253823..2d222c1 100644
--- a/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentLinkedQueue.java
@@ -5,9 +5,13 @@
  */
 
 package java.util.concurrent;
-import java.util.*;
-import java.util.concurrent.atomic.*;
 
+import java.util.AbstractQueue;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
 
 // BEGIN android-note
 // removed link to collections framework docs
@@ -126,34 +130,34 @@
      * CAS, so they never regress, although again this is merely an
      * optimization.
      */
+
     private static class Node<E> {
         private volatile E item;
         private volatile Node<E> next;
 
-        private static final
-            AtomicReferenceFieldUpdater<Node, Node>
-            nextUpdater =
-            AtomicReferenceFieldUpdater.newUpdater
-            (Node.class, Node.class, "next");
-        private static final
-            AtomicReferenceFieldUpdater<Node, Object>
-            itemUpdater =
-            AtomicReferenceFieldUpdater.newUpdater
-            (Node.class, Object.class, "item");
-
-
-        Node(E item) { setItem(item); }
+        Node(E item) {
+            // Piggyback on imminent casNext()
+            lazySetItem(item);
+        }
 
         E getItem() {
             return item;
         }
 
         boolean casItem(E cmp, E val) {
-            return itemUpdater.compareAndSet(this, cmp, val);
+            return UNSAFE.compareAndSwapObject(this, itemOffset, cmp, val);
         }
 
         void setItem(E val) {
-            itemUpdater.set(this, val);
+            item = val;
+        }
+
+        void lazySetItem(E val) {
+            UNSAFE.putOrderedObject(this, itemOffset, val);
+        }
+
+        void lazySetNext(Node<E> val) {
+            UNSAFE.putOrderedObject(this, nextOffset, val);
         }
 
         Node<E> getNext() {
@@ -161,42 +165,45 @@
         }
 
         boolean casNext(Node<E> cmp, Node<E> val) {
-            return nextUpdater.compareAndSet(this, cmp, val);
+            return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val);
         }
 
-        void setNext(Node<E> val) {
-            nextUpdater.set(this, val);
+        // Unsafe mechanics
+
+        private static final sun.misc.Unsafe UNSAFE =
+            sun.misc.Unsafe.getUnsafe();
+        private static final long nextOffset =
+            objectFieldOffset(UNSAFE, "next", Node.class);
+        private static final long itemOffset =
+            objectFieldOffset(UNSAFE, "item", Node.class);
     }
 
-    }
-
-    private static final
-        AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node>
-        tailUpdater =
-        AtomicReferenceFieldUpdater.newUpdater
-        (ConcurrentLinkedQueue.class, Node.class, "tail");
-    private static final
-        AtomicReferenceFieldUpdater<ConcurrentLinkedQueue, Node>
-        headUpdater =
-        AtomicReferenceFieldUpdater.newUpdater
-        (ConcurrentLinkedQueue.class,  Node.class, "head");
-
-    private boolean casTail(Node<E> cmp, Node<E> val) {
-        return tailUpdater.compareAndSet(this, cmp, val);
-    }
-
-    private boolean casHead(Node<E> cmp, Node<E> val) {
-        return headUpdater.compareAndSet(this, cmp, val);
-    }
-
-
-
     /**
-     * Pointer to first node, initialized to a dummy node.
+     * A node from which the first live (non-deleted) node (if any)
+     * can be reached in O(1) time.
+     * Invariants:
+     * - all live nodes are reachable from head via succ()
+     * - head != null
+     * - (tmp = head).next != tmp || tmp != head
+     * Non-invariants:
+     * - head.item may or may not be null.
+     * - it is permitted for tail to lag behind head, that is, for tail
+     *   to not be reachable from head!
      */
     private transient volatile Node<E> head = new Node<E>(null);
 
-    /** Pointer to last node on list */
+    /**
+     * A node from which the last node on list (that is, the unique
+     * node with node.next == null) can be reached in O(1) time.
+     * Invariants:
+     * - the last node is always reachable from tail via succ()
+     * - tail != null
+     * Non-invariants:
+     * - tail.item may or may not be null.
+     * - it is permitted for tail to lag behind head, that is, for tail
+     *   to not be reachable from head!
+     * - tail.next may or may not be self-pointing to tail.
+     */
     private transient volatile Node<E> tail = head;
 
 
@@ -214,8 +221,8 @@
      *         of its elements are null
      */
     public ConcurrentLinkedQueue(Collection<? extends E> c) {
-        for (Iterator<? extends E> it = c.iterator(); it.hasNext();)
-            add(it.next());
+        for (E e : c)
+            add(e);
     }
 
     // Have to override just to update the javadoc
@@ -231,7 +238,7 @@
     }
 
     /**
-     * We don't bother to update head or tail pointers if less than
+     * We don't bother to update head or tail pointers if fewer than
      * HOPS links from "true" location.  We assume that volatile
      * writes are significantly more expensive than volatile reads.
      */
@@ -243,7 +250,7 @@
      */
     final void updateHead(Node<E> h, Node<E> p) {
         if (h != p && casHead(h, p))
-            h.setNext(h);
+            h.lazySetNext(h);
     }
 
     /**
@@ -328,10 +335,12 @@
     }
 
     /**
-     * Returns the first actual (non-header) node on list.  This is yet
-     * another variant of poll/peek; here returning out the first
-     * node, not element (so we cannot collapse with peek() without
-     * introducing race.)
+     * Returns the first live (non-deleted) node on list, or null if none.
+     * This is yet another variant of poll/peek; here returning the
+     * first node, not element.  We could make peek() a wrapper around
+     * first(), but that would cost an extra volatile read of item,
+     * and the need to add a retry loop to deal with the possibility
+     * of losing a race to a concurrent poll().
      */
     Node<E> first() {
         Node<E> h = head;
@@ -422,7 +431,9 @@
         Node<E> pred = null;
         for (Node<E> p = first(); p != null; p = succ(p)) {
             E item = p.getItem();
-            if (item != null && o.equals(item) && p.casItem(item, null)) {
+            if (item != null &&
+                o.equals(item) &&
+                p.casItem(item, null)) {
                 Node<E> next = succ(p);
                 if (pred != null && next != null)
                     pred.casNext(p, next);
@@ -522,7 +533,8 @@
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
      * The returned iterator is a "weakly consistent" iterator that
-     * will never throw {@link ConcurrentModificationException},
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
@@ -658,4 +670,35 @@
         }
     }
 
+    // Unsafe mechanics
+
+    private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
+    private static final long headOffset =
+        objectFieldOffset(UNSAFE, "head", ConcurrentLinkedQueue.class);
+    private static final long tailOffset =
+        objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedQueue.class);
+
+    private boolean casTail(Node<E> cmp, Node<E> val) {
+        return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val);
+    }
+
+    private boolean casHead(Node<E> cmp, Node<E> val) {
+        return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val);
+    }
+
+    private void lazySetHead(Node<E> val) {
+        UNSAFE.putOrderedObject(this, headOffset, val);
+    }
+
+    static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
+                                  String field, Class<?> klazz) {
+        try {
+            return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
+        } catch (NoSuchFieldException e) {
+            // Convert Exception to corresponding Error
+            NoSuchFieldError error = new NoSuchFieldError(field);
+            error.initCause(e);
+            throw error;
+        }
+    }
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java
new file mode 100644
index 0000000..7d86afb
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentNavigableMap.java
@@ -0,0 +1,148 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+
+/**
+ * A {@link ConcurrentMap} supporting {@link NavigableMap} operations,
+ * and recursively so for its navigable sub-maps.
+ *
+ * <p>This interface is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ * @since 1.6
+ */
+public interface ConcurrentNavigableMap<K,V>
+    extends ConcurrentMap<K,V>, NavigableMap<K,V>
+{
+    /**
+     * @throws ClassCastException       {@inheritDoc}
+     * @throws NullPointerException     {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
+                                       K toKey,   boolean toInclusive);
+
+    /**
+     * @throws ClassCastException       {@inheritDoc}
+     * @throws NullPointerException     {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive);
+
+
+    /**
+     * @throws ClassCastException       {@inheritDoc}
+     * @throws NullPointerException     {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
+
+    /**
+     * @throws ClassCastException       {@inheritDoc}
+     * @throws NullPointerException     {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey);
+
+    /**
+     * @throws ClassCastException       {@inheritDoc}
+     * @throws NullPointerException     {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    ConcurrentNavigableMap<K,V> headMap(K toKey);
+
+    /**
+     * @throws ClassCastException       {@inheritDoc}
+     * @throws NullPointerException     {@inheritDoc}
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    ConcurrentNavigableMap<K,V> tailMap(K fromKey);
+
+    /**
+     * Returns a reverse order view of the mappings contained in this map.
+     * The descending map is backed by this map, so changes to the map are
+     * reflected in the descending map, and vice-versa.
+     *
+     * <p>The returned map has an ordering equivalent to
+     * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
+     * The expression {@code m.descendingMap().descendingMap()} returns a
+     * view of {@code m} essentially equivalent to {@code m}.
+     *
+     * @return a reverse order view of this map
+     */
+    ConcurrentNavigableMap<K,V> descendingMap();
+
+    /**
+     * Returns a {@link NavigableSet} view of the keys contained in this map.
+     * The set's iterator returns the keys in ascending order.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or {@code addAll}
+     * operations.
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * @return a navigable set view of the keys in this map
+     */
+    public NavigableSet<K> navigableKeySet();
+
+    /**
+     * Returns a {@link NavigableSet} view of the keys contained in this map.
+     * The set's iterator returns the keys in ascending order.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or {@code addAll}
+     * operations.
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * <p>This method is equivalent to method {@code navigableKeySet}.
+     *
+     * @return a navigable set view of the keys in this map
+     */
+    NavigableSet<K> keySet();
+
+    /**
+     * Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
+     * The set's iterator returns the keys in descending order.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or {@code addAll}
+     * operations.
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * @return a reverse order navigable set view of the keys in this map
+     */
+    public NavigableSet<K> descendingKeySet();
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java
new file mode 100644
index 0000000..d73d163
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentSkipListMap.java
@@ -0,0 +1,3115 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * A scalable concurrent {@link ConcurrentNavigableMap} implementation.
+ * The map is sorted according to the {@linkplain Comparable natural
+ * ordering} of its keys, or by a {@link Comparator} provided at map
+ * creation time, depending on which constructor is used.
+ *
+ * <p>This class implements a concurrent variant of <a
+ * href="http://www.cs.umd.edu/~pugh/">SkipLists</a> providing
+ * expected average <i>log(n)</i> time cost for the
+ * <tt>containsKey</tt>, <tt>get</tt>, <tt>put</tt> and
+ * <tt>remove</tt> operations and their variants.  Insertion, removal,
+ * update, and access operations safely execute concurrently by
+ * multiple threads.  Iterators are <i>weakly consistent</i>, returning
+ * elements reflecting the state of the map at some point at or since
+ * the creation of the iterator.  They do <em>not</em> throw {@link
+ * ConcurrentModificationException}, and may proceed concurrently with
+ * other operations. Ascending key ordered views and their iterators
+ * are faster than descending ones.
+ *
+ * <p>All <tt>Map.Entry</tt> pairs returned by methods in this class
+ * and its views represent snapshots of mappings at the time they were
+ * produced. They do <em>not</em> support the <tt>Entry.setValue</tt>
+ * method. (Note however that it is possible to change mappings in the
+ * associated map using <tt>put</tt>, <tt>putIfAbsent</tt>, or
+ * <tt>replace</tt>, depending on exactly which effect you need.)
+ *
+ * <p>Beware that, unlike in most collections, the <tt>size</tt>
+ * method is <em>not</em> a constant-time operation. Because of the
+ * asynchronous nature of these maps, determining the current number
+ * of elements requires a traversal of the elements.  Additionally,
+ * the bulk operations <tt>putAll</tt>, <tt>equals</tt>, and
+ * <tt>clear</tt> are <em>not</em> guaranteed to be performed
+ * atomically. For example, an iterator operating concurrently with a
+ * <tt>putAll</tt> operation might view only some of the added
+ * elements.
+ *
+ * <p>This class and its views and iterators implement all of the
+ * <em>optional</em> methods of the {@link Map} and {@link Iterator}
+ * interfaces. Like most other concurrent collections, this class does
+ * <em>not</em> permit the use of <tt>null</tt> keys or values because some
+ * null return values cannot be reliably distinguished from the absence of
+ * elements.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @author Doug Lea
+ * @param <K> the type of keys maintained by this map
+ * @param <V> the type of mapped values
+ * @since 1.6
+ */
+public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
+    implements ConcurrentNavigableMap<K,V>,
+               Cloneable,
+               java.io.Serializable {
+    /*
+     * This class implements a tree-like two-dimensionally linked skip
+     * list in which the index levels are represented in separate
+     * nodes from the base nodes holding data.  There are two reasons
+     * for taking this approach instead of the usual array-based
+     * structure: 1) Array based implementations seem to encounter
+     * more complexity and overhead 2) We can use cheaper algorithms
+     * for the heavily-traversed index lists than can be used for the
+     * base lists.  Here's a picture of some of the basics for a
+     * possible list with 2 levels of index:
+     *
+     * Head nodes          Index nodes
+     * +-+    right        +-+                      +-+
+     * |2|---------------->| |--------------------->| |->null
+     * +-+                 +-+                      +-+
+     *  | down              |                        |
+     *  v                   v                        v
+     * +-+            +-+  +-+       +-+            +-+       +-+
+     * |1|----------->| |->| |------>| |----------->| |------>| |->null
+     * +-+            +-+  +-+       +-+            +-+       +-+
+     *  v              |    |         |              |         |
+     * Nodes  next     v    v         v              v         v
+     * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
+     * | |->|A|->|B|->|C|->|D|->|E|->|F|->|G|->|H|->|I|->|J|->|K|->null
+     * +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+  +-+
+     *
+     * The base lists use a variant of the HM linked ordered set
+     * algorithm. See Tim Harris, "A pragmatic implementation of
+     * non-blocking linked lists"
+     * http://www.cl.cam.ac.uk/~tlh20/publications.html and Maged
+     * Michael "High Performance Dynamic Lock-Free Hash Tables and
+     * List-Based Sets"
+     * http://www.research.ibm.com/people/m/michael/pubs.htm.  The
+     * basic idea in these lists is to mark the "next" pointers of
+     * deleted nodes when deleting to avoid conflicts with concurrent
+     * insertions, and when traversing to keep track of triples
+     * (predecessor, node, successor) in order to detect when and how
+     * to unlink these deleted nodes.
+     *
+     * Rather than using mark-bits to mark list deletions (which can
+     * be slow and space-intensive using AtomicMarkedReference), nodes
+     * use direct CAS'able next pointers.  On deletion, instead of
+     * marking a pointer, they splice in another node that can be
+     * thought of as standing for a marked pointer (indicating this by
+     * using otherwise impossible field values).  Using plain nodes
+     * acts roughly like "boxed" implementations of marked pointers,
+     * but uses new nodes only when nodes are deleted, not for every
+     * link.  This requires less space and supports faster
+     * traversal. Even if marked references were better supported by
+     * JVMs, traversal using this technique might still be faster
+     * because any search need only read ahead one more node than
+     * otherwise required (to check for trailing marker) rather than
+     * unmasking mark bits or whatever on each read.
+     *
+     * This approach maintains the essential property needed in the HM
+     * algorithm of changing the next-pointer of a deleted node so
+     * that any other CAS of it will fail, but implements the idea by
+     * changing the pointer to point to a different node, not by
+     * marking it.  While it would be possible to further squeeze
+     * space by defining marker nodes not to have key/value fields, it
+     * isn't worth the extra type-testing overhead.  The deletion
+     * markers are rarely encountered during traversal and are
+     * normally quickly garbage collected. (Note that this technique
+     * would not work well in systems without garbage collection.)
+     *
+     * In addition to using deletion markers, the lists also use
+     * nullness of value fields to indicate deletion, in a style
+     * similar to typical lazy-deletion schemes.  If a node's value is
+     * null, then it is considered logically deleted and ignored even
+     * though it is still reachable. This maintains proper control of
+     * concurrent replace vs delete operations -- an attempted replace
+     * must fail if a delete beat it by nulling field, and a delete
+     * must return the last non-null value held in the field. (Note:
+     * Null, rather than some special marker, is used for value fields
+     * here because it just so happens to mesh with the Map API
+     * requirement that method get returns null if there is no
+     * mapping, which allows nodes to remain concurrently readable
+     * even when deleted. Using any other marker value here would be
+     * messy at best.)
+     *
+     * Here's the sequence of events for a deletion of node n with
+     * predecessor b and successor f, initially:
+     *
+     *        +------+       +------+      +------+
+     *   ...  |   b  |------>|   n  |----->|   f  | ...
+     *        +------+       +------+      +------+
+     *
+     * 1. CAS n's value field from non-null to null.
+     *    From this point on, no public operations encountering
+     *    the node consider this mapping to exist. However, other
+     *    ongoing insertions and deletions might still modify
+     *    n's next pointer.
+     *
+     * 2. CAS n's next pointer to point to a new marker node.
+     *    From this point on, no other nodes can be appended to n.
+     *    which avoids deletion errors in CAS-based linked lists.
+     *
+     *        +------+       +------+      +------+       +------+
+     *   ...  |   b  |------>|   n  |----->|marker|------>|   f  | ...
+     *        +------+       +------+      +------+       +------+
+     *
+     * 3. CAS b's next pointer over both n and its marker.
+     *    From this point on, no new traversals will encounter n,
+     *    and it can eventually be GCed.
+     *        +------+                                    +------+
+     *   ...  |   b  |----------------------------------->|   f  | ...
+     *        +------+                                    +------+
+     *
+     * A failure at step 1 leads to simple retry due to a lost race
+     * with another operation. Steps 2-3 can fail because some other
+     * thread noticed during a traversal a node with null value and
+     * helped out by marking and/or unlinking.  This helping-out
+     * ensures that no thread can become stuck waiting for progress of
+     * the deleting thread.  The use of marker nodes slightly
+     * complicates helping-out code because traversals must track
+     * consistent reads of up to four nodes (b, n, marker, f), not
+     * just (b, n, f), although the next field of a marker is
+     * immutable, and once a next field is CAS'ed to point to a
+     * marker, it never again changes, so this requires less care.
+     *
+     * Skip lists add indexing to this scheme, so that the base-level
+     * traversals start close to the locations being found, inserted
+     * or deleted -- usually base level traversals only traverse a few
+     * nodes. This doesn't change the basic algorithm except for the
+     * need to make sure base traversals start at predecessors (here,
+     * b) that are not (structurally) deleted, otherwise retrying
+     * after processing the deletion.
+     *
+     * Index levels are maintained as lists with volatile next fields,
+     * using CAS to link and unlink.  Races are allowed in index-list
+     * operations that can (rarely) fail to link in a new index node
+     * or delete one. (We can't do this of course for data nodes.)
+     * However, even when this happens, the index lists remain sorted,
+     * so correctly serve as indices.  This can impact performance,
+     * but since skip lists are probabilistic anyway, the net result
+     * is that under contention, the effective "p" value may be lower
+     * than its nominal value. And race windows are kept small enough
+     * that in practice these failures are rare, even under a lot of
+     * contention.
+     *
+     * The fact that retries (for both base and index lists) are
+     * relatively cheap due to indexing allows some minor
+     * simplifications of retry logic. Traversal restarts are
+     * performed after most "helping-out" CASes. This isn't always
+     * strictly necessary, but the implicit backoffs tend to help
+     * reduce other downstream failed CAS's enough to outweigh restart
+     * cost.  This worsens the worst case, but seems to improve even
+     * highly contended cases.
+     *
+     * Unlike most skip-list implementations, index insertion and
+     * deletion here require a separate traversal pass occuring after
+     * the base-level action, to add or remove index nodes.  This adds
+     * to single-threaded overhead, but improves contended
+     * multithreaded performance by narrowing interference windows,
+     * and allows deletion to ensure that all index nodes will be made
+     * unreachable upon return from a public remove operation, thus
+     * avoiding unwanted garbage retention. This is more important
+     * here than in some other data structures because we cannot null
+     * out node fields referencing user keys since they might still be
+     * read by other ongoing traversals.
+     *
+     * Indexing uses skip list parameters that maintain good search
+     * performance while using sparser-than-usual indices: The
+     * hardwired parameters k=1, p=0.5 (see method randomLevel) mean
+     * that about one-quarter of the nodes have indices. Of those that
+     * do, half have one level, a quarter have two, and so on (see
+     * Pugh's Skip List Cookbook, sec 3.4).  The expected total space
+     * requirement for a map is slightly less than for the current
+     * implementation of java.util.TreeMap.
+     *
+     * Changing the level of the index (i.e, the height of the
+     * tree-like structure) also uses CAS. The head index has initial
+     * level/height of one. Creation of an index with height greater
+     * than the current level adds a level to the head index by
+     * CAS'ing on a new top-most head. To maintain good performance
+     * after a lot of removals, deletion methods heuristically try to
+     * reduce the height if the topmost levels appear to be empty.
+     * This may encounter races in which it possible (but rare) to
+     * reduce and "lose" a level just as it is about to contain an
+     * index (that will then never be encountered). This does no
+     * structural harm, and in practice appears to be a better option
+     * than allowing unrestrained growth of levels.
+     *
+     * The code for all this is more verbose than you'd like. Most
+     * operations entail locating an element (or position to insert an
+     * element). The code to do this can't be nicely factored out
+     * because subsequent uses require a snapshot of predecessor
+     * and/or successor and/or value fields which can't be returned
+     * all at once, at least not without creating yet another object
+     * to hold them -- creating such little objects is an especially
+     * bad idea for basic internal search operations because it adds
+     * to GC overhead.  (This is one of the few times I've wished Java
+     * had macros.) Instead, some traversal code is interleaved within
+     * insertion and removal operations.  The control logic to handle
+     * all the retry conditions is sometimes twisty. Most search is
+     * broken into 2 parts. findPredecessor() searches index nodes
+     * only, returning a base-level predecessor of the key. findNode()
+     * finishes out the base-level search. Even with this factoring,
+     * there is a fair amount of near-duplication of code to handle
+     * variants.
+     *
+     * For explanation of algorithms sharing at least a couple of
+     * features with this one, see Mikhail Fomitchev's thesis
+     * (http://www.cs.yorku.ca/~mikhail/), Keir Fraser's thesis
+     * (http://www.cl.cam.ac.uk/users/kaf24/), and Hakan Sundell's
+     * thesis (http://www.cs.chalmers.se/~phs/).
+     *
+     * Given the use of tree-like index nodes, you might wonder why
+     * this doesn't use some kind of search tree instead, which would
+     * support somewhat faster search operations. The reason is that
+     * there are no known efficient lock-free insertion and deletion
+     * algorithms for search trees. The immutability of the "down"
+     * links of index nodes (as opposed to mutable "left" fields in
+     * true trees) makes this tractable using only CAS operations.
+     *
+     * Notation guide for local variables
+     * Node:         b, n, f    for  predecessor, node, successor
+     * Index:        q, r, d    for index node, right, down.
+     *               t          for another index node
+     * Head:         h
+     * Levels:       j
+     * Keys:         k, key
+     * Values:       v, value
+     * Comparisons:  c
+     */
+
+    private static final long serialVersionUID = -8627078645895051609L;
+
+    /**
+     * Generates the initial random seed for the cheaper per-instance
+     * random number generators used in randomLevel.
+     */
+    private static final Random seedGenerator = new Random();
+
+    /**
+     * Special value used to identify base-level header
+     */
+    private static final Object BASE_HEADER = new Object();
+
+    /**
+     * The topmost head index of the skiplist.
+     */
+    private transient volatile HeadIndex<K,V> head;
+
+    /**
+     * The comparator used to maintain order in this map, or null
+     * if using natural ordering.
+     * @serial
+     */
+    private final Comparator<? super K> comparator;
+
+    /**
+     * Seed for simple random number generator.  Not volatile since it
+     * doesn't matter too much if different threads don't see updates.
+     */
+    private transient int randomSeed;
+
+    /** Lazily initialized key set */
+    private transient KeySet keySet;
+    /** Lazily initialized entry set */
+    private transient EntrySet entrySet;
+    /** Lazily initialized values collection */
+    private transient Values values;
+    /** Lazily initialized descending key set */
+    private transient ConcurrentNavigableMap<K,V> descendingMap;
+
+    /**
+     * Initializes or resets state. Needed by constructors, clone,
+     * clear, readObject. and ConcurrentSkipListSet.clone.
+     * (Note that comparator must be separately initialized.)
+     */
+    final void initialize() {
+        keySet = null;
+        entrySet = null;
+        values = null;
+        descendingMap = null;
+        randomSeed = seedGenerator.nextInt() | 0x0100; // ensure nonzero
+        head = new HeadIndex<K,V>(new Node<K,V>(null, BASE_HEADER, null),
+                                  null, null, 1);
+    }
+
+    /** Updater for casHead */
+    private static final
+        AtomicReferenceFieldUpdater<ConcurrentSkipListMap, HeadIndex>
+        headUpdater = AtomicReferenceFieldUpdater.newUpdater
+        (ConcurrentSkipListMap.class, HeadIndex.class, "head");
+
+    /**
+     * compareAndSet head node
+     */
+    private boolean casHead(HeadIndex<K,V> cmp, HeadIndex<K,V> val) {
+        return headUpdater.compareAndSet(this, cmp, val);
+    }
+
+    /* ---------------- Nodes -------------- */
+
+    /**
+     * Nodes hold keys and values, and are singly linked in sorted
+     * order, possibly with some intervening marker nodes. The list is
+     * headed by a dummy node accessible as head.node. The value field
+     * is declared only as Object because it takes special non-V
+     * values for marker and header nodes.
+     */
+    static final class Node<K,V> {
+        final K key;
+        volatile Object value;
+        volatile Node<K,V> next;
+
+        /**
+         * Creates a new regular node.
+         */
+        Node(K key, Object value, Node<K,V> next) {
+            this.key = key;
+            this.value = value;
+            this.next = next;
+        }
+
+        /**
+         * Creates a new marker node. A marker is distinguished by
+         * having its value field point to itself.  Marker nodes also
+         * have null keys, a fact that is exploited in a few places,
+         * but this doesn't distinguish markers from the base-level
+         * header node (head.node), which also has a null key.
+         */
+        Node(Node<K,V> next) {
+            this.key = null;
+            this.value = this;
+            this.next = next;
+        }
+
+        /** Updater for casNext */
+        static final AtomicReferenceFieldUpdater<Node, Node>
+            nextUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (Node.class, Node.class, "next");
+
+        /** Updater for casValue */
+        static final AtomicReferenceFieldUpdater<Node, Object>
+            valueUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (Node.class, Object.class, "value");
+
+        /**
+         * compareAndSet value field
+         */
+        boolean casValue(Object cmp, Object val) {
+            return valueUpdater.compareAndSet(this, cmp, val);
+        }
+
+        /**
+         * compareAndSet next field
+         */
+        boolean casNext(Node<K,V> cmp, Node<K,V> val) {
+            return nextUpdater.compareAndSet(this, cmp, val);
+        }
+
+        /**
+         * Returns true if this node is a marker. This method isn't
+         * actually called in any current code checking for markers
+         * because callers will have already read value field and need
+         * to use that read (not another done here) and so directly
+         * test if value points to node.
+         * @param n a possibly null reference to a node
+         * @return true if this node is a marker node
+         */
+        boolean isMarker() {
+            return value == this;
+        }
+
+        /**
+         * Returns true if this node is the header of base-level list.
+         * @return true if this node is header node
+         */
+        boolean isBaseHeader() {
+            return value == BASE_HEADER;
+        }
+
+        /**
+         * Tries to append a deletion marker to this node.
+         * @param f the assumed current successor of this node
+         * @return true if successful
+         */
+        boolean appendMarker(Node<K,V> f) {
+            return casNext(f, new Node<K,V>(f));
+        }
+
+        /**
+         * Helps out a deletion by appending marker or unlinking from
+         * predecessor. This is called during traversals when value
+         * field seen to be null.
+         * @param b predecessor
+         * @param f successor
+         */
+        void helpDelete(Node<K,V> b, Node<K,V> f) {
+            /*
+             * Rechecking links and then doing only one of the
+             * help-out stages per call tends to minimize CAS
+             * interference among helping threads.
+             */
+            if (f == next && this == b.next) {
+                if (f == null || f.value != f) // not already marked
+                    appendMarker(f);
+                else
+                    b.casNext(this, f.next);
+            }
+        }
+
+        /**
+         * Returns value if this node contains a valid key-value pair,
+         * else null.
+         * @return this node's value if it isn't a marker or header or
+         * is deleted, else null.
+         */
+        V getValidValue() {
+            Object v = value;
+            if (v == this || v == BASE_HEADER)
+                return null;
+            return (V)v;
+        }
+
+        /**
+         * Creates and returns a new SimpleImmutableEntry holding current
+         * mapping if this node holds a valid value, else null.
+         * @return new entry or null
+         */
+        AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
+            V v = getValidValue();
+            if (v == null)
+                return null;
+            return new AbstractMap.SimpleImmutableEntry<K,V>(key, v);
+        }
+    }
+
+    /* ---------------- Indexing -------------- */
+
+    /**
+     * Index nodes represent the levels of the skip list.  Note that
+     * even though both Nodes and Indexes have forward-pointing
+     * fields, they have different types and are handled in different
+     * ways, that can't nicely be captured by placing field in a
+     * shared abstract class.
+     */
+    static class Index<K,V> {
+        final Node<K,V> node;
+        final Index<K,V> down;
+        volatile Index<K,V> right;
+
+        /**
+         * Creates index node with given values.
+         */
+        Index(Node<K,V> node, Index<K,V> down, Index<K,V> right) {
+            this.node = node;
+            this.down = down;
+            this.right = right;
+        }
+
+        /** Updater for casRight */
+        static final AtomicReferenceFieldUpdater<Index, Index>
+            rightUpdater = AtomicReferenceFieldUpdater.newUpdater
+            (Index.class, Index.class, "right");
+
+        /**
+         * compareAndSet right field
+         */
+        final boolean casRight(Index<K,V> cmp, Index<K,V> val) {
+            return rightUpdater.compareAndSet(this, cmp, val);
+        }
+
+        /**
+         * Returns true if the node this indexes has been deleted.
+         * @return true if indexed node is known to be deleted
+         */
+        final boolean indexesDeletedNode() {
+            return node.value == null;
+        }
+
+        /**
+         * Tries to CAS newSucc as successor.  To minimize races with
+         * unlink that may lose this index node, if the node being
+         * indexed is known to be deleted, it doesn't try to link in.
+         * @param succ the expected current successor
+         * @param newSucc the new successor
+         * @return true if successful
+         */
+        final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
+            Node<K,V> n = node;
+            newSucc.right = succ;
+            return n.value != null && casRight(succ, newSucc);
+        }
+
+        /**
+         * Tries to CAS right field to skip over apparent successor
+         * succ.  Fails (forcing a retraversal by caller) if this node
+         * is known to be deleted.
+         * @param succ the expected current successor
+         * @return true if successful
+         */
+        final boolean unlink(Index<K,V> succ) {
+            return !indexesDeletedNode() && casRight(succ, succ.right);
+        }
+    }
+
+    /* ---------------- Head nodes -------------- */
+
+    /**
+     * Nodes heading each level keep track of their level.
+     */
+    static final class HeadIndex<K,V> extends Index<K,V> {
+        final int level;
+        HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
+            super(node, down, right);
+            this.level = level;
+        }
+    }
+
+    /* ---------------- Comparison utilities -------------- */
+
+    /**
+     * Represents a key with a comparator as a Comparable.
+     *
+     * Because most sorted collections seem to use natural ordering on
+     * Comparables (Strings, Integers, etc), most internal methods are
+     * geared to use them. This is generally faster than checking
+     * per-comparison whether to use comparator or comparable because
+     * it doesn't require a (Comparable) cast for each comparison.
+     * (Optimizers can only sometimes remove such redundant checks
+     * themselves.) When Comparators are used,
+     * ComparableUsingComparators are created so that they act in the
+     * same way as natural orderings. This penalizes use of
+     * Comparators vs Comparables, which seems like the right
+     * tradeoff.
+     */
+    static final class ComparableUsingComparator<K> implements Comparable<K> {
+        final K actualKey;
+        final Comparator<? super K> cmp;
+        ComparableUsingComparator(K key, Comparator<? super K> cmp) {
+            this.actualKey = key;
+            this.cmp = cmp;
+        }
+        public int compareTo(K k2) {
+            return cmp.compare(actualKey, k2);
+        }
+    }
+
+    /**
+     * If using comparator, return a ComparableUsingComparator, else
+     * cast key as Comparable, which may cause ClassCastException,
+     * which is propagated back to caller.
+     */
+    private Comparable<? super K> comparable(Object key) throws ClassCastException {
+        if (key == null)
+            throw new NullPointerException();
+        if (comparator != null)
+            return new ComparableUsingComparator<K>((K)key, comparator);
+        else
+            return (Comparable<? super K>)key;
+    }
+
+    /**
+     * Compares using comparator or natural ordering. Used when the
+     * ComparableUsingComparator approach doesn't apply.
+     */
+    int compare(K k1, K k2) throws ClassCastException {
+        Comparator<? super K> cmp = comparator;
+        if (cmp != null)
+            return cmp.compare(k1, k2);
+        else
+            return ((Comparable<? super K>)k1).compareTo(k2);
+    }
+
+    /**
+     * Returns true if given key greater than or equal to least and
+     * strictly less than fence, bypassing either test if least or
+     * fence are null. Needed mainly in submap operations.
+     */
+    boolean inHalfOpenRange(K key, K least, K fence) {
+        if (key == null)
+            throw new NullPointerException();
+        return ((least == null || compare(key, least) >= 0) &&
+                (fence == null || compare(key, fence) <  0));
+    }
+
+    /**
+     * Returns true if given key greater than or equal to least and less
+     * or equal to fence. Needed mainly in submap operations.
+     */
+    boolean inOpenRange(K key, K least, K fence) {
+        if (key == null)
+            throw new NullPointerException();
+        return ((least == null || compare(key, least) >= 0) &&
+                (fence == null || compare(key, fence) <= 0));
+    }
+
+    /* ---------------- Traversal -------------- */
+
+    /**
+     * Returns a base-level node with key strictly less than given key,
+     * or the base-level header if there is no such node.  Also
+     * unlinks indexes to deleted nodes found along the way.  Callers
+     * rely on this side-effect of clearing indices to deleted nodes.
+     * @param key the key
+     * @return a predecessor of key
+     */
+    private Node<K,V> findPredecessor(Comparable<? super K> key) {
+        if (key == null)
+            throw new NullPointerException(); // don't postpone errors
+        for (;;) {
+            Index<K,V> q = head;
+            Index<K,V> r = q.right;
+            for (;;) {
+                if (r != null) {
+                    Node<K,V> n = r.node;
+                    K k = n.key;
+                    if (n.value == null) {
+                        if (!q.unlink(r))
+                            break;           // restart
+                        r = q.right;         // reread r
+                        continue;
+                    }
+                    if (key.compareTo(k) > 0) {
+                        q = r;
+                        r = r.right;
+                        continue;
+                    }
+                }
+                Index<K,V> d = q.down;
+                if (d != null) {
+                    q = d;
+                    r = d.right;
+                } else
+                    return q.node;
+            }
+        }
+    }
+
+    /**
+     * Returns node holding key or null if no such, clearing out any
+     * deleted nodes seen along the way.  Repeatedly traverses at
+     * base-level looking for key starting at predecessor returned
+     * from findPredecessor, processing base-level deletions as
+     * encountered. Some callers rely on this side-effect of clearing
+     * deleted nodes.
+     *
+     * Restarts occur, at traversal step centered on node n, if:
+     *
+     *   (1) After reading n's next field, n is no longer assumed
+     *       predecessor b's current successor, which means that
+     *       we don't have a consistent 3-node snapshot and so cannot
+     *       unlink any subsequent deleted nodes encountered.
+     *
+     *   (2) n's value field is null, indicating n is deleted, in
+     *       which case we help out an ongoing structural deletion
+     *       before retrying.  Even though there are cases where such
+     *       unlinking doesn't require restart, they aren't sorted out
+     *       here because doing so would not usually outweigh cost of
+     *       restarting.
+     *
+     *   (3) n is a marker or n's predecessor's value field is null,
+     *       indicating (among other possibilities) that
+     *       findPredecessor returned a deleted node. We can't unlink
+     *       the node because we don't know its predecessor, so rely
+     *       on another call to findPredecessor to notice and return
+     *       some earlier predecessor, which it will do. This check is
+     *       only strictly needed at beginning of loop, (and the
+     *       b.value check isn't strictly needed at all) but is done
+     *       each iteration to help avoid contention with other
+     *       threads by callers that will fail to be able to change
+     *       links, and so will retry anyway.
+     *
+     * The traversal loops in doPut, doRemove, and findNear all
+     * include the same three kinds of checks. And specialized
+     * versions appear in findFirst, and findLast and their
+     * variants. They can't easily share code because each uses the
+     * reads of fields held in locals occurring in the orders they
+     * were performed.
+     *
+     * @param key the key
+     * @return node holding key, or null if no such
+     */
+    private Node<K,V> findNode(Comparable<? super K> key) {
+        for (;;) {
+            Node<K,V> b = findPredecessor(key);
+            Node<K,V> n = b.next;
+            for (;;) {
+                if (n == null)
+                    return null;
+                Node<K,V> f = n.next;
+                if (n != b.next)                // inconsistent read
+                    break;
+                Object v = n.value;
+                if (v == null) {                // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (v == n || b.value == null)  // b is deleted
+                    break;
+                int c = key.compareTo(n.key);
+                if (c == 0)
+                    return n;
+                if (c < 0)
+                    return null;
+                b = n;
+                n = f;
+            }
+        }
+    }
+
+    /**
+     * Specialized variant of findNode to perform Map.get. Does a weak
+     * traversal, not bothering to fix any deleted index nodes,
+     * returning early if it happens to see key in index, and passing
+     * over any deleted base nodes, falling back to getUsingFindNode
+     * only if it would otherwise return value from an ongoing
+     * deletion. Also uses "bound" to eliminate need for some
+     * comparisons (see Pugh Cookbook). Also folds uses of null checks
+     * and node-skipping because markers have null keys.
+     * @param okey the key
+     * @return the value, or null if absent
+     */
+    private V doGet(Object okey) {
+        Comparable<? super K> key = comparable(okey);
+        Node<K,V> bound = null;
+        Index<K,V> q = head;
+        Index<K,V> r = q.right;
+        Node<K,V> n;
+        K k;
+        int c;
+        for (;;) {
+            Index<K,V> d;
+            // Traverse rights
+            if (r != null && (n = r.node) != bound && (k = n.key) != null) {
+                if ((c = key.compareTo(k)) > 0) {
+                    q = r;
+                    r = r.right;
+                    continue;
+                } else if (c == 0) {
+                    Object v = n.value;
+                    return (v != null)? (V)v : getUsingFindNode(key);
+                } else
+                    bound = n;
+            }
+
+            // Traverse down
+            if ((d = q.down) != null) {
+                q = d;
+                r = d.right;
+            } else
+                break;
+        }
+
+        // Traverse nexts
+        for (n = q.node.next;  n != null; n = n.next) {
+            if ((k = n.key) != null) {
+                if ((c = key.compareTo(k)) == 0) {
+                    Object v = n.value;
+                    return (v != null)? (V)v : getUsingFindNode(key);
+                } else if (c < 0)
+                    break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Performs map.get via findNode.  Used as a backup if doGet
+     * encounters an in-progress deletion.
+     * @param key the key
+     * @return the value, or null if absent
+     */
+    private V getUsingFindNode(Comparable<? super K> key) {
+        /*
+         * Loop needed here and elsewhere in case value field goes
+         * null just as it is about to be returned, in which case we
+         * lost a race with a deletion, so must retry.
+         */
+        for (;;) {
+            Node<K,V> n = findNode(key);
+            if (n == null)
+                return null;
+            Object v = n.value;
+            if (v != null)
+                return (V)v;
+        }
+    }
+
+    /* ---------------- Insertion -------------- */
+
+    /**
+     * Main insertion method.  Adds element if not present, or
+     * replaces value if present and onlyIfAbsent is false.
+     * @param kkey the key
+     * @param value  the value that must be associated with key
+     * @param onlyIfAbsent if should not insert if already present
+     * @return the old value, or null if newly inserted
+     */
+    private V doPut(K kkey, V value, boolean onlyIfAbsent) {
+        Comparable<? super K> key = comparable(kkey);
+        for (;;) {
+            Node<K,V> b = findPredecessor(key);
+            Node<K,V> n = b.next;
+            for (;;) {
+                if (n != null) {
+                    Node<K,V> f = n.next;
+                    if (n != b.next)               // inconsistent read
+                        break;
+                    Object v = n.value;
+                    if (v == null) {               // n is deleted
+                        n.helpDelete(b, f);
+                        break;
+                    }
+                    if (v == n || b.value == null) // b is deleted
+                        break;
+                    int c = key.compareTo(n.key);
+                    if (c > 0) {
+                        b = n;
+                        n = f;
+                        continue;
+                    }
+                    if (c == 0) {
+                        if (onlyIfAbsent || n.casValue(v, value))
+                            return (V)v;
+                        else
+                            break; // restart if lost race to replace value
+                    }
+                    // else c < 0; fall through
+                }
+
+                Node<K,V> z = new Node<K,V>(kkey, value, n);
+                if (!b.casNext(n, z))
+                    break;         // restart if lost race to append to b
+                int level = randomLevel();
+                if (level > 0)
+                    insertIndex(z, level);
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Returns a random level for inserting a new node.
+     * Hardwired to k=1, p=0.5, max 31 (see above and
+     * Pugh's "Skip List Cookbook", sec 3.4).
+     *
+     * This uses the simplest of the generators described in George
+     * Marsaglia's "Xorshift RNGs" paper.  This is not a high-quality
+     * generator but is acceptable here.
+     */
+    private int randomLevel() {
+        int x = randomSeed;
+        x ^= x << 13;
+        x ^= x >>> 17;
+        randomSeed = x ^= x << 5;
+        if ((x & 0x8001) != 0) // test highest and lowest bits
+            return 0;
+        int level = 1;
+        while (((x >>>= 1) & 1) != 0) ++level;
+        return level;
+    }
+
+    /**
+     * Creates and adds index nodes for the given node.
+     * @param z the node
+     * @param level the level of the index
+     */
+    private void insertIndex(Node<K,V> z, int level) {
+        HeadIndex<K,V> h = head;
+        int max = h.level;
+
+        if (level <= max) {
+            Index<K,V> idx = null;
+            for (int i = 1; i <= level; ++i)
+                idx = new Index<K,V>(z, idx, null);
+            addIndex(idx, h, level);
+
+        } else { // Add a new level
+            /*
+             * To reduce interference by other threads checking for
+             * empty levels in tryReduceLevel, new levels are added
+             * with initialized right pointers. Which in turn requires
+             * keeping levels in an array to access them while
+             * creating new head index nodes from the opposite
+             * direction.
+             */
+            level = max + 1;
+            Index<K,V>[] idxs = (Index<K,V>[])new Index[level+1];
+            Index<K,V> idx = null;
+            for (int i = 1; i <= level; ++i)
+                idxs[i] = idx = new Index<K,V>(z, idx, null);
+
+            HeadIndex<K,V> oldh;
+            int k;
+            for (;;) {
+                oldh = head;
+                int oldLevel = oldh.level;
+                if (level <= oldLevel) { // lost race to add level
+                    k = level;
+                    break;
+                }
+                HeadIndex<K,V> newh = oldh;
+                Node<K,V> oldbase = oldh.node;
+                for (int j = oldLevel+1; j <= level; ++j)
+                    newh = new HeadIndex<K,V>(oldbase, newh, idxs[j], j);
+                if (casHead(oldh, newh)) {
+                    k = oldLevel;
+                    break;
+                }
+            }
+            addIndex(idxs[k], oldh, k);
+        }
+    }
+
+    /**
+     * Adds given index nodes from given level down to 1.
+     * @param idx the topmost index node being inserted
+     * @param h the value of head to use to insert. This must be
+     * snapshotted by callers to provide correct insertion level
+     * @param indexLevel the level of the index
+     */
+    private void addIndex(Index<K,V> idx, HeadIndex<K,V> h, int indexLevel) {
+        // Track next level to insert in case of retries
+        int insertionLevel = indexLevel;
+        Comparable<? super K> key = comparable(idx.node.key);
+        if (key == null) throw new NullPointerException();
+
+        // Similar to findPredecessor, but adding index nodes along
+        // path to key.
+        for (;;) {
+            int j = h.level;
+            Index<K,V> q = h;
+            Index<K,V> r = q.right;
+            Index<K,V> t = idx;
+            for (;;) {
+                if (r != null) {
+                    Node<K,V> n = r.node;
+                    // compare before deletion check avoids needing recheck
+                    int c = key.compareTo(n.key);
+                    if (n.value == null) {
+                        if (!q.unlink(r))
+                            break;
+                        r = q.right;
+                        continue;
+                    }
+                    if (c > 0) {
+                        q = r;
+                        r = r.right;
+                        continue;
+                    }
+                }
+
+                if (j == insertionLevel) {
+                    // Don't insert index if node already deleted
+                    if (t.indexesDeletedNode()) {
+                        findNode(key); // cleans up
+                        return;
+                    }
+                    if (!q.link(r, t))
+                        break; // restart
+                    if (--insertionLevel == 0) {
+                        // need final deletion check before return
+                        if (t.indexesDeletedNode())
+                            findNode(key);
+                        return;
+                    }
+                }
+
+                if (--j >= insertionLevel && j < indexLevel)
+                    t = t.down;
+                q = q.down;
+                r = q.right;
+            }
+        }
+    }
+
+    /* ---------------- Deletion -------------- */
+
+    /**
+     * Main deletion method. Locates node, nulls value, appends a
+     * deletion marker, unlinks predecessor, removes associated index
+     * nodes, and possibly reduces head index level.
+     *
+     * Index nodes are cleared out simply by calling findPredecessor.
+     * which unlinks indexes to deleted nodes found along path to key,
+     * which will include the indexes to this node.  This is done
+     * unconditionally. We can't check beforehand whether there are
+     * index nodes because it might be the case that some or all
+     * indexes hadn't been inserted yet for this node during initial
+     * search for it, and we'd like to ensure lack of garbage
+     * retention, so must call to be sure.
+     *
+     * @param okey the key
+     * @param value if non-null, the value that must be
+     * associated with key
+     * @return the node, or null if not found
+     */
+    final V doRemove(Object okey, Object value) {
+        Comparable<? super K> key = comparable(okey);
+        for (;;) {
+            Node<K,V> b = findPredecessor(key);
+            Node<K,V> n = b.next;
+            for (;;) {
+                if (n == null)
+                    return null;
+                Node<K,V> f = n.next;
+                if (n != b.next)                    // inconsistent read
+                    break;
+                Object v = n.value;
+                if (v == null) {                    // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (v == n || b.value == null)      // b is deleted
+                    break;
+                int c = key.compareTo(n.key);
+                if (c < 0)
+                    return null;
+                if (c > 0) {
+                    b = n;
+                    n = f;
+                    continue;
+                }
+                if (value != null && !value.equals(v))
+                    return null;
+                if (!n.casValue(v, null))
+                    break;
+                if (!n.appendMarker(f) || !b.casNext(n, f))
+                    findNode(key);                  // Retry via findNode
+                else {
+                    findPredecessor(key);           // Clean index
+                    if (head.right == null)
+                        tryReduceLevel();
+                }
+                return (V)v;
+            }
+        }
+    }
+
+    /**
+     * Possibly reduce head level if it has no nodes.  This method can
+     * (rarely) make mistakes, in which case levels can disappear even
+     * though they are about to contain index nodes. This impacts
+     * performance, not correctness.  To minimize mistakes as well as
+     * to reduce hysteresis, the level is reduced by one only if the
+     * topmost three levels look empty. Also, if the removed level
+     * looks non-empty after CAS, we try to change it back quick
+     * before anyone notices our mistake! (This trick works pretty
+     * well because this method will practically never make mistakes
+     * unless current thread stalls immediately before first CAS, in
+     * which case it is very unlikely to stall again immediately
+     * afterwards, so will recover.)
+     *
+     * We put up with all this rather than just let levels grow
+     * because otherwise, even a small map that has undergone a large
+     * number of insertions and removals will have a lot of levels,
+     * slowing down access more than would an occasional unwanted
+     * reduction.
+     */
+    private void tryReduceLevel() {
+        HeadIndex<K,V> h = head;
+        HeadIndex<K,V> d;
+        HeadIndex<K,V> e;
+        if (h.level > 3 &&
+            (d = (HeadIndex<K,V>)h.down) != null &&
+            (e = (HeadIndex<K,V>)d.down) != null &&
+            e.right == null &&
+            d.right == null &&
+            h.right == null &&
+            casHead(h, d) && // try to set
+            h.right != null) // recheck
+            casHead(d, h);   // try to backout
+    }
+
+    /* ---------------- Finding and removing first element -------------- */
+
+    /**
+     * Specialized variant of findNode to get first valid node.
+     * @return first node or null if empty
+     */
+    Node<K,V> findFirst() {
+        for (;;) {
+            Node<K,V> b = head.node;
+            Node<K,V> n = b.next;
+            if (n == null)
+                return null;
+            if (n.value != null)
+                return n;
+            n.helpDelete(b, n.next);
+        }
+    }
+
+    /**
+     * Removes first entry; returns its snapshot.
+     * @return null if empty, else snapshot of first entry
+     */
+    Map.Entry<K,V> doRemoveFirstEntry() {
+        for (;;) {
+            Node<K,V> b = head.node;
+            Node<K,V> n = b.next;
+            if (n == null)
+                return null;
+            Node<K,V> f = n.next;
+            if (n != b.next)
+                continue;
+            Object v = n.value;
+            if (v == null) {
+                n.helpDelete(b, f);
+                continue;
+            }
+            if (!n.casValue(v, null))
+                continue;
+            if (!n.appendMarker(f) || !b.casNext(n, f))
+                findFirst(); // retry
+            clearIndexToFirst();
+            return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, (V)v);
+        }
+    }
+
+    /**
+     * Clears out index nodes associated with deleted first entry.
+     */
+    private void clearIndexToFirst() {
+        for (;;) {
+            Index<K,V> q = head;
+            for (;;) {
+                Index<K,V> r = q.right;
+                if (r != null && r.indexesDeletedNode() && !q.unlink(r))
+                    break;
+                if ((q = q.down) == null) {
+                    if (head.right == null)
+                        tryReduceLevel();
+                    return;
+                }
+            }
+        }
+    }
+
+
+    /* ---------------- Finding and removing last element -------------- */
+
+    /**
+     * Specialized version of find to get last valid node.
+     * @return last node or null if empty
+     */
+    Node<K,V> findLast() {
+        /*
+         * findPredecessor can't be used to traverse index level
+         * because this doesn't use comparisons.  So traversals of
+         * both levels are folded together.
+         */
+        Index<K,V> q = head;
+        for (;;) {
+            Index<K,V> d, r;
+            if ((r = q.right) != null) {
+                if (r.indexesDeletedNode()) {
+                    q.unlink(r);
+                    q = head; // restart
+                }
+                else
+                    q = r;
+            } else if ((d = q.down) != null) {
+                q = d;
+            } else {
+                Node<K,V> b = q.node;
+                Node<K,V> n = b.next;
+                for (;;) {
+                    if (n == null)
+                        return (b.isBaseHeader())? null : b;
+                    Node<K,V> f = n.next;            // inconsistent read
+                    if (n != b.next)
+                        break;
+                    Object v = n.value;
+                    if (v == null) {                 // n is deleted
+                        n.helpDelete(b, f);
+                        break;
+                    }
+                    if (v == n || b.value == null)   // b is deleted
+                        break;
+                    b = n;
+                    n = f;
+                }
+                q = head; // restart
+            }
+        }
+    }
+
+    /**
+     * Specialized variant of findPredecessor to get predecessor of last
+     * valid node.  Needed when removing the last entry.  It is possible
+     * that all successors of returned node will have been deleted upon
+     * return, in which case this method can be retried.
+     * @return likely predecessor of last node
+     */
+    private Node<K,V> findPredecessorOfLast() {
+        for (;;) {
+            Index<K,V> q = head;
+            for (;;) {
+                Index<K,V> d, r;
+                if ((r = q.right) != null) {
+                    if (r.indexesDeletedNode()) {
+                        q.unlink(r);
+                        break;    // must restart
+                    }
+                    // proceed as far across as possible without overshooting
+                    if (r.node.next != null) {
+                        q = r;
+                        continue;
+                    }
+                }
+                if ((d = q.down) != null)
+                    q = d;
+                else
+                    return q.node;
+            }
+        }
+    }
+
+    /**
+     * Removes last entry; returns its snapshot.
+     * Specialized variant of doRemove.
+     * @return null if empty, else snapshot of last entry
+     */
+    Map.Entry<K,V> doRemoveLastEntry() {
+        for (;;) {
+            Node<K,V> b = findPredecessorOfLast();
+            Node<K,V> n = b.next;
+            if (n == null) {
+                if (b.isBaseHeader())               // empty
+                    return null;
+                else
+                    continue; // all b's successors are deleted; retry
+            }
+            for (;;) {
+                Node<K,V> f = n.next;
+                if (n != b.next)                    // inconsistent read
+                    break;
+                Object v = n.value;
+                if (v == null) {                    // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (v == n || b.value == null)      // b is deleted
+                    break;
+                if (f != null) {
+                    b = n;
+                    n = f;
+                    continue;
+                }
+                if (!n.casValue(v, null))
+                    break;
+                K key = n.key;
+                Comparable<? super K> ck = comparable(key);
+                if (!n.appendMarker(f) || !b.casNext(n, f))
+                    findNode(ck);                  // Retry via findNode
+                else {
+                    findPredecessor(ck);           // Clean index
+                    if (head.right == null)
+                        tryReduceLevel();
+                }
+                return new AbstractMap.SimpleImmutableEntry<K,V>(key, (V)v);
+            }
+        }
+    }
+
+    /* ---------------- Relational operations -------------- */
+
+    // Control values OR'ed as arguments to findNear
+
+    private static final int EQ = 1;
+    private static final int LT = 2;
+    private static final int GT = 0; // Actually checked as !LT
+
+    /**
+     * Utility for ceiling, floor, lower, higher methods.
+     * @param kkey the key
+     * @param rel the relation -- OR'ed combination of EQ, LT, GT
+     * @return nearest node fitting relation, or null if no such
+     */
+    Node<K,V> findNear(K kkey, int rel) {
+        Comparable<? super K> key = comparable(kkey);
+        for (;;) {
+            Node<K,V> b = findPredecessor(key);
+            Node<K,V> n = b.next;
+            for (;;) {
+                if (n == null)
+                    return ((rel & LT) == 0 || b.isBaseHeader())? null : b;
+                Node<K,V> f = n.next;
+                if (n != b.next)                  // inconsistent read
+                    break;
+                Object v = n.value;
+                if (v == null) {                  // n is deleted
+                    n.helpDelete(b, f);
+                    break;
+                }
+                if (v == n || b.value == null)    // b is deleted
+                    break;
+                int c = key.compareTo(n.key);
+                if ((c == 0 && (rel & EQ) != 0) ||
+                    (c <  0 && (rel & LT) == 0))
+                    return n;
+                if ( c <= 0 && (rel & LT) != 0)
+                    return (b.isBaseHeader())? null : b;
+                b = n;
+                n = f;
+            }
+        }
+    }
+
+    /**
+     * Returns SimpleImmutableEntry for results of findNear.
+     * @param key the key
+     * @param rel the relation -- OR'ed combination of EQ, LT, GT
+     * @return Entry fitting relation, or null if no such
+     */
+    AbstractMap.SimpleImmutableEntry<K,V> getNear(K key, int rel) {
+        for (;;) {
+            Node<K,V> n = findNear(key, rel);
+            if (n == null)
+                return null;
+            AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
+            if (e != null)
+                return e;
+        }
+    }
+
+
+    /* ---------------- Constructors -------------- */
+
+    /**
+     * Constructs a new, empty map, sorted according to the
+     * {@linkplain Comparable natural ordering} of the keys.
+     */
+    public ConcurrentSkipListMap() {
+        this.comparator = null;
+        initialize();
+    }
+
+    /**
+     * Constructs a new, empty map, sorted according to the specified
+     * comparator.
+     *
+     * @param comparator the comparator that will be used to order this map.
+     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        ordering} of the keys will be used.
+     */
+    public ConcurrentSkipListMap(Comparator<? super K> comparator) {
+        this.comparator = comparator;
+        initialize();
+    }
+
+    /**
+     * Constructs a new map containing the same mappings as the given map,
+     * sorted according to the {@linkplain Comparable natural ordering} of
+     * the keys.
+     *
+     * @param  m the map whose mappings are to be placed in this map
+     * @throws ClassCastException if the keys in <tt>m</tt> are not
+     *         {@link Comparable}, or are not mutually comparable
+     * @throws NullPointerException if the specified map or any of its keys
+     *         or values are null
+     */
+    public ConcurrentSkipListMap(Map<? extends K, ? extends V> m) {
+        this.comparator = null;
+        initialize();
+        putAll(m);
+    }
+
+    /**
+     * Constructs a new map containing the same mappings and using the
+     * same ordering as the specified sorted map.
+     *
+     * @param m the sorted map whose mappings are to be placed in this
+     *        map, and whose comparator is to be used to sort this map
+     * @throws NullPointerException if the specified sorted map or any of
+     *         its keys or values are null
+     */
+    public ConcurrentSkipListMap(SortedMap<K, ? extends V> m) {
+        this.comparator = m.comparator();
+        initialize();
+        buildFromSorted(m);
+    }
+
+    /**
+     * Returns a shallow copy of this <tt>ConcurrentSkipListMap</tt>
+     * instance. (The keys and values themselves are not cloned.)
+     *
+     * @return a shallow copy of this map
+     */
+    public ConcurrentSkipListMap<K,V> clone() {
+        ConcurrentSkipListMap<K,V> clone = null;
+        try {
+            clone = (ConcurrentSkipListMap<K,V>) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+
+        clone.initialize();
+        clone.buildFromSorted(this);
+        return clone;
+    }
+
+    /**
+     * Streamlined bulk insertion to initialize from elements of
+     * given sorted map.  Call only from constructor or clone
+     * method.
+     */
+    private void buildFromSorted(SortedMap<K, ? extends V> map) {
+        if (map == null)
+            throw new NullPointerException();
+
+        HeadIndex<K,V> h = head;
+        Node<K,V> basepred = h.node;
+
+        // Track the current rightmost node at each level. Uses an
+        // ArrayList to avoid committing to initial or maximum level.
+        ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
+
+        // initialize
+        for (int i = 0; i <= h.level; ++i)
+            preds.add(null);
+        Index<K,V> q = h;
+        for (int i = h.level; i > 0; --i) {
+            preds.set(i, q);
+            q = q.down;
+        }
+
+        Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
+            map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<? extends K, ? extends V> e = it.next();
+            int j = randomLevel();
+            if (j > h.level) j = h.level + 1;
+            K k = e.getKey();
+            V v = e.getValue();
+            if (k == null || v == null)
+                throw new NullPointerException();
+            Node<K,V> z = new Node<K,V>(k, v, null);
+            basepred.next = z;
+            basepred = z;
+            if (j > 0) {
+                Index<K,V> idx = null;
+                for (int i = 1; i <= j; ++i) {
+                    idx = new Index<K,V>(z, idx, null);
+                    if (i > h.level)
+                        h = new HeadIndex<K,V>(h.node, h, idx, i);
+
+                    if (i < preds.size()) {
+                        preds.get(i).right = idx;
+                        preds.set(i, idx);
+                    } else
+                        preds.add(idx);
+                }
+            }
+        }
+        head = h;
+    }
+
+    /* ---------------- Serialization -------------- */
+
+    /**
+     * Save the state of this map to a stream.
+     *
+     * @serialData The key (Object) and value (Object) for each
+     * key-value mapping represented by the map, followed by
+     * <tt>null</tt>. The key-value mappings are emitted in key-order
+     * (as determined by the Comparator, or by the keys' natural
+     * ordering if no Comparator).
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+        // Write out the Comparator and any hidden stuff
+        s.defaultWriteObject();
+
+        // Write out keys and values (alternating)
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            V v = n.getValidValue();
+            if (v != null) {
+                s.writeObject(n.key);
+                s.writeObject(v);
+            }
+        }
+        s.writeObject(null);
+    }
+
+    /**
+     * Reconstitute the map from a stream.
+     */
+    private void readObject(final java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        // Read in the Comparator and any hidden stuff
+        s.defaultReadObject();
+        // Reset transients
+        initialize();
+
+        /*
+         * This is nearly identical to buildFromSorted, but is
+         * distinct because readObject calls can't be nicely adapted
+         * as the kind of iterator needed by buildFromSorted. (They
+         * can be, but doing so requires type cheats and/or creation
+         * of adaptor classes.) It is simpler to just adapt the code.
+         */
+
+        HeadIndex<K,V> h = head;
+        Node<K,V> basepred = h.node;
+        ArrayList<Index<K,V>> preds = new ArrayList<Index<K,V>>();
+        for (int i = 0; i <= h.level; ++i)
+            preds.add(null);
+        Index<K,V> q = h;
+        for (int i = h.level; i > 0; --i) {
+            preds.set(i, q);
+            q = q.down;
+        }
+
+        for (;;) {
+            Object k = s.readObject();
+            if (k == null)
+                break;
+            Object v = s.readObject();
+            if (v == null)
+                throw new NullPointerException();
+            K key = (K) k;
+            V val = (V) v;
+            int j = randomLevel();
+            if (j > h.level) j = h.level + 1;
+            Node<K,V> z = new Node<K,V>(key, val, null);
+            basepred.next = z;
+            basepred = z;
+            if (j > 0) {
+                Index<K,V> idx = null;
+                for (int i = 1; i <= j; ++i) {
+                    idx = new Index<K,V>(z, idx, null);
+                    if (i > h.level)
+                        h = new HeadIndex<K,V>(h.node, h, idx, i);
+
+                    if (i < preds.size()) {
+                        preds.get(i).right = idx;
+                        preds.set(i, idx);
+                    } else
+                        preds.add(idx);
+                }
+            }
+        }
+        head = h;
+    }
+
+    /* ------ Map API methods ------ */
+
+    /**
+     * Returns <tt>true</tt> if this map contains a mapping for the specified
+     * key.
+     *
+     * @param key key whose presence in this map is to be tested
+     * @return <tt>true</tt> if this map contains a mapping for the specified key
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key is null
+     */
+    public boolean containsKey(Object key) {
+        return doGet(key) != null;
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
+     *
+     * <p>More formally, if this map contains a mapping from a key
+     * {@code k} to a value {@code v} such that {@code key} compares
+     * equal to {@code k} according to the map's ordering, then this
+     * method returns {@code v}; otherwise it returns {@code null}.
+     * (There can be at most one such mapping.)
+     *
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key is null
+     */
+    public V get(Object key) {
+        return doGet(key);
+    }
+
+    /**
+     * Associates the specified value with the specified key in this map.
+     * If the map previously contained a mapping for the key, the old
+     * value is replaced.
+     *
+     * @param key key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     * @return the previous value associated with the specified key, or
+     *         <tt>null</tt> if there was no mapping for the key
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key or value is null
+     */
+    public V put(K key, V value) {
+        if (value == null)
+            throw new NullPointerException();
+        return doPut(key, value, false);
+    }
+
+    /**
+     * Removes the mapping for the specified key from this map if present.
+     *
+     * @param  key key for which mapping should be removed
+     * @return the previous value associated with the specified key, or
+     *         <tt>null</tt> if there was no mapping for the key
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key is null
+     */
+    public V remove(Object key) {
+        return doRemove(key, null);
+    }
+
+    /**
+     * Returns <tt>true</tt> if this map maps one or more keys to the
+     * specified value.  This operation requires time linear in the
+     * map size.
+     *
+     * @param value value whose presence in this map is to be tested
+     * @return <tt>true</tt> if a mapping to <tt>value</tt> exists;
+     *         <tt>false</tt> otherwise
+     * @throws NullPointerException if the specified value is null
+     */
+    public boolean containsValue(Object value) {
+        if (value == null)
+            throw new NullPointerException();
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            V v = n.getValidValue();
+            if (v != null && value.equals(v))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the number of key-value mappings in this map.  If this map
+     * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
+     * returns <tt>Integer.MAX_VALUE</tt>.
+     *
+     * <p>Beware that, unlike in most collections, this method is
+     * <em>NOT</em> a constant-time operation. Because of the
+     * asynchronous nature of these maps, determining the current
+     * number of elements requires traversing them all to count them.
+     * Additionally, it is possible for the size to change during
+     * execution of this method, in which case the returned result
+     * will be inaccurate. Thus, this method is typically not very
+     * useful in concurrent applications.
+     *
+     * @return the number of elements in this map
+     */
+    public int size() {
+        long count = 0;
+        for (Node<K,V> n = findFirst(); n != null; n = n.next) {
+            if (n.getValidValue() != null)
+                ++count;
+        }
+        return (count >= Integer.MAX_VALUE)? Integer.MAX_VALUE : (int)count;
+    }
+
+    /**
+     * Returns <tt>true</tt> if this map contains no key-value mappings.
+     * @return <tt>true</tt> if this map contains no key-value mappings
+     */
+    public boolean isEmpty() {
+        return findFirst() == null;
+    }
+
+    /**
+     * Removes all of the mappings from this map.
+     */
+    public void clear() {
+        initialize();
+    }
+
+    /* ---------------- View methods -------------- */
+
+    /*
+     * Note: Lazy initialization works for views because view classes
+     * are stateless/immutable so it doesn't matter wrt correctness if
+     * more than one is created (which will only rarely happen).  Even
+     * so, the following idiom conservatively ensures that the method
+     * returns the one it created if it does so, not one created by
+     * another racing thread.
+     */
+
+    /**
+     * Returns a {@link NavigableSet} view of the keys contained in this map.
+     * The set's iterator returns the keys in ascending order.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the {@code Iterator.remove}, {@code Set.remove},
+     * {@code removeAll}, {@code retainAll}, and {@code clear}
+     * operations.  It does not support the {@code add} or {@code addAll}
+     * operations.
+     *
+     * <p>The view's {@code iterator} is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * <p>This method is equivalent to method {@code navigableKeySet}.
+     *
+     * @return a navigable set view of the keys in this map
+     */
+     public NavigableSet<K> keySet() {
+        KeySet ks = keySet;
+        return (ks != null) ? ks : (keySet = new KeySet(this));
+    }
+
+    public NavigableSet<K> navigableKeySet() {
+        KeySet ks = keySet;
+        return (ks != null) ? ks : (keySet = new KeySet(this));
+    }
+
+    /**
+     * Returns a {@link Collection} view of the values contained in this map.
+     * The collection's iterator returns the values in ascending order
+     * of the corresponding keys.
+     * The collection is backed by the map, so changes to the map are
+     * reflected in the collection, and vice-versa.  The collection
+     * supports element removal, which removes the corresponding
+     * mapping from the map, via the <tt>Iterator.remove</tt>,
+     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
+     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
+     * support the <tt>add</tt> or <tt>addAll</tt> operations.
+     *
+     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public Collection<V> values() {
+        Values vs = values;
+        return (vs != null) ? vs : (values = new Values(this));
+    }
+
+    /**
+     * Returns a {@link Set} view of the mappings contained in this map.
+     * The set's iterator returns the entries in ascending key order.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  The set supports element
+     * removal, which removes the corresponding mapping from the map,
+     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
+     * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
+     * operations.  It does not support the <tt>add</tt> or
+     * <tt>addAll</tt> operations.
+     *
+     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
+     * that will never throw {@link ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * <p>The <tt>Map.Entry</tt> elements returned by
+     * <tt>iterator.next()</tt> do <em>not</em> support the
+     * <tt>setValue</tt> operation.
+     *
+     * @return a set view of the mappings contained in this map,
+     *         sorted in ascending key order
+     */
+    public Set<Map.Entry<K,V>> entrySet() {
+        EntrySet es = entrySet;
+        return (es != null) ? es : (entrySet = new EntrySet(this));
+    }
+
+    public ConcurrentNavigableMap<K,V> descendingMap() {
+        ConcurrentNavigableMap<K,V> dm = descendingMap;
+        return (dm != null) ? dm : (descendingMap = new SubMap<K,V>
+                                    (this, null, false, null, false, true));
+    }
+
+    public NavigableSet<K> descendingKeySet() {
+        return descendingMap().navigableKeySet();
+    }
+
+    /* ---------------- AbstractMap Overrides -------------- */
+
+    /**
+     * Compares the specified object with this map for equality.
+     * Returns <tt>true</tt> if the given object is also a map and the
+     * two maps represent the same mappings.  More formally, two maps
+     * <tt>m1</tt> and <tt>m2</tt> represent the same mappings if
+     * <tt>m1.entrySet().equals(m2.entrySet())</tt>.  This
+     * operation may return misleading results if either map is
+     * concurrently modified during execution of this method.
+     *
+     * @param o object to be compared for equality with this map
+     * @return <tt>true</tt> if the specified object is equal to this map
+     */
+    public boolean equals(Object o) {
+        if (o == this)
+            return true;
+        if (!(o instanceof Map))
+            return false;
+        Map<?,?> m = (Map<?,?>) o;
+        try {
+            for (Map.Entry<K,V> e : this.entrySet())
+                if (! e.getValue().equals(m.get(e.getKey())))
+                    return false;
+            for (Map.Entry<?,?> e : m.entrySet()) {
+                Object k = e.getKey();
+                Object v = e.getValue();
+                if (k == null || v == null || !v.equals(get(k)))
+                    return false;
+            }
+            return true;
+        } catch (ClassCastException unused) {
+            return false;
+        } catch (NullPointerException unused) {
+            return false;
+        }
+    }
+
+    /* ------ ConcurrentMap API methods ------ */
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or <tt>null</tt> if there was no mapping for the key
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key or value is null
+     */
+    public V putIfAbsent(K key, V value) {
+        if (value == null)
+            throw new NullPointerException();
+        return doPut(key, value, true);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key is null
+     */
+    public boolean remove(Object key, Object value) {
+        if (key == null)
+            throw new NullPointerException();
+        if (value == null)
+            return false;
+        return doRemove(key, value) != null;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if any of the arguments are null
+     */
+    public boolean replace(K key, V oldValue, V newValue) {
+        if (oldValue == null || newValue == null)
+            throw new NullPointerException();
+        Comparable<? super K> k = comparable(key);
+        for (;;) {
+            Node<K,V> n = findNode(k);
+            if (n == null)
+                return false;
+            Object v = n.value;
+            if (v != null) {
+                if (!oldValue.equals(v))
+                    return false;
+                if (n.casValue(v, newValue))
+                    return true;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the previous value associated with the specified key,
+     *         or <tt>null</tt> if there was no mapping for the key
+     * @throws ClassCastException if the specified key cannot be compared
+     *         with the keys currently in the map
+     * @throws NullPointerException if the specified key or value is null
+     */
+    public V replace(K key, V value) {
+        if (value == null)
+            throw new NullPointerException();
+        Comparable<? super K> k = comparable(key);
+        for (;;) {
+            Node<K,V> n = findNode(k);
+            if (n == null)
+                return null;
+            Object v = n.value;
+            if (v != null && n.casValue(v, value))
+                return (V)v;
+        }
+    }
+
+    /* ------ SortedMap API methods ------ */
+
+    public Comparator<? super K> comparator() {
+        return comparator;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public K firstKey() {
+        Node<K,V> n = findFirst();
+        if (n == null)
+            throw new NoSuchElementException();
+        return n.key;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public K lastKey() {
+        Node<K,V> n = findLast();
+        if (n == null)
+            throw new NoSuchElementException();
+        return n.key;
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public ConcurrentNavigableMap<K,V> subMap(K fromKey,
+                                              boolean fromInclusive,
+                                              K toKey,
+                                              boolean toInclusive) {
+        if (fromKey == null || toKey == null)
+            throw new NullPointerException();
+        return new SubMap<K,V>
+            (this, fromKey, fromInclusive, toKey, toInclusive, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code toKey} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public ConcurrentNavigableMap<K,V> headMap(K toKey,
+                                               boolean inclusive) {
+        if (toKey == null)
+            throw new NullPointerException();
+        return new SubMap<K,V>
+            (this, null, false, toKey, inclusive, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromKey} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public ConcurrentNavigableMap<K,V> tailMap(K fromKey,
+                                               boolean inclusive) {
+        if (fromKey == null)
+            throw new NullPointerException();
+        return new SubMap<K,V>
+            (this, fromKey, inclusive, null, false, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromKey} or {@code toKey} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey) {
+        return subMap(fromKey, true, toKey, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code toKey} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public ConcurrentNavigableMap<K,V> headMap(K toKey) {
+        return headMap(toKey, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromKey} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public ConcurrentNavigableMap<K,V> tailMap(K fromKey) {
+        return tailMap(fromKey, true);
+    }
+
+    /* ---------------- Relational operations -------------- */
+
+    /**
+     * Returns a key-value mapping associated with the greatest key
+     * strictly less than the given key, or <tt>null</tt> if there is
+     * no such key. The returned entry does <em>not</em> support the
+     * <tt>Entry.setValue</tt> method.
+     *
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public Map.Entry<K,V> lowerEntry(K key) {
+        return getNear(key, LT);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public K lowerKey(K key) {
+        Node<K,V> n = findNear(key, LT);
+        return (n == null)? null : n.key;
+    }
+
+    /**
+     * Returns a key-value mapping associated with the greatest key
+     * less than or equal to the given key, or <tt>null</tt> if there
+     * is no such key. The returned entry does <em>not</em> support
+     * the <tt>Entry.setValue</tt> method.
+     *
+     * @param key the key
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public Map.Entry<K,V> floorEntry(K key) {
+        return getNear(key, LT|EQ);
+    }
+
+    /**
+     * @param key the key
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public K floorKey(K key) {
+        Node<K,V> n = findNear(key, LT|EQ);
+        return (n == null)? null : n.key;
+    }
+
+    /**
+     * Returns a key-value mapping associated with the least key
+     * greater than or equal to the given key, or <tt>null</tt> if
+     * there is no such entry. The returned entry does <em>not</em>
+     * support the <tt>Entry.setValue</tt> method.
+     *
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public Map.Entry<K,V> ceilingEntry(K key) {
+        return getNear(key, GT|EQ);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public K ceilingKey(K key) {
+        Node<K,V> n = findNear(key, GT|EQ);
+        return (n == null)? null : n.key;
+    }
+
+    /**
+     * Returns a key-value mapping associated with the least key
+     * strictly greater than the given key, or <tt>null</tt> if there
+     * is no such key. The returned entry does <em>not</em> support
+     * the <tt>Entry.setValue</tt> method.
+     *
+     * @param key the key
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public Map.Entry<K,V> higherEntry(K key) {
+        return getNear(key, GT);
+    }
+
+    /**
+     * @param key the key
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified key is null
+     */
+    public K higherKey(K key) {
+        Node<K,V> n = findNear(key, GT);
+        return (n == null)? null : n.key;
+    }
+
+    /**
+     * Returns a key-value mapping associated with the least
+     * key in this map, or <tt>null</tt> if the map is empty.
+     * The returned entry does <em>not</em> support
+     * the <tt>Entry.setValue</tt> method.
+     */
+    public Map.Entry<K,V> firstEntry() {
+        for (;;) {
+            Node<K,V> n = findFirst();
+            if (n == null)
+                return null;
+            AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
+            if (e != null)
+                return e;
+        }
+    }
+
+    /**
+     * Returns a key-value mapping associated with the greatest
+     * key in this map, or <tt>null</tt> if the map is empty.
+     * The returned entry does <em>not</em> support
+     * the <tt>Entry.setValue</tt> method.
+     */
+    public Map.Entry<K,V> lastEntry() {
+        for (;;) {
+            Node<K,V> n = findLast();
+            if (n == null)
+                return null;
+            AbstractMap.SimpleImmutableEntry<K,V> e = n.createSnapshot();
+            if (e != null)
+                return e;
+        }
+    }
+
+    /**
+     * Removes and returns a key-value mapping associated with
+     * the least key in this map, or <tt>null</tt> if the map is empty.
+     * The returned entry does <em>not</em> support
+     * the <tt>Entry.setValue</tt> method.
+     */
+    public Map.Entry<K,V> pollFirstEntry() {
+        return doRemoveFirstEntry();
+    }
+
+    /**
+     * Removes and returns a key-value mapping associated with
+     * the greatest key in this map, or <tt>null</tt> if the map is empty.
+     * The returned entry does <em>not</em> support
+     * the <tt>Entry.setValue</tt> method.
+     */
+    public Map.Entry<K,V> pollLastEntry() {
+        return doRemoveLastEntry();
+    }
+
+
+    /* ---------------- Iterators -------------- */
+
+    /**
+     * Base of iterator classes:
+     */
+    abstract class Iter<T> implements Iterator<T> {
+        /** the last node returned by next() */
+        Node<K,V> lastReturned;
+        /** the next node to return from next(); */
+        Node<K,V> next;
+        /** Cache of next value field to maintain weak consistency */
+        V nextValue;
+
+        /** Initializes ascending iterator for entire range. */
+        Iter() {
+            for (;;) {
+                next = findFirst();
+                if (next == null)
+                    break;
+                Object x = next.value;
+                if (x != null && x != next) {
+                    nextValue = (V) x;
+                    break;
+                }
+            }
+        }
+
+        public final boolean hasNext() {
+            return next != null;
+        }
+
+        /** Advances next to higher entry. */
+        final void advance() {
+            if (next == null)
+                throw new NoSuchElementException();
+            lastReturned = next;
+            for (;;) {
+                next = next.next;
+                if (next == null)
+                    break;
+                Object x = next.value;
+                if (x != null && x != next) {
+                    nextValue = (V) x;
+                    break;
+                }
+            }
+        }
+
+        public void remove() {
+            Node<K,V> l = lastReturned;
+            if (l == null)
+                throw new IllegalStateException();
+            // It would not be worth all of the overhead to directly
+            // unlink from here. Using remove is fast enough.
+            ConcurrentSkipListMap.this.remove(l.key);
+            lastReturned = null;
+        }
+
+    }
+
+    final class ValueIterator extends Iter<V> {
+        public V next() {
+            V v = nextValue;
+            advance();
+            return v;
+        }
+    }
+
+    final class KeyIterator extends Iter<K> {
+        public K next() {
+            Node<K,V> n = next;
+            advance();
+            return n.key;
+        }
+    }
+
+    final class EntryIterator extends Iter<Map.Entry<K,V>> {
+        public Map.Entry<K,V> next() {
+            Node<K,V> n = next;
+            V v = nextValue;
+            advance();
+            return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
+        }
+    }
+
+    // Factory methods for iterators needed by ConcurrentSkipListSet etc
+
+    Iterator<K> keyIterator() {
+        return new KeyIterator();
+    }
+
+    Iterator<V> valueIterator() {
+        return new ValueIterator();
+    }
+
+    Iterator<Map.Entry<K,V>> entryIterator() {
+        return new EntryIterator();
+    }
+
+    /* ---------------- View Classes -------------- */
+
+    /*
+     * View classes are static, delegating to a ConcurrentNavigableMap
+     * to allow use by SubMaps, which outweighs the ugliness of
+     * needing type-tests for Iterator methods.
+     */
+
+    static final <E> List<E> toList(Collection<E> c) {
+        // Using size() here would be a pessimization.
+        List<E> list = new ArrayList<E>();
+        for (E e : c)
+            list.add(e);
+        return list;
+    }
+
+    static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
+        private final ConcurrentNavigableMap<E,Object> m;
+        KeySet(ConcurrentNavigableMap<E,Object> map) { m = map; }
+        public int size() { return m.size(); }
+        public boolean isEmpty() { return m.isEmpty(); }
+        public boolean contains(Object o) { return m.containsKey(o); }
+        public boolean remove(Object o) { return m.remove(o) != null; }
+        public void clear() { m.clear(); }
+        public E lower(E e) { return m.lowerKey(e); }
+        public E floor(E e) { return m.floorKey(e); }
+        public E ceiling(E e) { return m.ceilingKey(e); }
+        public E higher(E e) { return m.higherKey(e); }
+        public Comparator<? super E> comparator() { return m.comparator(); }
+        public E first() { return m.firstKey(); }
+        public E last() { return m.lastKey(); }
+        public E pollFirst() {
+            Map.Entry<E,Object> e = m.pollFirstEntry();
+            return e == null? null : e.getKey();
+        }
+        public E pollLast() {
+            Map.Entry<E,Object> e = m.pollLastEntry();
+            return e == null? null : e.getKey();
+        }
+        public Iterator<E> iterator() {
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<E,Object>)m).keyIterator();
+            else
+                return ((ConcurrentSkipListMap.SubMap<E,Object>)m).keyIterator();
+        }
+        public boolean equals(Object o) {
+            if (o == this)
+                return true;
+            if (!(o instanceof Set))
+                return false;
+            Collection<?> c = (Collection<?>) o;
+            try {
+                return containsAll(c) && c.containsAll(this);
+            } catch (ClassCastException unused)   {
+                return false;
+            } catch (NullPointerException unused) {
+                return false;
+            }
+        }
+        public Object[] toArray()     { return toList(this).toArray();  }
+        public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
+        public Iterator<E> descendingIterator() {
+            return descendingSet().iterator();
+        }
+        public NavigableSet<E> subSet(E fromElement,
+                                      boolean fromInclusive,
+                                      E toElement,
+                                      boolean toInclusive) {
+            return new KeySet<E>(m.subMap(fromElement, fromInclusive,
+                                          toElement,   toInclusive));
+        }
+        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
+            return new KeySet<E>(m.headMap(toElement, inclusive));
+        }
+        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+            return new KeySet<E>(m.tailMap(fromElement, inclusive));
+        }
+        public NavigableSet<E> subSet(E fromElement, E toElement) {
+            return subSet(fromElement, true, toElement, false);
+        }
+        public NavigableSet<E> headSet(E toElement) {
+            return headSet(toElement, false);
+        }
+        public NavigableSet<E> tailSet(E fromElement) {
+            return tailSet(fromElement, true);
+        }
+        public NavigableSet<E> descendingSet() {
+            return new KeySet(m.descendingMap());
+        }
+    }
+
+    static final class Values<E> extends AbstractCollection<E> {
+        private final ConcurrentNavigableMap<Object, E> m;
+        Values(ConcurrentNavigableMap<Object, E> map) {
+            m = map;
+        }
+        public Iterator<E> iterator() {
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<Object,E>)m).valueIterator();
+            else
+                return ((SubMap<Object,E>)m).valueIterator();
+        }
+        public boolean isEmpty() {
+            return m.isEmpty();
+        }
+        public int size() {
+            return m.size();
+        }
+        public boolean contains(Object o) {
+            return m.containsValue(o);
+        }
+        public void clear() {
+            m.clear();
+        }
+        public Object[] toArray()     { return toList(this).toArray();  }
+        public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
+    }
+
+    static final class EntrySet<K1,V1> extends AbstractSet<Map.Entry<K1,V1>> {
+        private final ConcurrentNavigableMap<K1, V1> m;
+        EntrySet(ConcurrentNavigableMap<K1, V1> map) {
+            m = map;
+        }
+
+        public Iterator<Map.Entry<K1,V1>> iterator() {
+            if (m instanceof ConcurrentSkipListMap)
+                return ((ConcurrentSkipListMap<K1,V1>)m).entryIterator();
+            else
+                return ((SubMap<K1,V1>)m).entryIterator();
+        }
+
+        public boolean contains(Object o) {
+            if (!(o instanceof Map.Entry))
+                return false;
+            Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
+            V1 v = m.get(e.getKey());
+            return v != null && v.equals(e.getValue());
+        }
+        public boolean remove(Object o) {
+            if (!(o instanceof Map.Entry))
+                return false;
+            Map.Entry<K1,V1> e = (Map.Entry<K1,V1>)o;
+            return m.remove(e.getKey(),
+                            e.getValue());
+        }
+        public boolean isEmpty() {
+            return m.isEmpty();
+        }
+        public int size() {
+            return m.size();
+        }
+        public void clear() {
+            m.clear();
+        }
+        public boolean equals(Object o) {
+            if (o == this)
+                return true;
+            if (!(o instanceof Set))
+                return false;
+            Collection<?> c = (Collection<?>) o;
+            try {
+                return containsAll(c) && c.containsAll(this);
+            } catch (ClassCastException unused)   {
+                return false;
+            } catch (NullPointerException unused) {
+                return false;
+            }
+        }
+        public Object[] toArray()     { return toList(this).toArray();  }
+        public <T> T[] toArray(T[] a) { return toList(this).toArray(a); }
+    }
+
+    /**
+     * Submaps returned by {@link ConcurrentSkipListMap} submap operations
+     * represent a subrange of mappings of their underlying
+     * maps. Instances of this class support all methods of their
+     * underlying maps, differing in that mappings outside their range are
+     * ignored, and attempts to add mappings outside their ranges result
+     * in {@link IllegalArgumentException}.  Instances of this class are
+     * constructed only using the <tt>subMap</tt>, <tt>headMap</tt>, and
+     * <tt>tailMap</tt> methods of their underlying maps.
+     *
+     * @serial include
+     */
+    static final class SubMap<K,V> extends AbstractMap<K,V>
+        implements ConcurrentNavigableMap<K,V>, Cloneable,
+                   java.io.Serializable {
+        private static final long serialVersionUID = -7647078645895051609L;
+
+        /** Underlying map */
+        private final ConcurrentSkipListMap<K,V> m;
+        /** lower bound key, or null if from start */
+        private final K lo;
+        /** upper bound key, or null if to end */
+        private final K hi;
+        /** inclusion flag for lo */
+        private final boolean loInclusive;
+        /** inclusion flag for hi */
+        private final boolean hiInclusive;
+        /** direction */
+        private final boolean isDescending;
+
+        // Lazily initialized view holders
+        private transient KeySet<K> keySetView;
+        private transient Set<Map.Entry<K,V>> entrySetView;
+        private transient Collection<V> valuesView;
+
+        /**
+         * Creates a new submap, initializing all fields
+         */
+        SubMap(ConcurrentSkipListMap<K,V> map,
+               K fromKey, boolean fromInclusive,
+               K toKey, boolean toInclusive,
+               boolean isDescending) {
+            if (fromKey != null && toKey != null &&
+                map.compare(fromKey, toKey) > 0)
+                throw new IllegalArgumentException("inconsistent range");
+            this.m = map;
+            this.lo = fromKey;
+            this.hi = toKey;
+            this.loInclusive = fromInclusive;
+            this.hiInclusive = toInclusive;
+            this.isDescending = isDescending;
+        }
+
+        /* ----------------  Utilities -------------- */
+
+        private boolean tooLow(K key) {
+            if (lo != null) {
+                int c = m.compare(key, lo);
+                if (c < 0 || (c == 0 && !loInclusive))
+                    return true;
+            }
+            return false;
+        }
+
+        private boolean tooHigh(K key) {
+            if (hi != null) {
+                int c = m.compare(key, hi);
+                if (c > 0 || (c == 0 && !hiInclusive))
+                    return true;
+            }
+            return false;
+        }
+
+        private boolean inBounds(K key) {
+            return !tooLow(key) && !tooHigh(key);
+        }
+
+        private void checkKeyBounds(K key) throws IllegalArgumentException {
+            if (key == null)
+                throw new NullPointerException();
+            if (!inBounds(key))
+                throw new IllegalArgumentException("key out of range");
+        }
+
+        /**
+         * Returns true if node key is less than upper bound of range
+         */
+        private boolean isBeforeEnd(ConcurrentSkipListMap.Node<K,V> n) {
+            if (n == null)
+                return false;
+            if (hi == null)
+                return true;
+            K k = n.key;
+            if (k == null) // pass by markers and headers
+                return true;
+            int c = m.compare(k, hi);
+            if (c > 0 || (c == 0 && !hiInclusive))
+                return false;
+            return true;
+        }
+
+        /**
+         * Returns lowest node. This node might not be in range, so
+         * most usages need to check bounds
+         */
+        private ConcurrentSkipListMap.Node<K,V> loNode() {
+            if (lo == null)
+                return m.findFirst();
+            else if (loInclusive)
+                return m.findNear(lo, m.GT|m.EQ);
+            else
+                return m.findNear(lo, m.GT);
+        }
+
+        /**
+         * Returns highest node. This node might not be in range, so
+         * most usages need to check bounds
+         */
+        private ConcurrentSkipListMap.Node<K,V> hiNode() {
+            if (hi == null)
+                return m.findLast();
+            else if (hiInclusive)
+                return m.findNear(hi, m.LT|m.EQ);
+            else
+                return m.findNear(hi, m.LT);
+        }
+
+        /**
+         * Returns lowest absolute key (ignoring directonality)
+         */
+        private K lowestKey() {
+            ConcurrentSkipListMap.Node<K,V> n = loNode();
+            if (isBeforeEnd(n))
+                return n.key;
+            else
+                throw new NoSuchElementException();
+        }
+
+        /**
+         * Returns highest absolute key (ignoring directonality)
+         */
+        private K highestKey() {
+            ConcurrentSkipListMap.Node<K,V> n = hiNode();
+            if (n != null) {
+                K last = n.key;
+                if (inBounds(last))
+                    return last;
+            }
+            throw new NoSuchElementException();
+        }
+
+        private Map.Entry<K,V> lowestEntry() {
+            for (;;) {
+                ConcurrentSkipListMap.Node<K,V> n = loNode();
+                if (!isBeforeEnd(n))
+                    return null;
+                Map.Entry<K,V> e = n.createSnapshot();
+                if (e != null)
+                    return e;
+            }
+        }
+
+        private Map.Entry<K,V> highestEntry() {
+            for (;;) {
+                ConcurrentSkipListMap.Node<K,V> n = hiNode();
+                if (n == null || !inBounds(n.key))
+                    return null;
+                Map.Entry<K,V> e = n.createSnapshot();
+                if (e != null)
+                    return e;
+            }
+        }
+
+        private Map.Entry<K,V> removeLowest() {
+            for (;;) {
+                Node<K,V> n = loNode();
+                if (n == null)
+                    return null;
+                K k = n.key;
+                if (!inBounds(k))
+                    return null;
+                V v = m.doRemove(k, null);
+                if (v != null)
+                    return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
+            }
+        }
+
+        private Map.Entry<K,V> removeHighest() {
+            for (;;) {
+                Node<K,V> n = hiNode();
+                if (n == null)
+                    return null;
+                K k = n.key;
+                if (!inBounds(k))
+                    return null;
+                V v = m.doRemove(k, null);
+                if (v != null)
+                    return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
+            }
+        }
+
+        /**
+         * Submap version of ConcurrentSkipListMap.getNearEntry
+         */
+        private Map.Entry<K,V> getNearEntry(K key, int rel) {
+            if (isDescending) { // adjust relation for direction
+                if ((rel & m.LT) == 0)
+                    rel |= m.LT;
+                else
+                    rel &= ~m.LT;
+            }
+            if (tooLow(key))
+                return ((rel & m.LT) != 0)? null : lowestEntry();
+            if (tooHigh(key))
+                return ((rel & m.LT) != 0)? highestEntry() : null;
+            for (;;) {
+                Node<K,V> n = m.findNear(key, rel);
+                if (n == null || !inBounds(n.key))
+                    return null;
+                K k = n.key;
+                V v = n.getValidValue();
+                if (v != null)
+                    return new AbstractMap.SimpleImmutableEntry<K,V>(k, v);
+            }
+        }
+
+        // Almost the same as getNearEntry, except for keys
+        private K getNearKey(K key, int rel) {
+            if (isDescending) { // adjust relation for direction
+                if ((rel & m.LT) == 0)
+                    rel |= m.LT;
+                else
+                    rel &= ~m.LT;
+            }
+            if (tooLow(key)) {
+                if ((rel & m.LT) == 0) {
+                    ConcurrentSkipListMap.Node<K,V> n = loNode();
+                    if (isBeforeEnd(n))
+                        return n.key;
+                }
+                return null;
+            }
+            if (tooHigh(key)) {
+                if ((rel & m.LT) != 0) {
+                    ConcurrentSkipListMap.Node<K,V> n = hiNode();
+                    if (n != null) {
+                        K last = n.key;
+                        if (inBounds(last))
+                            return last;
+                    }
+                }
+                return null;
+            }
+            for (;;) {
+                Node<K,V> n = m.findNear(key, rel);
+                if (n == null || !inBounds(n.key))
+                    return null;
+                K k = n.key;
+                V v = n.getValidValue();
+                if (v != null)
+                    return k;
+            }
+        }
+
+        /* ----------------  Map API methods -------------- */
+
+        public boolean containsKey(Object key) {
+            if (key == null) throw new NullPointerException();
+            K k = (K)key;
+            return inBounds(k) && m.containsKey(k);
+        }
+
+        public V get(Object key) {
+            if (key == null) throw new NullPointerException();
+            K k = (K)key;
+            return ((!inBounds(k)) ? null : m.get(k));
+        }
+
+        public V put(K key, V value) {
+            checkKeyBounds(key);
+            return m.put(key, value);
+        }
+
+        public V remove(Object key) {
+            K k = (K)key;
+            return (!inBounds(k))? null : m.remove(k);
+        }
+
+        public int size() {
+            long count = 0;
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
+                 isBeforeEnd(n);
+                 n = n.next) {
+                if (n.getValidValue() != null)
+                    ++count;
+            }
+            return count >= Integer.MAX_VALUE? Integer.MAX_VALUE : (int)count;
+        }
+
+        public boolean isEmpty() {
+            return !isBeforeEnd(loNode());
+        }
+
+        public boolean containsValue(Object value) {
+            if (value == null)
+                throw new NullPointerException();
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
+                 isBeforeEnd(n);
+                 n = n.next) {
+                V v = n.getValidValue();
+                if (v != null && value.equals(v))
+                    return true;
+            }
+            return false;
+        }
+
+        public void clear() {
+            for (ConcurrentSkipListMap.Node<K,V> n = loNode();
+                 isBeforeEnd(n);
+                 n = n.next) {
+                if (n.getValidValue() != null)
+                    m.remove(n.key);
+            }
+        }
+
+        /* ----------------  ConcurrentMap API methods -------------- */
+
+        public V putIfAbsent(K key, V value) {
+            checkKeyBounds(key);
+            return m.putIfAbsent(key, value);
+        }
+
+        public boolean remove(Object key, Object value) {
+            K k = (K)key;
+            return inBounds(k) && m.remove(k, value);
+        }
+
+        public boolean replace(K key, V oldValue, V newValue) {
+            checkKeyBounds(key);
+            return m.replace(key, oldValue, newValue);
+        }
+
+        public V replace(K key, V value) {
+            checkKeyBounds(key);
+            return m.replace(key, value);
+        }
+
+        /* ----------------  SortedMap API methods -------------- */
+
+        public Comparator<? super K> comparator() {
+            Comparator<? super K> cmp = m.comparator();
+            if (isDescending)
+                return Collections.reverseOrder(cmp);
+            else
+                return cmp;
+        }
+
+        /**
+         * Utility to create submaps, where given bounds override
+         * unbounded(null) ones and/or are checked against bounded ones.
+         */
+        private SubMap<K,V> newSubMap(K fromKey,
+                                      boolean fromInclusive,
+                                      K toKey,
+                                      boolean toInclusive) {
+            if (isDescending) { // flip senses
+                K tk = fromKey;
+                fromKey = toKey;
+                toKey = tk;
+                boolean ti = fromInclusive;
+                fromInclusive = toInclusive;
+                toInclusive = ti;
+            }
+            if (lo != null) {
+                if (fromKey == null) {
+                    fromKey = lo;
+                    fromInclusive = loInclusive;
+                }
+                else {
+                    int c = m.compare(fromKey, lo);
+                    if (c < 0 || (c == 0 && !loInclusive && fromInclusive))
+                        throw new IllegalArgumentException("key out of range");
+                }
+            }
+            if (hi != null) {
+                if (toKey == null) {
+                    toKey = hi;
+                    toInclusive = hiInclusive;
+                }
+                else {
+                    int c = m.compare(toKey, hi);
+                    if (c > 0 || (c == 0 && !hiInclusive && toInclusive))
+                        throw new IllegalArgumentException("key out of range");
+                }
+            }
+            return new SubMap<K,V>(m, fromKey, fromInclusive,
+                                   toKey, toInclusive, isDescending);
+        }
+
+        public SubMap<K,V> subMap(K fromKey,
+                                  boolean fromInclusive,
+                                  K toKey,
+                                  boolean toInclusive) {
+            if (fromKey == null || toKey == null)
+                throw new NullPointerException();
+            return newSubMap(fromKey, fromInclusive, toKey, toInclusive);
+        }
+
+        public SubMap<K,V> headMap(K toKey,
+                                   boolean inclusive) {
+            if (toKey == null)
+                throw new NullPointerException();
+            return newSubMap(null, false, toKey, inclusive);
+        }
+
+        public SubMap<K,V> tailMap(K fromKey,
+                                   boolean inclusive) {
+            if (fromKey == null)
+                throw new NullPointerException();
+            return newSubMap(fromKey, inclusive, null, false);
+        }
+
+        public SubMap<K,V> subMap(K fromKey, K toKey) {
+            return subMap(fromKey, true, toKey, false);
+        }
+
+        public SubMap<K,V> headMap(K toKey) {
+            return headMap(toKey, false);
+        }
+
+        public SubMap<K,V> tailMap(K fromKey) {
+            return tailMap(fromKey, true);
+        }
+
+        public SubMap<K,V> descendingMap() {
+            return new SubMap<K,V>(m, lo, loInclusive,
+                                   hi, hiInclusive, !isDescending);
+        }
+
+        /* ----------------  Relational methods -------------- */
+
+        public Map.Entry<K,V> ceilingEntry(K key) {
+            return getNearEntry(key, (m.GT|m.EQ));
+        }
+
+        public K ceilingKey(K key) {
+            return getNearKey(key, (m.GT|m.EQ));
+        }
+
+        public Map.Entry<K,V> lowerEntry(K key) {
+            return getNearEntry(key, (m.LT));
+        }
+
+        public K lowerKey(K key) {
+            return getNearKey(key, (m.LT));
+        }
+
+        public Map.Entry<K,V> floorEntry(K key) {
+            return getNearEntry(key, (m.LT|m.EQ));
+        }
+
+        public K floorKey(K key) {
+            return getNearKey(key, (m.LT|m.EQ));
+        }
+
+        public Map.Entry<K,V> higherEntry(K key) {
+            return getNearEntry(key, (m.GT));
+        }
+
+        public K higherKey(K key) {
+            return getNearKey(key, (m.GT));
+        }
+
+        public K firstKey() {
+            return isDescending? highestKey() : lowestKey();
+        }
+
+        public K lastKey() {
+            return isDescending? lowestKey() : highestKey();
+        }
+
+        public Map.Entry<K,V> firstEntry() {
+            return isDescending? highestEntry() : lowestEntry();
+        }
+
+        public Map.Entry<K,V> lastEntry() {
+            return isDescending? lowestEntry() : highestEntry();
+        }
+
+        public Map.Entry<K,V> pollFirstEntry() {
+            return isDescending? removeHighest() : removeLowest();
+        }
+
+        public Map.Entry<K,V> pollLastEntry() {
+            return isDescending? removeLowest() : removeHighest();
+        }
+
+        /* ---------------- Submap Views -------------- */
+
+        public NavigableSet<K> keySet() {
+            KeySet<K> ks = keySetView;
+            return (ks != null) ? ks : (keySetView = new KeySet(this));
+        }
+
+        public NavigableSet<K> navigableKeySet() {
+            KeySet<K> ks = keySetView;
+            return (ks != null) ? ks : (keySetView = new KeySet(this));
+        }
+
+        public Collection<V> values() {
+            Collection<V> vs = valuesView;
+            return (vs != null) ? vs : (valuesView = new Values(this));
+        }
+
+        public Set<Map.Entry<K,V>> entrySet() {
+            Set<Map.Entry<K,V>> es = entrySetView;
+            return (es != null) ? es : (entrySetView = new EntrySet(this));
+        }
+
+        public NavigableSet<K> descendingKeySet() {
+            return descendingMap().navigableKeySet();
+        }
+
+        Iterator<K> keyIterator() {
+            return new SubMapKeyIterator();
+        }
+
+        Iterator<V> valueIterator() {
+            return new SubMapValueIterator();
+        }
+
+        Iterator<Map.Entry<K,V>> entryIterator() {
+            return new SubMapEntryIterator();
+        }
+
+        /**
+         * Variant of main Iter class to traverse through submaps.
+         */
+        abstract class SubMapIter<T> implements Iterator<T> {
+            /** the last node returned by next() */
+            Node<K,V> lastReturned;
+            /** the next node to return from next(); */
+            Node<K,V> next;
+            /** Cache of next value field to maintain weak consistency */
+            V nextValue;
+
+            SubMapIter() {
+                for (;;) {
+                    next = isDescending ? hiNode() : loNode();
+                    if (next == null)
+                        break;
+                    Object x = next.value;
+                    if (x != null && x != next) {
+                        if (! inBounds(next.key))
+                            next = null;
+                        else
+                            nextValue = (V) x;
+                        break;
+                    }
+                }
+            }
+
+            public final boolean hasNext() {
+                return next != null;
+            }
+
+            final void advance() {
+                if (next == null)
+                    throw new NoSuchElementException();
+                lastReturned = next;
+                if (isDescending)
+                    descend();
+                else
+                    ascend();
+            }
+
+            private void ascend() {
+                for (;;) {
+                    next = next.next;
+                    if (next == null)
+                        break;
+                    Object x = next.value;
+                    if (x != null && x != next) {
+                        if (tooHigh(next.key))
+                            next = null;
+                        else
+                            nextValue = (V) x;
+                        break;
+                    }
+                }
+            }
+
+            private void descend() {
+                for (;;) {
+                    next = m.findNear(lastReturned.key, LT);
+                    if (next == null)
+                        break;
+                    Object x = next.value;
+                    if (x != null && x != next) {
+                        if (tooLow(next.key))
+                            next = null;
+                        else
+                            nextValue = (V) x;
+                        break;
+                    }
+                }
+            }
+
+            public void remove() {
+                Node<K,V> l = lastReturned;
+                if (l == null)
+                    throw new IllegalStateException();
+                m.remove(l.key);
+                lastReturned = null;
+            }
+
+        }
+
+        final class SubMapValueIterator extends SubMapIter<V> {
+            public V next() {
+                V v = nextValue;
+                advance();
+                return v;
+            }
+        }
+
+        final class SubMapKeyIterator extends SubMapIter<K> {
+            public K next() {
+                Node<K,V> n = next;
+                advance();
+                return n.key;
+            }
+        }
+
+        final class SubMapEntryIterator extends SubMapIter<Map.Entry<K,V>> {
+            public Map.Entry<K,V> next() {
+                Node<K,V> n = next;
+                V v = nextValue;
+                advance();
+                return new AbstractMap.SimpleImmutableEntry<K,V>(n.key, v);
+            }
+        }
+    }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java b/concurrent/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java
new file mode 100644
index 0000000..7fd1c76
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/ConcurrentSkipListSet.java
@@ -0,0 +1,456 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+import sun.misc.Unsafe;
+
+/**
+ * A scalable concurrent {@link NavigableSet} implementation based on
+ * a {@link ConcurrentSkipListMap}.  The elements of the set are kept
+ * sorted according to their {@linkplain Comparable natural ordering},
+ * or by a {@link Comparator} provided at set creation time, depending
+ * on which constructor is used.
+ *
+ * <p>This implementation provides expected average <i>log(n)</i> time
+ * cost for the <tt>contains</tt>, <tt>add</tt>, and <tt>remove</tt>
+ * operations and their variants.  Insertion, removal, and access
+ * operations safely execute concurrently by multiple threads.
+ * Iterators are <i>weakly consistent</i>, returning elements
+ * reflecting the state of the set at some point at or since the
+ * creation of the iterator.  They do <em>not</em> throw {@link
+ * ConcurrentModificationException}, and may proceed concurrently with
+ * other operations.  Ascending ordered views and their iterators are
+ * faster than descending ones.
+ *
+ * <p>Beware that, unlike in most collections, the <tt>size</tt>
+ * method is <em>not</em> a constant-time operation. Because of the
+ * asynchronous nature of these sets, determining the current number
+ * of elements requires a traversal of the elements. Additionally, the
+ * bulk operations <tt>addAll</tt>, <tt>removeAll</tt>,
+ * <tt>retainAll</tt>, and <tt>containsAll</tt> are <em>not</em>
+ * guaranteed to be performed atomically. For example, an iterator
+ * operating concurrently with an <tt>addAll</tt> operation might view
+ * only some of the added elements.
+ *
+ * <p>This class and its iterators implement all of the
+ * <em>optional</em> methods of the {@link Set} and {@link Iterator}
+ * interfaces. Like most other concurrent collection implementations,
+ * this class does not permit the use of <tt>null</tt> elements,
+ * because <tt>null</tt> arguments and return values cannot be reliably
+ * distinguished from the absence of elements.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @author Doug Lea
+ * @param <E> the type of elements maintained by this set
+ * @since 1.6
+ */
+public class ConcurrentSkipListSet<E>
+    extends AbstractSet<E>
+    implements NavigableSet<E>, Cloneable, java.io.Serializable {
+
+    private static final long serialVersionUID = -2479143111061671589L;
+
+    /**
+     * The underlying map. Uses Boolean.TRUE as value for each
+     * element.  This field is declared final for the sake of thread
+     * safety, which entails some ugliness in clone()
+     */
+    private final ConcurrentNavigableMap<E,Object> m;
+
+    /**
+     * Constructs a new, empty set that orders its elements according to
+     * their {@linkplain Comparable natural ordering}.
+     */
+    public ConcurrentSkipListSet() {
+        m = new ConcurrentSkipListMap<E,Object>();
+    }
+
+    /**
+     * Constructs a new, empty set that orders its elements according to
+     * the specified comparator.
+     *
+     * @param comparator the comparator that will be used to order this set.
+     *        If <tt>null</tt>, the {@linkplain Comparable natural
+     *        ordering} of the elements will be used.
+     */
+    public ConcurrentSkipListSet(Comparator<? super E> comparator) {
+        m = new ConcurrentSkipListMap<E,Object>(comparator);
+    }
+
+    /**
+     * Constructs a new set containing the elements in the specified
+     * collection, that orders its elements according to their
+     * {@linkplain Comparable natural ordering}.
+     *
+     * @param c The elements that will comprise the new set
+     * @throws ClassCastException if the elements in <tt>c</tt> are
+     *         not {@link Comparable}, or are not mutually comparable
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     */
+    public ConcurrentSkipListSet(Collection<? extends E> c) {
+        m = new ConcurrentSkipListMap<E,Object>();
+        addAll(c);
+    }
+
+    /**
+     * Constructs a new set containing the same elements and using the
+     * same ordering as the specified sorted set.
+     *
+     * @param s sorted set whose elements will comprise the new set
+     * @throws NullPointerException if the specified sorted set or any
+     *         of its elements are null
+     */
+    public ConcurrentSkipListSet(SortedSet<E> s) {
+        m = new ConcurrentSkipListMap<E,Object>(s.comparator());
+        addAll(s);
+    }
+
+    /**
+     * For use by submaps
+     */
+    ConcurrentSkipListSet(ConcurrentNavigableMap<E,Object> m) {
+        this.m = m;
+    }
+
+    /**
+     * Returns a shallow copy of this <tt>ConcurrentSkipListSet</tt>
+     * instance. (The elements themselves are not cloned.)
+     *
+     * @return a shallow copy of this set
+     */
+    public ConcurrentSkipListSet<E> clone() {
+        ConcurrentSkipListSet<E> clone = null;
+        try {
+            clone = (ConcurrentSkipListSet<E>) super.clone();
+            clone.setMap(new ConcurrentSkipListMap(m));
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError();
+        }
+
+        return clone;
+    }
+
+    /* ---------------- Set operations -------------- */
+
+    /**
+     * Returns the number of elements in this set.  If this set
+     * contains more than <tt>Integer.MAX_VALUE</tt> elements, it
+     * returns <tt>Integer.MAX_VALUE</tt>.
+     *
+     * <p>Beware that, unlike in most collections, this method is
+     * <em>NOT</em> a constant-time operation. Because of the
+     * asynchronous nature of these sets, determining the current
+     * number of elements requires traversing them all to count them.
+     * Additionally, it is possible for the size to change during
+     * execution of this method, in which case the returned result
+     * will be inaccurate. Thus, this method is typically not very
+     * useful in concurrent applications.
+     *
+     * @return the number of elements in this set
+     */
+    public int size() {
+        return m.size();
+    }
+
+    /**
+     * Returns <tt>true</tt> if this set contains no elements.
+     * @return <tt>true</tt> if this set contains no elements
+     */
+    public boolean isEmpty() {
+        return m.isEmpty();
+    }
+
+    /**
+     * Returns <tt>true</tt> if this set contains the specified element.
+     * More formally, returns <tt>true</tt> if and only if this set
+     * contains an element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     *
+     * @param o object to be checked for containment in this set
+     * @return <tt>true</tt> if this set contains the specified element
+     * @throws ClassCastException if the specified element cannot be
+     *         compared with the elements currently in this set
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean contains(Object o) {
+        return m.containsKey(o);
+    }
+
+    /**
+     * Adds the specified element to this set if it is not already present.
+     * More formally, adds the specified element <tt>e</tt> to this set if
+     * the set contains no element <tt>e2</tt> such that <tt>e.equals(e2)</tt>.
+     * If this set already contains the element, the call leaves the set
+     * unchanged and returns <tt>false</tt>.
+     *
+     * @param e element to be added to this set
+     * @return <tt>true</tt> if this set did not already contain the
+     *         specified element
+     * @throws ClassCastException if <tt>e</tt> cannot be compared
+     *         with the elements currently in this set
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean add(E e) {
+        return m.putIfAbsent(e, Boolean.TRUE) == null;
+    }
+
+    /**
+     * Removes the specified element from this set if it is present.
+     * More formally, removes an element <tt>e</tt> such that
+     * <tt>o.equals(e)</tt>, if this set contains such an element.
+     * Returns <tt>true</tt> if this set contained the element (or
+     * equivalently, if this set changed as a result of the call).
+     * (This set will not contain the element once the call returns.)
+     *
+     * @param o object to be removed from this set, if present
+     * @return <tt>true</tt> if this set contained the specified element
+     * @throws ClassCastException if <tt>o</tt> cannot be compared
+     *         with the elements currently in this set
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean remove(Object o) {
+        return m.remove(o, Boolean.TRUE);
+    }
+
+    /**
+     * Removes all of the elements from this set.
+     */
+    public void clear() {
+        m.clear();
+    }
+
+    /**
+     * Returns an iterator over the elements in this set in ascending order.
+     *
+     * @return an iterator over the elements in this set in ascending order
+     */
+    public Iterator<E> iterator() {
+        return m.navigableKeySet().iterator();
+    }
+
+    /**
+     * Returns an iterator over the elements in this set in descending order.
+     *
+     * @return an iterator over the elements in this set in descending order
+     */
+    public Iterator<E> descendingIterator() {
+        return m.descendingKeySet().iterator();
+    }
+
+
+    /* ---------------- AbstractSet Overrides -------------- */
+
+    /**
+     * Compares the specified object with this set for equality.  Returns
+     * <tt>true</tt> if the specified object is also a set, the two sets
+     * have the same size, and every member of the specified set is
+     * contained in this set (or equivalently, every member of this set is
+     * contained in the specified set).  This definition ensures that the
+     * equals method works properly across different implementations of the
+     * set interface.
+     *
+     * @param o the object to be compared for equality with this set
+     * @return <tt>true</tt> if the specified object is equal to this set
+     */
+    public boolean equals(Object o) {
+        // Override AbstractSet version to avoid calling size()
+        if (o == this)
+            return true;
+        if (!(o instanceof Set))
+            return false;
+        Collection<?> c = (Collection<?>) o;
+        try {
+            return containsAll(c) && c.containsAll(this);
+        } catch (ClassCastException unused)   {
+            return false;
+        } catch (NullPointerException unused) {
+            return false;
+        }
+    }
+
+    /**
+     * Removes from this set all of its elements that are contained in
+     * the specified collection.  If the specified collection is also
+     * a set, this operation effectively modifies this set so that its
+     * value is the <i>asymmetric set difference</i> of the two sets.
+     *
+     * @param  c collection containing elements to be removed from this set
+     * @return <tt>true</tt> if this set changed as a result of the call
+     * @throws ClassCastException if the types of one or more elements in this
+     *         set are incompatible with the specified collection
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     */
+    public boolean removeAll(Collection<?> c) {
+        // Override AbstractSet version to avoid unnecessary call to size()
+        boolean modified = false;
+        for (Iterator<?> i = c.iterator(); i.hasNext(); )
+            if (remove(i.next()))
+                modified = true;
+        return modified;
+    }
+
+    /* ---------------- Relational operations -------------- */
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     */
+    public E lower(E e) {
+        return m.lowerKey(e);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     */
+    public E floor(E e) {
+        return m.floorKey(e);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     */
+    public E ceiling(E e) {
+        return m.ceilingKey(e);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if the specified element is null
+     */
+    public E higher(E e) {
+        return m.higherKey(e);
+    }
+
+    public E pollFirst() {
+        Map.Entry<E,Object> e = m.pollFirstEntry();
+        return e == null? null : e.getKey();
+    }
+
+    public E pollLast() {
+        Map.Entry<E,Object> e = m.pollLastEntry();
+        return e == null? null : e.getKey();
+    }
+
+
+    /* ---------------- SortedSet operations -------------- */
+
+
+    public Comparator<? super E> comparator() {
+        return m.comparator();
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E first() {
+        return m.firstKey();
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E last() {
+        return m.lastKey();
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromElement} or
+     *         {@code toElement} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public NavigableSet<E> subSet(E fromElement,
+                                  boolean fromInclusive,
+                                  E toElement,
+                                  boolean toInclusive) {
+        return new ConcurrentSkipListSet<E>
+            (m.subMap(fromElement, fromInclusive,
+                      toElement,   toInclusive));
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code toElement} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public NavigableSet<E> headSet(E toElement, boolean inclusive) {
+        return new ConcurrentSkipListSet<E>(m.headMap(toElement, inclusive));
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromElement} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+        return new ConcurrentSkipListSet<E>(m.tailMap(fromElement, inclusive));
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromElement} or
+     *         {@code toElement} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public NavigableSet<E> subSet(E fromElement, E toElement) {
+        return subSet(fromElement, true, toElement, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code toElement} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public NavigableSet<E> headSet(E toElement) {
+        return headSet(toElement, false);
+    }
+
+    /**
+     * @throws ClassCastException {@inheritDoc}
+     * @throws NullPointerException if {@code fromElement} is null
+     * @throws IllegalArgumentException {@inheritDoc}
+     */
+    public NavigableSet<E> tailSet(E fromElement) {
+        return tailSet(fromElement, true);
+    }
+
+    /**
+     * Returns a reverse order view of the elements contained in this set.
+     * The descending set is backed by this set, so changes to the set are
+     * reflected in the descending set, and vice-versa.
+     *
+     * <p>The returned set has an ordering equivalent to
+     * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
+     * The expression {@code s.descendingSet().descendingSet()} returns a
+     * view of {@code s} essentially equivalent to {@code s}.
+     *
+     * @return a reverse order view of this set
+     */
+    public NavigableSet<E> descendingSet() {
+        return new ConcurrentSkipListSet(m.descendingMap());
+    }
+
+    // Support for resetting map in clone
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final long mapOffset;
+    static {
+        try {
+            mapOffset = unsafe.objectFieldOffset
+                (ConcurrentSkipListSet.class.getDeclaredField("m"));
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+    private void setMap(ConcurrentNavigableMap<E,Object> map) {
+        unsafe.putObjectVolatile(this, mapOffset, map);
+    }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java b/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
index f0c8ac6..237c5df 100644
--- a/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
+++ b/concurrent/src/main/java/java/util/concurrent/CopyOnWriteArrayList.java
@@ -17,8 +17,6 @@
 package java.util.concurrent;
 import java.util.*;
 import java.util.concurrent.locks.*;
-import java.lang.reflect.Array;
-
 import sun.misc.Unsafe;
 
 // BEGIN android-note
@@ -102,7 +100,7 @@
         Object[] elements = c.toArray();
         // c.toArray might (incorrectly) not return Object[] (see 6260652)
         if (elements.getClass() != Object[].class)
-            elements = Java6Arrays.copyOf(elements, elements.length, Object[].class);
+            elements = Arrays.copyOf(elements, elements.length, Object[].class);
         setArray(elements);
     }
 
@@ -114,7 +112,7 @@
      * @throws NullPointerException if the specified array is null
      */
     public CopyOnWriteArrayList(E[] toCopyIn) {
-        setArray(Java6Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
+        setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
     }
 
     /**
@@ -288,7 +286,7 @@
      */
     public Object[] toArray() {
         Object[] elements = getArray();
-        return Java6Arrays.copyOf(elements, elements.length);
+        return Arrays.copyOf(elements, elements.length);
     }
 
     /**
@@ -335,7 +333,7 @@
         Object[] elements = getArray();
         int len = elements.length;
         if (a.length < len)
-            return (T[]) Java6Arrays.copyOf(elements, len, a.getClass());
+            return (T[]) Arrays.copyOf(elements, len, a.getClass());
         else {
             System.arraycopy(elements, 0, a, 0, len);
             if (a.length > len)
@@ -375,7 +373,7 @@
 
             if (oldValue != element) {
                 int len = elements.length;
-                Object[] newElements = Java6Arrays.copyOf(elements, len);
+                Object[] newElements = Arrays.copyOf(elements, len);
                 newElements[index] = element;
                 setArray(newElements);
             } else {
@@ -400,7 +398,7 @@
         try {
             Object[] elements = getArray();
             int len = elements.length;
-            Object[] newElements = Java6Arrays.copyOf(elements, len + 1);
+            Object[] newElements = Arrays.copyOf(elements, len + 1);
             newElements[len] = e;
             setArray(newElements);
             return true;
@@ -428,7 +426,7 @@
             Object[] newElements;
             int numMoved = len - index;
             if (numMoved == 0)
-                newElements = Java6Arrays.copyOf(elements, len + 1);
+                newElements = Arrays.copyOf(elements, len + 1);
             else {
                 newElements = new Object[len + 1];
                 System.arraycopy(elements, 0, newElements, 0, index);
@@ -458,7 +456,7 @@
             E oldValue = get(elements, index);
             int numMoved = len - index - 1;
             if (numMoved == 0)
-                setArray(Java6Arrays.copyOf(elements, len - 1));
+                setArray(Arrays.copyOf(elements, len - 1));
             else {
                 Object[] newElements = new Object[len - 1];
                 System.arraycopy(elements, 0, newElements, 0, index);
@@ -544,7 +542,7 @@
             int newlen = len - (toIndex - fromIndex);
             int numMoved = len - toIndex;
             if (numMoved == 0)
-                setArray(Java6Arrays.copyOf(elements, newlen));
+                setArray(Arrays.copyOf(elements, newlen));
             else {
                 Object[] newElements = new Object[newlen];
                 System.arraycopy(elements, 0, newElements, 0, fromIndex);
@@ -636,7 +634,7 @@
                         temp[newlen++] = element;
                 }
                 if (newlen != len) {
-                    setArray(Java6Arrays.copyOf(temp, newlen));
+                    setArray(Arrays.copyOf(temp, newlen));
                     return true;
                 }
             }
@@ -676,7 +674,7 @@
                         temp[newlen++] = element;
                 }
                 if (newlen != len) {
-                    setArray(Java6Arrays.copyOf(temp, newlen));
+                    setArray(Arrays.copyOf(temp, newlen));
                     return true;
                 }
             }
@@ -715,7 +713,7 @@
                     uniq[added++] = e;
             }
             if (added > 0) {
-                Object[] newElements = Java6Arrays.copyOf(elements, len + added);
+                Object[] newElements = Arrays.copyOf(elements, len + added);
                 System.arraycopy(uniq, 0, newElements, len, added);
                 setArray(newElements);
             }
@@ -758,7 +756,7 @@
         try {
             Object[] elements = getArray();
             int len = elements.length;
-            Object[] newElements = Java6Arrays.copyOf(elements, len + cs.length);
+            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
             System.arraycopy(cs, 0, newElements, len, cs.length);
             setArray(newElements);
             return true;
@@ -798,7 +796,7 @@
             int numMoved = len - index;
             Object[] newElements;
             if (numMoved == 0)
-                newElements = Java6Arrays.copyOf(elements, len + cs.length);
+                newElements = Arrays.copyOf(elements, len + cs.length);
             else {
                 newElements = new Object[len + cs.length];
                 System.arraycopy(elements, 0, newElements, 0, index);
@@ -1314,4 +1312,5 @@
     private void resetLock() {
         unsafe.putObjectVolatile(this, lockOffset, new ReentrantLock());
     }
+
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/Delayed.java b/concurrent/src/main/java/java/util/concurrent/Delayed.java
index af41300..b1ff4ee 100644
--- a/concurrent/src/main/java/java/util/concurrent/Delayed.java
+++ b/concurrent/src/main/java/java/util/concurrent/Delayed.java
@@ -4,19 +4,10 @@
  * http://creativecommons.org/licenses/publicdomain
  */
 
-/*
- * Modified in Apache Harmony to comply with Java 5 signature
- * specification.
- */
-
 package java.util.concurrent;
 
 import java.util.*;
 
-// BEGIN android-note
-// Added generic type Delayed to Comparable to be closer to the RI.
-// END android-note
-
 /**
  * A mix-in style interface for marking objects that should be
  * acted upon after a given delay.
diff --git a/concurrent/src/main/java/java/util/concurrent/Exchanger.java b/concurrent/src/main/java/java/util/concurrent/Exchanger.java
index f67659c..bb2193c 100644
--- a/concurrent/src/main/java/java/util/concurrent/Exchanger.java
+++ b/concurrent/src/main/java/java/util/concurrent/Exchanger.java
@@ -471,7 +471,7 @@
             else if (w.isInterrupted())         // Abort on interrupt
                 tryCancel(node, slot);
             else                                // Block
-                LockSupport.park();
+                LockSupport.park(node);
         }
     }
 
@@ -506,7 +506,7 @@
                 else if (w.isInterrupted())
                     tryCancel(node, slot);
                 else
-                    LockSupport.parkNanos(nanos);
+                    LockSupport.parkNanos(node, nanos);
             }
             else if (tryCancel(node, slot) && !w.isInterrupted())
                 return scanOnTimeout(node);
diff --git a/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java b/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
index 02606f9..bf4a584 100644
--- a/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
+++ b/concurrent/src/main/java/java/util/concurrent/ExecutorCompletionService.java
@@ -84,7 +84,7 @@
      * FutureTask extension to enqueue upon completion
      */
     private class QueueingFuture extends FutureTask<Void> {
-        QueueingFuture(FutureTask<V> task) {
+        QueueingFuture(RunnableFuture<V> task) {
             super(task, null);
             this.task = task;
         }
@@ -92,12 +92,18 @@
         private final Future<V> task;
     }
 
-    private FutureTask<V> newTaskFor(Callable<V> task) {
-        return new FutureTask<V>(task);
+    private RunnableFuture<V> newTaskFor(Callable<V> task) {
+        if (aes == null)
+            return new FutureTask<V>(task);
+        else
+            return aes.newTaskFor(task);
     }
 
-    private FutureTask<V> newTaskFor(Runnable task, V result) {
-        return new FutureTask<V>(task, result);
+    private RunnableFuture<V> newTaskFor(Runnable task, V result) {
+        if (aes == null)
+            return new FutureTask<V>(task, result);
+        else
+            return aes.newTaskFor(task, result);
     }
 
     /**
@@ -142,14 +148,14 @@
 
     public Future<V> submit(Callable<V> task) {
         if (task == null) throw new NullPointerException();
-        FutureTask<V> f = newTaskFor(task);
+        RunnableFuture<V> f = newTaskFor(task);
         executor.execute(new QueueingFuture(f));
         return f;
     }
 
     public Future<V> submit(Runnable task, V result) {
         if (task == null) throw new NullPointerException();
-        FutureTask<V> f = newTaskFor(task, result);
+        RunnableFuture<V> f = newTaskFor(task, result);
         executor.execute(new QueueingFuture(f));
         return f;
     }
diff --git a/concurrent/src/main/java/java/util/concurrent/ExecutorService.java b/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
index 757f7cb..ddd77bf 100644
--- a/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
+++ b/concurrent/src/main/java/java/util/concurrent/ExecutorService.java
@@ -258,7 +258,7 @@
      *         scheduled for execution
      */
 
-    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
+    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
         throws InterruptedException;
 
     /**
@@ -288,7 +288,7 @@
      * @throws RejectedExecutionException if any task cannot be scheduled
      *         for execution
      */
-    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                   long timeout, TimeUnit unit)
         throws InterruptedException;
 
@@ -303,14 +303,14 @@
      * @param tasks the collection of tasks
      * @return the result returned by one of the tasks
      * @throws InterruptedException if interrupted while waiting
-     * @throws NullPointerException if tasks or any of its elements
-     *         are <tt>null</tt>
+     * @throws NullPointerException if tasks or any element task
+     *         subject to execution is <tt>null</tt>
      * @throws IllegalArgumentException if tasks is empty
      * @throws ExecutionException if no task successfully completes
      * @throws RejectedExecutionException if tasks cannot be scheduled
      *         for execution
      */
-    <T> T invokeAny(Collection<Callable<T>> tasks)
+    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
         throws InterruptedException, ExecutionException;
 
     /**
@@ -327,15 +327,15 @@
      * @param unit the time unit of the timeout argument
      * @return the result returned by one of the tasks.
      * @throws InterruptedException if interrupted while waiting
-     * @throws NullPointerException if tasks, any of its elements, or
-     *         unit are <tt>null</tt>
+     * @throws NullPointerException if tasks, or unit, or any element
+     *         task subject to execution is <tt>null</tt>
      * @throws TimeoutException if the given timeout elapses before
      *         any task successfully completes
      * @throws ExecutionException if no task successfully completes
      * @throws RejectedExecutionException if tasks cannot be scheduled
      *         for execution
      */
-    <T> T invokeAny(Collection<Callable<T>> tasks,
+    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                     long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException;
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/Executors.java b/concurrent/src/main/java/java/util/concurrent/Executors.java
index a57abe5..96f6c15 100644
--- a/concurrent/src/main/java/java/util/concurrent/Executors.java
+++ b/concurrent/src/main/java/java/util/concurrent/Executors.java
@@ -13,6 +13,7 @@
 import java.security.PrivilegedExceptionAction;
 import java.security.PrivilegedActionException;
 import java.security.AccessControlException;
+// import sun.security.util.SecurityConstants; // android-removed
 
 /**
  * Factory and utility methods for {@link Executor}, {@link
@@ -359,7 +360,7 @@
      * @return a callable object
      * @throws NullPointerException if action null
      */
-    public static Callable<Object> callable(final PrivilegedAction action) {
+    public static Callable<Object> callable(final PrivilegedAction<?> action) {
         if (action == null)
             throw new NullPointerException();
         return new Callable<Object>() {
@@ -374,7 +375,7 @@
      * @return a callable object
      * @throws NullPointerException if action null
      */
-    public static Callable<Object> callable(final PrivilegedExceptionAction action) {
+    public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
         if (action == null)
             throw new NullPointerException();
         return new Callable<Object>() {
@@ -484,7 +485,7 @@
                 // Calls to getContextClassLoader from this class
                 // never trigger a security check, but we check
                 // whether our callers have this permission anyways.
-                sm.checkPermission(new RuntimePermission("getContextClassLoader"));
+                sm.checkPermission(new RuntimePermission("getContextClassLoader")); // android-changed
 
                 // Whether setContextClassLoader turns out to be necessary
                 // or not, we fail fast if permission is not available.
@@ -565,7 +566,7 @@
                 // Calls to getContextClassLoader from this class
                 // never trigger a security check, but we check
                 // whether our callers have this permission anyways.
-                sm.checkPermission(new RuntimePermission("getContextClassLoader"));
+                sm.checkPermission(new RuntimePermission("getContextClassLoader")); // android-changed
 
                 // Fail fast
                 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
@@ -614,20 +615,20 @@
         public <T> Future<T> submit(Runnable task, T result) {
             return e.submit(task, result);
         }
-        public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
+        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
             throws InterruptedException {
             return e.invokeAll(tasks);
         }
-        public <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                              long timeout, TimeUnit unit)
             throws InterruptedException {
             return e.invokeAll(tasks, timeout, unit);
         }
-        public <T> T invokeAny(Collection<Callable<T>> tasks)
+        public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
             throws InterruptedException, ExecutionException {
             return e.invokeAny(tasks);
         }
-        public <T> T invokeAny(Collection<Callable<T>> tasks,
+        public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                                long timeout, TimeUnit unit)
             throws InterruptedException, ExecutionException, TimeoutException {
             return e.invokeAny(tasks, timeout, unit);
diff --git a/concurrent/src/main/java/java/util/concurrent/FutureTask.java b/concurrent/src/main/java/java/util/concurrent/FutureTask.java
index 8aa9dd1..6bd13f9 100644
--- a/concurrent/src/main/java/java/util/concurrent/FutureTask.java
+++ b/concurrent/src/main/java/java/util/concurrent/FutureTask.java
@@ -30,7 +30,7 @@
  * @author Doug Lea
  * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
  */
-public class FutureTask<V> implements Future<V>, Runnable {
+public class FutureTask<V> implements RunnableFuture<V> {
     /** Synchronization control for FutureTask */
     private final Sync sync;
 
diff --git a/concurrent/src/main/java/java/util/concurrent/Java6Arrays.java b/concurrent/src/main/java/java/util/concurrent/Java6Arrays.java
deleted file mode 100644
index 6b728be..0000000
--- a/concurrent/src/main/java/java/util/concurrent/Java6Arrays.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-package java.util.concurrent;
-
-import java.lang.reflect.Array;
-
-/**
- * Arrays.copyOf and Arrays.copyOfRange backported from Java 6.
- */
-class Java6Arrays {
-
-    static <T> T[] copyOf(T[] original, int newLength) {
-        if (null == original) {
-            throw new NullPointerException();
-        }
-        if (0 <= newLength) {
-            return copyOfRange(original, 0, newLength);
-        }
-        throw new NegativeArraySizeException();
-    }
-
-    static <T, U> T[] copyOf(U[] original, int newLength,
-            Class<? extends T[]> newType) {
-        if (0 <= newLength) {
-            return copyOfRange(original, 0, newLength, newType);
-        }
-        throw new NegativeArraySizeException();
-    }
-
-    @SuppressWarnings("unchecked")
-    static <T> T[] copyOfRange(T[] original, int start, int end) {
-        if (original.length >= start && 0 <= start) {
-            if (start <= end) {
-                int length = end - start;
-                int copyLength = Math.min(length, original.length - start);
-                T[] copy = (T[]) Array.newInstance(original.getClass().getComponentType(), length);
-                System.arraycopy(original, start, copy, 0, copyLength);
-                return copy;
-            }
-            throw new IllegalArgumentException();
-        }
-        throw new ArrayIndexOutOfBoundsException();
-    }
-
-    @SuppressWarnings("unchecked")
-    static <T, U> T[] copyOfRange(U[] original, int start, int end,
-            Class<? extends T[]> newType) {
-        if (start <= end) {
-            if (original.length >= start && 0 <= start) {
-                int length = end - start;
-                int copyLength = Math.min(length, original.length - start);
-                T[] copy = (T[]) Array.newInstance(newType.getComponentType(),
-                        length);
-                System.arraycopy(original, start, copy, 0, copyLength);
-                return copy;
-            }
-            throw new ArrayIndexOutOfBoundsException();
-        }
-        throw new IllegalArgumentException();
-    }
-
-}
diff --git a/concurrent/src/main/java/java/util/concurrent/LinkedBlockingDeque.java b/concurrent/src/main/java/java/util/concurrent/LinkedBlockingDeque.java
new file mode 100644
index 0000000..196ea76
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/LinkedBlockingDeque.java
@@ -0,0 +1,1137 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+import java.util.AbstractQueue;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * An optionally-bounded {@linkplain BlockingDeque blocking deque} based on
+ * linked nodes.
+ *
+ * <p> The optional capacity bound constructor argument serves as a
+ * way to prevent excessive expansion. The capacity, if unspecified,
+ * is equal to {@link Integer#MAX_VALUE}.  Linked nodes are
+ * dynamically created upon each insertion unless this would bring the
+ * deque above capacity.
+ *
+ * <p>Most operations run in constant time (ignoring time spent
+ * blocking).  Exceptions include {@link #remove(Object) remove},
+ * {@link #removeFirstOccurrence removeFirstOccurrence}, {@link
+ * #removeLastOccurrence removeLastOccurrence}, {@link #contains
+ * contains}, {@link #iterator iterator.remove()}, and the bulk
+ * operations, all of which run in linear time.
+ *
+ * <p>This class and its iterator implement all of the
+ * <em>optional</em> methods of the {@link Collection} and {@link
+ * Iterator} interfaces.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.6
+ * @author  Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public class LinkedBlockingDeque<E>
+    extends AbstractQueue<E>
+    implements BlockingDeque<E>,  java.io.Serializable {
+
+    /*
+     * Implemented as a simple doubly-linked list protected by a
+     * single lock and using conditions to manage blocking.
+     *
+     * To implement weakly consistent iterators, it appears we need to
+     * keep all Nodes GC-reachable from a predecessor dequeued Node.
+     * That would cause two problems:
+     * - allow a rogue Iterator to cause unbounded memory retention
+     * - cause cross-generational linking of old Nodes to new Nodes if
+     *   a Node was tenured while live, which generational GCs have a
+     *   hard time dealing with, causing repeated major collections.
+     * However, only non-deleted Nodes need to be reachable from
+     * dequeued Nodes, and reachability does not necessarily have to
+     * be of the kind understood by the GC.  We use the trick of
+     * linking a Node that has just been dequeued to itself.  Such a
+     * self-link implicitly means to jump to "first" (for next links)
+     * or "last" (for prev links).
+     */
+
+    /*
+     * We have "diamond" multiple interface/abstract class inheritance
+     * here, and that introduces ambiguities. Often we want the
+     * BlockingDeque javadoc combined with the AbstractQueue
+     * implementation, so a lot of method specs are duplicated here.
+     */
+
+    private static final long serialVersionUID = -387911632671998426L;
+
+    /** Doubly-linked list node class */
+    static final class Node<E> {
+        /**
+         * The item, or null if this node has been removed.
+         */
+        E item;
+
+        /**
+         * One of:
+         * - the real predecessor Node
+         * - this Node, meaning the predecessor is tail
+         * - null, meaning there is no predecessor
+         */
+        Node<E> prev;
+
+        /**
+         * One of:
+         * - the real successor Node
+         * - this Node, meaning the successor is head
+         * - null, meaning there is no successor
+         */
+        Node<E> next;
+
+        Node(E x, Node<E> p, Node<E> n) {
+            item = x;
+            prev = p;
+            next = n;
+        }
+    }
+
+    /**
+     * Pointer to first node.
+     * Invariant: (first == null && last == null) ||
+     *            (first.prev == null && first.item != null)
+     */
+    transient Node<E> first;
+
+    /**
+     * Pointer to last node.
+     * Invariant: (first == null && last == null) ||
+     *            (last.next == null && last.item != null)
+     */
+    transient Node<E> last;
+
+    /** Number of items in the deque */
+    private transient int count;
+
+    /** Maximum number of items in the deque */
+    private final int capacity;
+
+    /** Main lock guarding all access */
+    final ReentrantLock lock = new ReentrantLock();
+
+    /** Condition for waiting takes */
+    private final Condition notEmpty = lock.newCondition();
+
+    /** Condition for waiting puts */
+    private final Condition notFull = lock.newCondition();
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with a capacity of
+     * {@link Integer#MAX_VALUE}.
+     */
+    public LinkedBlockingDeque() {
+        this(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with the given (fixed) capacity.
+     *
+     * @param capacity the capacity of this deque
+     * @throws IllegalArgumentException if {@code capacity} is less than 1
+     */
+    public LinkedBlockingDeque(int capacity) {
+        if (capacity <= 0) throw new IllegalArgumentException();
+        this.capacity = capacity;
+    }
+
+    /**
+     * Creates a {@code LinkedBlockingDeque} with a capacity of
+     * {@link Integer#MAX_VALUE}, initially containing the elements of
+     * the given collection, added in traversal order of the
+     * collection's iterator.
+     *
+     * @param c the collection of elements to initially contain
+     * @throws NullPointerException if the specified collection or any
+     *         of its elements are null
+     */
+    public LinkedBlockingDeque(Collection<? extends E> c) {
+        this(Integer.MAX_VALUE);
+        final ReentrantLock lock = this.lock;
+        lock.lock(); // Never contended, but necessary for visibility
+        try {
+            for (E e : c) {
+                if (e == null)
+                    throw new NullPointerException();
+                if (!linkLast(e))
+                    throw new IllegalStateException("Deque full");
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+
+    // Basic linking and unlinking operations, called only while holding lock
+
+    /**
+     * Links e as first element, or returns false if full.
+     */
+    private boolean linkFirst(E e) {
+        // assert lock.isHeldByCurrentThread();
+        if (count >= capacity)
+            return false;
+        Node<E> f = first;
+        Node<E> x = new Node<E>(e, null, f);
+        first = x;
+        if (last == null)
+            last = x;
+        else
+            f.prev = x;
+        ++count;
+        notEmpty.signal();
+        return true;
+    }
+
+    /**
+     * Links e as last element, or returns false if full.
+     */
+    private boolean linkLast(E e) {
+        // assert lock.isHeldByCurrentThread();
+        if (count >= capacity)
+            return false;
+        Node<E> l = last;
+        Node<E> x = new Node<E>(e, l, null);
+        last = x;
+        if (first == null)
+            first = x;
+        else
+            l.next = x;
+        ++count;
+        notEmpty.signal();
+        return true;
+    }
+
+    /**
+     * Removes and returns first element, or null if empty.
+     */
+    private E unlinkFirst() {
+        // assert lock.isHeldByCurrentThread();
+        Node<E> f = first;
+        if (f == null)
+            return null;
+        Node<E> n = f.next;
+        E item = f.item;
+        f.item = null;
+        f.next = f; // help GC
+        first = n;
+        if (n == null)
+            last = null;
+        else
+            n.prev = null;
+        --count;
+        notFull.signal();
+        return item;
+    }
+
+    /**
+     * Removes and returns last element, or null if empty.
+     */
+    private E unlinkLast() {
+        // assert lock.isHeldByCurrentThread();
+        Node<E> l = last;
+        if (l == null)
+            return null;
+        Node<E> p = l.prev;
+        E item = l.item;
+        l.item = null;
+        l.prev = l; // help GC
+        last = p;
+        if (p == null)
+            first = null;
+        else
+            p.next = null;
+        --count;
+        notFull.signal();
+        return item;
+    }
+
+    /**
+     * Unlinks x.
+     */
+    void unlink(Node<E> x) {
+        // assert lock.isHeldByCurrentThread();
+        Node<E> p = x.prev;
+        Node<E> n = x.next;
+        if (p == null) {
+            unlinkFirst();
+        } else if (n == null) {
+            unlinkLast();
+        } else {
+            p.next = n;
+            n.prev = p;
+            x.item = null;
+            // Don't mess with x's links.  They may still be in use by
+            // an iterator.
+            --count;
+            notFull.signal();
+        }
+    }
+
+    // BlockingDeque methods
+
+    /**
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws NullPointerException  {@inheritDoc}
+     */
+    public void addFirst(E e) {
+        if (!offerFirst(e))
+            throw new IllegalStateException("Deque full");
+    }
+
+    /**
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws NullPointerException  {@inheritDoc}
+     */
+    public void addLast(E e) {
+        if (!offerLast(e))
+            throw new IllegalStateException("Deque full");
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offerFirst(E e) {
+        if (e == null) throw new NullPointerException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return linkFirst(e);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean offerLast(E e) {
+        if (e == null) throw new NullPointerException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return linkLast(e);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public void putFirst(E e) throws InterruptedException {
+        if (e == null) throw new NullPointerException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            while (!linkFirst(e))
+                notFull.await();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public void putLast(E e) throws InterruptedException {
+        if (e == null) throw new NullPointerException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            while (!linkLast(e))
+                notFull.await();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public boolean offerFirst(E e, long timeout, TimeUnit unit)
+        throws InterruptedException {
+        if (e == null) throw new NullPointerException();
+        long nanos = unit.toNanos(timeout);
+        final ReentrantLock lock = this.lock;
+        lock.lockInterruptibly();
+        try {
+            while (!linkFirst(e)) {
+                if (nanos <= 0)
+                    return false;
+                nanos = notFull.awaitNanos(nanos);
+            }
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public boolean offerLast(E e, long timeout, TimeUnit unit)
+        throws InterruptedException {
+        if (e == null) throw new NullPointerException();
+        long nanos = unit.toNanos(timeout);
+        final ReentrantLock lock = this.lock;
+        lock.lockInterruptibly();
+        try {
+            while (!linkLast(e)) {
+                if (nanos <= 0)
+                    return false;
+                nanos = notFull.awaitNanos(nanos);
+            }
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E removeFirst() {
+        E x = pollFirst();
+        if (x == null) throw new NoSuchElementException();
+        return x;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E removeLast() {
+        E x = pollLast();
+        if (x == null) throw new NoSuchElementException();
+        return x;
+    }
+
+    public E pollFirst() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return unlinkFirst();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E pollLast() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return unlinkLast();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E takeFirst() throws InterruptedException {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            E x;
+            while ( (x = unlinkFirst()) == null)
+                notEmpty.await();
+            return x;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E takeLast() throws InterruptedException {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            E x;
+            while ( (x = unlinkLast()) == null)
+                notEmpty.await();
+            return x;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E pollFirst(long timeout, TimeUnit unit)
+        throws InterruptedException {
+        long nanos = unit.toNanos(timeout);
+        final ReentrantLock lock = this.lock;
+        lock.lockInterruptibly();
+        try {
+            E x;
+            while ( (x = unlinkFirst()) == null) {
+                if (nanos <= 0)
+                    return null;
+                nanos = notEmpty.awaitNanos(nanos);
+            }
+            return x;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E pollLast(long timeout, TimeUnit unit)
+        throws InterruptedException {
+        long nanos = unit.toNanos(timeout);
+        final ReentrantLock lock = this.lock;
+        lock.lockInterruptibly();
+        try {
+            E x;
+            while ( (x = unlinkLast()) == null) {
+                if (nanos <= 0)
+                    return null;
+                nanos = notEmpty.awaitNanos(nanos);
+            }
+            return x;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E getFirst() {
+        E x = peekFirst();
+        if (x == null) throw new NoSuchElementException();
+        return x;
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E getLast() {
+        E x = peekLast();
+        if (x == null) throw new NoSuchElementException();
+        return x;
+    }
+
+    public E peekFirst() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return (first == null) ? null : first.item;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public E peekLast() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return (last == null) ? null : last.item;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public boolean removeFirstOccurrence(Object o) {
+        if (o == null) return false;
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            for (Node<E> p = first; p != null; p = p.next) {
+                if (o.equals(p.item)) {
+                    unlink(p);
+                    return true;
+                }
+            }
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public boolean removeLastOccurrence(Object o) {
+        if (o == null) return false;
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            for (Node<E> p = last; p != null; p = p.prev) {
+                if (o.equals(p.item)) {
+                    unlink(p);
+                    return true;
+                }
+            }
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    // BlockingQueue methods
+
+    /**
+     * Inserts the specified element at the end of this deque unless it would
+     * violate capacity restrictions.  When using a capacity-restricted deque,
+     * it is generally preferable to use method {@link #offer(Object) offer}.
+     *
+     * <p>This method is equivalent to {@link #addLast}.
+     *
+     * @throws IllegalStateException if the element cannot be added at this
+     *         time due to capacity restrictions
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean add(E e) {
+        addLast(e);
+        return true;
+    }
+
+    /**
+     * @throws NullPointerException if the specified element is null
+     */
+    public boolean offer(E e) {
+        return offerLast(e);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public void put(E e) throws InterruptedException {
+        putLast(e);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     * @throws InterruptedException {@inheritDoc}
+     */
+    public boolean offer(E e, long timeout, TimeUnit unit)
+        throws InterruptedException {
+        return offerLast(e, timeout, unit);
+    }
+
+    /**
+     * Retrieves and removes the head of the queue represented by this deque.
+     * This method differs from {@link #poll poll} only in that it throws an
+     * exception if this deque is empty.
+     *
+     * <p>This method is equivalent to {@link #removeFirst() removeFirst}.
+     *
+     * @return the head of the queue represented by this deque
+     * @throws NoSuchElementException if this deque is empty
+     */
+    public E remove() {
+        return removeFirst();
+    }
+
+    public E poll() {
+        return pollFirst();
+    }
+
+    public E take() throws InterruptedException {
+        return takeFirst();
+    }
+
+    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
+        return pollFirst(timeout, unit);
+    }
+
+    /**
+     * Retrieves, but does not remove, the head of the queue represented by
+     * this deque.  This method differs from {@link #peek peek} only in that
+     * it throws an exception if this deque is empty.
+     *
+     * <p>This method is equivalent to {@link #getFirst() getFirst}.
+     *
+     * @return the head of the queue represented by this deque
+     * @throws NoSuchElementException if this deque is empty
+     */
+    public E element() {
+        return getFirst();
+    }
+
+    public E peek() {
+        return peekFirst();
+    }
+
+    /**
+     * Returns the number of additional elements that this deque can ideally
+     * (in the absence of memory or resource constraints) accept without
+     * blocking. This is always equal to the initial capacity of this deque
+     * less the current {@code size} of this deque.
+     *
+     * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+     * an element will succeed by inspecting {@code remainingCapacity}
+     * because it may be the case that another thread is about to
+     * insert or remove an element.
+     */
+    public int remainingCapacity() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return capacity - count;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
+    public int drainTo(Collection<? super E> c) {
+        return drainTo(c, Integer.MAX_VALUE);
+    }
+
+    /**
+     * @throws UnsupportedOperationException {@inheritDoc}
+     * @throws ClassCastException            {@inheritDoc}
+     * @throws NullPointerException          {@inheritDoc}
+     * @throws IllegalArgumentException      {@inheritDoc}
+     */
+    public int drainTo(Collection<? super E> c, int maxElements) {
+        if (c == null)
+            throw new NullPointerException();
+        if (c == this)
+            throw new IllegalArgumentException();
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            int n = Math.min(maxElements, count);
+            for (int i = 0; i < n; i++) {
+                c.add(first.item);   // In this order, in case add() throws.
+                unlinkFirst();
+            }
+            return n;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    // Stack methods
+
+    /**
+     * @throws IllegalStateException {@inheritDoc}
+     * @throws NullPointerException  {@inheritDoc}
+     */
+    public void push(E e) {
+        addFirst(e);
+    }
+
+    /**
+     * @throws NoSuchElementException {@inheritDoc}
+     */
+    public E pop() {
+        return removeFirst();
+    }
+
+    // Collection methods
+
+    /**
+     * Removes the first occurrence of the specified element from this deque.
+     * If the deque does not contain the element, it is unchanged.
+     * More formally, removes the first element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
+     * (or equivalently, if this deque changed as a result of the call).
+     *
+     * <p>This method is equivalent to
+     * {@link #removeFirstOccurrence(Object) removeFirstOccurrence}.
+     *
+     * @param o element to be removed from this deque, if present
+     * @return {@code true} if this deque changed as a result of the call
+     */
+    public boolean remove(Object o) {
+        return removeFirstOccurrence(o);
+    }
+
+    /**
+     * Returns the number of elements in this deque.
+     *
+     * @return the number of elements in this deque
+     */
+    public int size() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return count;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Returns {@code true} if this deque contains the specified element.
+     * More formally, returns {@code true} if and only if this deque contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
+     *
+     * @param o object to be checked for containment in this deque
+     * @return {@code true} if this deque contains the specified element
+     */
+    public boolean contains(Object o) {
+        if (o == null) return false;
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            for (Node<E> p = first; p != null; p = p.next)
+                if (o.equals(p.item))
+                    return true;
+            return false;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /*
+     * TODO: Add support for more efficient bulk operations.
+     *
+     * We don't want to acquire the lock for every iteration, but we
+     * also want other threads a chance to interact with the
+     * collection, especially when count is close to capacity.
+     */
+
+//     /**
+//      * Adds all of the elements in the specified collection to this
+//      * queue.  Attempts to addAll of a queue to itself result in
+//      * {@code IllegalArgumentException}. Further, the behavior of
+//      * this operation is undefined if the specified collection is
+//      * modified while the operation is in progress.
+//      *
+//      * @param c collection containing elements to be added to this queue
+//      * @return {@code true} if this queue changed as a result of the call
+//      * @throws ClassCastException            {@inheritDoc}
+//      * @throws NullPointerException          {@inheritDoc}
+//      * @throws IllegalArgumentException      {@inheritDoc}
+//      * @throws IllegalStateException         {@inheritDoc}
+//      * @see #add(Object)
+//      */
+//     public boolean addAll(Collection<? extends E> c) {
+//         if (c == null)
+//             throw new NullPointerException();
+//         if (c == this)
+//             throw new IllegalArgumentException();
+//         final ReentrantLock lock = this.lock;
+//         lock.lock();
+//         try {
+//             boolean modified = false;
+//             for (E e : c)
+//                 if (linkLast(e))
+//                     modified = true;
+//             return modified;
+//         } finally {
+//             lock.unlock();
+//         }
+//     }
+
+    /**
+     * Returns an array containing all of the elements in this deque, in
+     * proper sequence (from first to last element).
+     *
+     * <p>The returned array will be "safe" in that no references to it are
+     * maintained by this deque.  (In other words, this method must allocate
+     * a new array).  The caller is thus free to modify the returned array.
+     *
+     * <p>This method acts as bridge between array-based and collection-based
+     * APIs.
+     *
+     * @return an array containing all of the elements in this deque
+     */
+    @SuppressWarnings("unchecked")
+    public Object[] toArray() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            Object[] a = new Object[count];
+            int k = 0;
+            for (Node<E> p = first; p != null; p = p.next)
+                a[k++] = p.item;
+            return a;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Returns an array containing all of the elements in this deque, in
+     * proper sequence; the runtime type of the returned array is that of
+     * the specified array.  If the deque fits in the specified array, it
+     * is returned therein.  Otherwise, a new array is allocated with the
+     * runtime type of the specified array and the size of this deque.
+     *
+     * <p>If this deque fits in the specified array with room to spare
+     * (i.e., the array has more elements than this deque), the element in
+     * the array immediately following the end of the deque is set to
+     * {@code null}.
+     *
+     * <p>Like the {@link #toArray()} method, this method acts as bridge between
+     * array-based and collection-based APIs.  Further, this method allows
+     * precise control over the runtime type of the output array, and may,
+     * under certain circumstances, be used to save allocation costs.
+     *
+     * <p>Suppose {@code x} is a deque known to contain only strings.
+     * The following code can be used to dump the deque into a newly
+     * allocated array of {@code String}:
+     *
+     * <pre>
+     *     String[] y = x.toArray(new String[0]);</pre>
+     *
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
+     *
+     * @param a the array into which the elements of the deque are to
+     *          be stored, if it is big enough; otherwise, a new array of the
+     *          same runtime type is allocated for this purpose
+     * @return an array containing all of the elements in this deque
+     * @throws ArrayStoreException if the runtime type of the specified array
+     *         is not a supertype of the runtime type of every element in
+     *         this deque
+     * @throws NullPointerException if the specified array is null
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T[] toArray(T[] a) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            if (a.length < count)
+                a = (T[])java.lang.reflect.Array.newInstance
+                    (a.getClass().getComponentType(), count);
+
+            int k = 0;
+            for (Node<E> p = first; p != null; p = p.next)
+                a[k++] = (T)p.item;
+            if (a.length > k)
+                a[k] = null;
+            return a;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public String toString() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return super.toString();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Atomically removes all of the elements from this deque.
+     * The deque will be empty after this call returns.
+     */
+    public void clear() {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            for (Node<E> f = first; f != null; ) {
+                f.item = null;
+                Node<E> n = f.next;
+                f.prev = null;
+                f.next = null;
+                f = n;
+            }
+            first = last = null;
+            count = 0;
+            notFull.signalAll();
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Returns an iterator over the elements in this deque in proper sequence.
+     * The elements will be returned in order from first (head) to last (tail).
+     * The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     *
+     * @return an iterator over the elements in this deque in proper sequence
+     */
+    public Iterator<E> iterator() {
+        return new Itr();
+    }
+
+    /**
+     * Returns an iterator over the elements in this deque in reverse
+     * sequential order.  The elements will be returned in order from
+     * last (tail) to first (head).
+     * The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
+     * and guarantees to traverse elements as they existed upon
+     * construction of the iterator, and may (but is not guaranteed to)
+     * reflect any modifications subsequent to construction.
+     */
+    public Iterator<E> descendingIterator() {
+        return new DescendingItr();
+    }
+
+    /**
+     * Base class for Iterators for LinkedBlockingDeque
+     */
+    private abstract class AbstractItr implements Iterator<E> {
+        /**
+         * The next node to return in next()
+         */
+         Node<E> next;
+
+        /**
+         * nextItem holds on to item fields because once we claim that
+         * an element exists in hasNext(), we must return item read
+         * under lock (in advance()) even if it was in the process of
+         * being removed when hasNext() was called.
+         */
+        E nextItem;
+
+        /**
+         * Node returned by most recent call to next. Needed by remove.
+         * Reset to null if this element is deleted by a call to remove.
+         */
+        private Node<E> lastRet;
+
+        abstract Node<E> firstNode();
+        abstract Node<E> nextNode(Node<E> n);
+
+        AbstractItr() {
+            // set to initial position
+            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
+            lock.lock();
+            try {
+                next = firstNode();
+                nextItem = (next == null) ? null : next.item;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        /**
+         * Advances next.
+         */
+        void advance() {
+            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
+            lock.lock();
+            try {
+                // assert next != null;
+                Node<E> s = nextNode(next);
+                if (s == next) {
+                    next = firstNode();
+                } else {
+                    // Skip over removed nodes.
+                    // May be necessary if multiple interior Nodes are removed.
+                    while (s != null && s.item == null)
+                        s = nextNode(s);
+                    next = s;
+                }
+                nextItem = (next == null) ? null : next.item;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        public boolean hasNext() {
+            return next != null;
+        }
+
+        public E next() {
+            if (next == null)
+                throw new NoSuchElementException();
+            lastRet = next;
+            E x = nextItem;
+            advance();
+            return x;
+        }
+
+        public void remove() {
+            Node<E> n = lastRet;
+            if (n == null)
+                throw new IllegalStateException();
+            lastRet = null;
+            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
+            lock.lock();
+            try {
+                if (n.item != null)
+                    unlink(n);
+            } finally {
+                lock.unlock();
+            }
+        }
+    }
+
+    /** Forward iterator */
+    private class Itr extends AbstractItr {
+        Node<E> firstNode() { return first; }
+        Node<E> nextNode(Node<E> n) { return n.next; }
+    }
+
+    /** Descending iterator */
+    private class DescendingItr extends AbstractItr {
+        Node<E> firstNode() { return last; }
+        Node<E> nextNode(Node<E> n) { return n.prev; }
+    }
+
+    /**
+     * Save the state of this deque to a stream (that is, serialize it).
+     *
+     * @serialData The capacity (int), followed by elements (each an
+     * {@code Object}) in the proper order, followed by a null
+     * @param s the stream
+     */
+    private void writeObject(java.io.ObjectOutputStream s)
+        throws java.io.IOException {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            // Write out capacity and any hidden stuff
+            s.defaultWriteObject();
+            // Write out all elements in the proper order.
+            for (Node<E> p = first; p != null; p = p.next)
+                s.writeObject(p.item);
+            // Use trailing null as sentinel
+            s.writeObject(null);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Reconstitute this deque from a stream (that is,
+     * deserialize it).
+     * @param s the stream
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        count = 0;
+        first = null;
+        last = null;
+        // Read in all elements and place in queue
+        for (;;) {
+            @SuppressWarnings("unchecked")
+            E item = (E)s.readObject();
+            if (item == null)
+                break;
+            add(item);
+        }
+    }
+
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
index e06f7bd..1a8e412 100644
--- a/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
+++ b/concurrent/src/main/java/java/util/concurrent/LinkedBlockingQueue.java
@@ -5,14 +5,19 @@
  */
 
 package java.util.concurrent;
-import java.util.concurrent.atomic.*;
-import java.util.concurrent.locks.*;
-import java.util.*;
 
 // BEGIN android-note
 // removed link to collections framework docs
 // END android-note
 
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.AbstractQueue;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
 /**
  * An optionally-bounded {@linkplain BlockingQueue blocking queue} based on
  * linked nodes.
@@ -57,15 +62,43 @@
      * items have been entered since the signal. And symmetrically for
      * takes signalling puts. Operations such as remove(Object) and
      * iterators acquire both locks.
+     *
+     * Visibility between writers and readers is provided as follows:
+     *
+     * Whenever an element is enqueued, the putLock is acquired and
+     * count updated.  A subsequent reader guarantees visibility to the
+     * enqueued Node by either acquiring the putLock (via fullyLock)
+     * or by acquiring the takeLock, and then reading n = count.get();
+     * this gives visibility to the first n items.
+     *
+     * To implement weakly consistent iterators, it appears we need to
+     * keep all Nodes GC-reachable from a predecessor dequeued Node.
+     * That would cause two problems:
+     * - allow a rogue Iterator to cause unbounded memory retention
+     * - cause cross-generational linking of old Nodes to new Nodes if
+     *   a Node was tenured while live, which generational GCs have a
+     *   hard time dealing with, causing repeated major collections.
+     * However, only non-deleted Nodes need to be reachable from
+     * dequeued Nodes, and reachability does not necessarily have to
+     * be of the kind understood by the GC.  We use the trick of
+     * linking a Node that has just been dequeued to itself.  Such a
+     * self-link implicitly means to advance to head.next.
      */
 
     /**
      * Linked list node class
      */
     static class Node<E> {
-        /** The item, volatile to ensure barrier separating write and read */
-        volatile E item;
+        E item;
+
+        /**
+         * One of:
+         * - the real successor Node
+         * - this Node, meaning the successor is head.next
+         * - null, meaning there is no successor (this is the last node)
+         */
         Node<E> next;
+
         Node(E x) { item = x; }
     }
 
@@ -75,10 +108,16 @@
     /** Current number of elements */
     private final AtomicInteger count = new AtomicInteger(0);
 
-    /** Head of linked list */
+    /**
+     * Head of linked list.
+     * Invariant: head.item == null
+     */
     private transient Node<E> head;
 
-    /** Tail of linked list */
+    /**
+     * Tail of linked list.
+     * Invariant: last.next == null
+     */
     private transient Node<E> last;
 
     /** Lock held by take, poll, etc */
@@ -122,20 +161,26 @@
 
     /**
      * Creates a node and links it at end of queue.
+     *
      * @param x the item
      */
-    private void insert(E x) {
+    private void enqueue(E x) {
+        // assert putLock.isHeldByCurrentThread();
+        // assert last.next == null;
         last = last.next = new Node<E>(x);
     }
 
     /**
-     * Removes a node from head of queue,
+     * Removes a node from head of queue.
+     *
      * @return the node
      */
-    private E extract() {
+    private E dequeue() {
+        // assert takeLock.isHeldByCurrentThread();
+        // assert head.item == null;
         Node<E> h = head;
         Node<E> first = h.next;
-        h.next = null; // help GC
+        h.next = h; // help GC
         head = first;
         E x = first.item;
         first.item = null;
@@ -145,7 +190,7 @@
     /**
      * Lock to prevent both puts and takes.
      */
-    private void fullyLock() {
+    void fullyLock() {
         putLock.lock();
         takeLock.lock();
     }
@@ -153,14 +198,21 @@
     /**
      * Unlock to allow both puts and takes.
      */
-    private void fullyUnlock() {
+    void fullyUnlock() {
         takeLock.unlock();
         putLock.unlock();
     }
 
+//     /**
+//      * Tells whether both locks are held by current thread.
+//      */
+//     boolean isFullyLocked() {
+//         return (putLock.isHeldByCurrentThread() &&
+//                 takeLock.isHeldByCurrentThread());
+//     }
 
     /**
-     * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of
+     * Creates a {@code LinkedBlockingQueue} with a capacity of
      * {@link Integer#MAX_VALUE}.
      */
     public LinkedBlockingQueue() {
@@ -168,10 +220,10 @@
     }
 
     /**
-     * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity.
+     * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
      *
      * @param capacity the capacity of this queue
-     * @throws IllegalArgumentException if <tt>capacity</tt> is not greater
+     * @throws IllegalArgumentException if {@code capacity} is not greater
      *         than zero
      */
     public LinkedBlockingQueue(int capacity) {
@@ -181,7 +233,7 @@
     }
 
     /**
-     * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of
+     * Creates a {@code LinkedBlockingQueue} with a capacity of
      * {@link Integer#MAX_VALUE}, initially containing the elements of the
      * given collection,
      * added in traversal order of the collection's iterator.
@@ -192,8 +244,22 @@
      */
     public LinkedBlockingQueue(Collection<? extends E> c) {
         this(Integer.MAX_VALUE);
-        for (E e : c)
-            add(e);
+        final ReentrantLock putLock = this.putLock;
+        putLock.lock(); // Never contended, but necessary for visibility
+        try {
+            int n = 0;
+            for (E e : c) {
+                if (e == null)
+                    throw new NullPointerException();
+                if (n == capacity)
+                    throw new IllegalStateException("Queue full");
+                enqueue(e);
+                ++n;
+            }
+            count.set(n);
+        } finally {
+            putLock.unlock();
+        }
     }
 
 
@@ -214,10 +280,10 @@
      * Returns the number of additional elements that this queue can ideally
      * (in the absence of memory or resource constraints) accept without
      * blocking. This is always equal to the initial capacity of this queue
-     * less the current <tt>size</tt> of this queue.
+     * less the current {@code size} of this queue.
      *
      * <p>Note that you <em>cannot</em> always tell if an attempt to insert
-     * an element will succeed by inspecting <tt>remainingCapacity</tt>
+     * an element will succeed by inspecting {@code remainingCapacity}
      * because it may be the case that another thread is about to
      * insert or remove an element.
      */
@@ -234,8 +300,8 @@
      */
     public void put(E e) throws InterruptedException {
         if (e == null) throw new NullPointerException();
-        // Note: convention in all put/take/etc is to preset
-        // local var holding count  negative to indicate failure unless set.
+        // Note: convention in all put/take/etc is to preset local var
+        // holding count negative to indicate failure unless set.
         int c = -1;
         final ReentrantLock putLock = this.putLock;
         final AtomicInteger count = this.count;
@@ -246,18 +312,13 @@
              * not protected by lock. This works because count can
              * only decrease at this point (all other puts are shut
              * out by lock), and we (or some other waiting put) are
-             * signalled if it ever changes from
-             * capacity. Similarly for all other uses of count in
-             * other wait guards.
+             * signalled if it ever changes from capacity. Similarly
+             * for all other uses of count in other wait guards.
              */
-            try {
-                while (count.get() == capacity)
-                    notFull.await();
-            } catch (InterruptedException ie) {
-                notFull.signal(); // propagate to a non-interrupted thread
-                throw ie;
+            while (count.get() == capacity) {
+                notFull.await();
             }
-            insert(e);
+            enqueue(e);
             c = count.getAndIncrement();
             if (c + 1 < capacity)
                 notFull.signal();
@@ -272,7 +333,7 @@
      * Inserts the specified element at the tail of this queue, waiting if
      * necessary up to the specified wait time for space to become available.
      *
-     * @return <tt>true</tt> if successful, or <tt>false</tt> if
+     * @return {@code true} if successful, or {@code false} if
      *         the specified waiting time elapses before space is available.
      * @throws InterruptedException {@inheritDoc}
      * @throws NullPointerException {@inheritDoc}
@@ -287,23 +348,15 @@
         final AtomicInteger count = this.count;
         putLock.lockInterruptibly();
         try {
-            for (;;) {
-                if (count.get() < capacity) {
-                    insert(e);
-                    c = count.getAndIncrement();
-                    if (c + 1 < capacity)
-                        notFull.signal();
-                    break;
-                }
+            while (count.get() == capacity) {
                 if (nanos <= 0)
                     return false;
-                try {
-                    nanos = notFull.awaitNanos(nanos);
-                } catch (InterruptedException ie) {
-                    notFull.signal(); // propagate to a non-interrupted thread
-                    throw ie;
-                }
+                nanos = notFull.awaitNanos(nanos);
             }
+            enqueue(e);
+            c = count.getAndIncrement();
+            if (c + 1 < capacity)
+                notFull.signal();
         } finally {
             putLock.unlock();
         }
@@ -315,7 +368,7 @@
     /**
      * Inserts the specified element at the tail of this queue if it is
      * possible to do so immediately without exceeding the queue's capacity,
-     * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
+     * returning {@code true} upon success and {@code false} if this queue
      * is full.
      * When using a capacity-restricted queue, this method is generally
      * preferable to method {@link BlockingQueue#add add}, which can fail to
@@ -333,7 +386,7 @@
         putLock.lock();
         try {
             if (count.get() < capacity) {
-                insert(e);
+                enqueue(e);
                 c = count.getAndIncrement();
                 if (c + 1 < capacity)
                     notFull.signal();
@@ -354,15 +407,10 @@
         final ReentrantLock takeLock = this.takeLock;
         takeLock.lockInterruptibly();
         try {
-            try {
-                while (count.get() == 0)
-                    notEmpty.await();
-            } catch (InterruptedException ie) {
-                notEmpty.signal(); // propagate to a non-interrupted thread
-                throw ie;
+            while (count.get() == 0) {
+                notEmpty.await();
             }
-
-            x = extract();
+            x = dequeue();
             c = count.getAndDecrement();
             if (c > 1)
                 notEmpty.signal();
@@ -382,23 +430,15 @@
         final ReentrantLock takeLock = this.takeLock;
         takeLock.lockInterruptibly();
         try {
-            for (;;) {
-                if (count.get() > 0) {
-                    x = extract();
-                    c = count.getAndDecrement();
-                    if (c > 1)
-                        notEmpty.signal();
-                    break;
-                }
+            while (count.get() == 0) {
                 if (nanos <= 0)
                     return null;
-                try {
-                    nanos = notEmpty.awaitNanos(nanos);
-                } catch (InterruptedException ie) {
-                    notEmpty.signal(); // propagate to a non-interrupted thread
-                    throw ie;
-                }
+                nanos = notEmpty.awaitNanos(nanos);
             }
+            x = dequeue();
+            c = count.getAndDecrement();
+            if (c > 1)
+                notEmpty.signal();
         } finally {
             takeLock.unlock();
         }
@@ -417,7 +457,7 @@
         takeLock.lock();
         try {
             if (count.get() > 0) {
-                x = extract();
+                x = dequeue();
                 c = count.getAndDecrement();
                 if (c > 1)
                     notEmpty.signal();
@@ -430,7 +470,6 @@
         return x;
     }
 
-
     public E peek() {
         if (count.get() == 0)
             return null;
@@ -448,43 +487,47 @@
     }
 
     /**
+     * Unlinks interior Node p with predecessor trail.
+     */
+    void unlink(Node<E> p, Node<E> trail) {
+        // assert isFullyLocked();
+        // p.next is not changed, to allow iterators that are
+        // traversing p to maintain their weak-consistency guarantee.
+        p.item = null;
+        trail.next = p.next;
+        if (last == p)
+            last = trail;
+        if (count.getAndDecrement() == capacity)
+            notFull.signal();
+    }
+
+    /**
      * Removes a single instance of the specified element from this queue,
-     * if it is present.  More formally, removes an element <tt>e</tt> such
-     * that <tt>o.equals(e)</tt>, if this queue contains one or more such
+     * if it is present.  More formally, removes an element {@code e} such
+     * that {@code o.equals(e)}, if this queue contains one or more such
      * elements.
-     * Returns <tt>true</tt> if this queue contained the specified element
+     * Returns {@code true} if this queue contained the specified element
      * (or equivalently, if this queue changed as a result of the call).
      *
      * @param o element to be removed from this queue, if present
-     * @return <tt>true</tt> if this queue changed as a result of the call
+     * @return {@code true} if this queue changed as a result of the call
      */
     public boolean remove(Object o) {
         if (o == null) return false;
-        boolean removed = false;
         fullyLock();
         try {
-            Node<E> trail = head;
-            Node<E> p = head.next;
-            while (p != null) {
+            for (Node<E> trail = head, p = trail.next;
+                 p != null;
+                 trail = p, p = p.next) {
                 if (o.equals(p.item)) {
-                    removed = true;
-                    break;
+                    unlink(p, trail);
+                    return true;
                 }
-                trail = p;
-                p = p.next;
             }
-            if (removed) {
-                p.item = null;
-                trail.next = p.next;
-                if (last == p)
-                    last = trail;
-                if (count.getAndDecrement() == capacity)
-                    notFull.signalAll();
-            }
+            return false;
         } finally {
             fullyUnlock();
         }
-        return removed;
     }
 
     /**
@@ -524,22 +567,22 @@
      * <p>If this queue fits in the specified array with room to spare
      * (i.e., the array has more elements than this queue), the element in
      * the array immediately following the end of the queue is set to
-     * <tt>null</tt>.
+     * {@code null}.
      *
      * <p>Like the {@link #toArray()} method, this method acts as bridge between
      * array-based and collection-based APIs.  Further, this method allows
      * precise control over the runtime type of the output array, and may,
      * under certain circumstances, be used to save allocation costs.
      *
-     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+     * <p>Suppose {@code x} is a queue known to contain only strings.
      * The following code can be used to dump the queue into a newly
-     * allocated array of <tt>String</tt>:
+     * allocated array of {@code String}:
      *
      * <pre>
      *     String[] y = x.toArray(new String[0]);</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of the queue are to
      *          be stored, if it is big enough; otherwise, a new array of the
@@ -550,6 +593,7 @@
      *         this queue
      * @throws NullPointerException if the specified array is null
      */
+    @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
         fullyLock();
         try {
@@ -559,7 +603,7 @@
                     (a.getClass().getComponentType(), size);
 
             int k = 0;
-            for (Node p = head.next; p != null; p = p.next)
+            for (Node<E> p = head.next; p != null; p = p.next)
                 a[k++] = (T)p.item;
             if (a.length > k)
                 a[k] = null;
@@ -585,11 +629,14 @@
     public void clear() {
         fullyLock();
         try {
-            head.next = null;
-            assert head.item == null;
-            last = head;
+            for (Node<E> p, h = head; (p = h.next) != null; h = p) {
+                h.next = h;
+                p.item = null;
+            }
+            head = last;
+            // assert head.item == null && head.next == null;
             if (count.getAndSet(0) == capacity)
-                notFull.signalAll();
+                notFull.signal();
         } finally {
             fullyUnlock();
         }
@@ -602,30 +649,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        if (c == null)
-            throw new NullPointerException();
-        if (c == this)
-            throw new IllegalArgumentException();
-        Node<E> first;
-        fullyLock();
-        try {
-            first = head.next;
-            head.next = null;
-            assert head.item == null;
-            last = head;
-            if (count.getAndSet(0) == capacity)
-                notFull.signalAll();
-        } finally {
-            fullyUnlock();
-        }
-        // Transfer the elements outside of locks
-        int n = 0;
-        for (Node<E> p = first; p != null; p = p.next) {
-            c.add(p.item);
-            p.item = null;
-            ++n;
-        }
-        return n;
+        return drainTo(c, Integer.MAX_VALUE);
     }
 
     /**
@@ -639,34 +663,44 @@
             throw new NullPointerException();
         if (c == this)
             throw new IllegalArgumentException();
-        fullyLock();
+        boolean signalNotFull = false;
+        final ReentrantLock takeLock = this.takeLock;
+        takeLock.lock();
         try {
-            int n = 0;
-            Node<E> p = head.next;
-            while (p != null && n < maxElements) {
-                c.add(p.item);
-                p.item = null;
-                p = p.next;
-                ++n;
+            int n = Math.min(maxElements, count.get());
+            // count.get provides visibility to first n Nodes
+            Node<E> h = head;
+            int i = 0;
+            try {
+                while (i < n) {
+                    Node<E> p = h.next;
+                    c.add(p.item);
+                    p.item = null;
+                    h.next = h;
+                    h = p;
+                    ++i;
+                }
+                return n;
+            } finally {
+                // Restore invariants even if c.add() threw
+                if (i > 0) {
+                    // assert h.item == null;
+                    head = h;
+                    signalNotFull = (count.getAndAdd(-i) == capacity);
+                }
             }
-            if (n != 0) {
-                head.next = p;
-                assert head.item == null;
-                if (p == null)
-                    last = head;
-                if (count.getAndAdd(-n) == capacity)
-                    notFull.signalAll();
-            }
-            return n;
         } finally {
-            fullyUnlock();
+            takeLock.unlock();
+            if (signalNotFull)
+                signalNotFull();
         }
     }
 
     /**
      * Returns an iterator over the elements in this queue in proper sequence.
-     * The returned <tt>Iterator</tt> is a "weakly consistent" iterator that
-     * will never throw {@link ConcurrentModificationException},
+     * The returned {@code Iterator} is a "weakly consistent" iterator that
+     * will never throw {@link java.util.ConcurrentModificationException
+     * ConcurrentModificationException},
      * and guarantees to traverse elements as they existed upon
      * construction of the iterator, and may (but is not guaranteed to)
      * reflect any modifications subsequent to construction.
@@ -679,7 +713,7 @@
 
     private class Itr implements Iterator<E> {
         /*
-         * Basic weak-consistent iterator.  At all times hold the next
+         * Basic weakly-consistent iterator.  At all times hold the next
          * item to hand out so that if hasNext() reports true, we will
          * still have it to return even if lost race with a take etc.
          */
@@ -688,17 +722,13 @@
         private E currentElement;
 
         Itr() {
-            final ReentrantLock putLock = LinkedBlockingQueue.this.putLock;
-            final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock;
-            putLock.lock();
-            takeLock.lock();
+            fullyLock();
             try {
                 current = head.next;
                 if (current != null)
                     currentElement = current.item;
             } finally {
-                takeLock.unlock();
-                putLock.unlock();
+                fullyUnlock();
             }
         }
 
@@ -706,54 +736,56 @@
             return current != null;
         }
 
+        /**
+         * Returns the next live successor of p, or null if no such.
+         *
+         * Unlike other traversal methods, iterators need to handle both:
+         * - dequeued nodes (p.next == p)
+         * - (possibly multiple) interior removed nodes (p.item == null)
+         */
+        private Node<E> nextNode(Node<E> p) {
+            for (;;) {
+                Node<E> s = p.next;
+                if (s == p)
+                    return head.next;
+                if (s == null || s.item != null)
+                    return s;
+                p = s;
+            }
+        }
+
         public E next() {
-            final ReentrantLock putLock = LinkedBlockingQueue.this.putLock;
-            final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock;
-            putLock.lock();
-            takeLock.lock();
+            fullyLock();
             try {
                 if (current == null)
                     throw new NoSuchElementException();
                 E x = currentElement;
                 lastRet = current;
-                current = current.next;
-                if (current != null)
-                    currentElement = current.item;
+                current = nextNode(current);
+                currentElement = (current == null) ? null : current.item;
                 return x;
             } finally {
-                takeLock.unlock();
-                putLock.unlock();
+                fullyUnlock();
             }
         }
 
         public void remove() {
             if (lastRet == null)
                 throw new IllegalStateException();
-            final ReentrantLock putLock = LinkedBlockingQueue.this.putLock;
-            final ReentrantLock takeLock = LinkedBlockingQueue.this.takeLock;
-            putLock.lock();
-            takeLock.lock();
+            fullyLock();
             try {
                 Node<E> node = lastRet;
                 lastRet = null;
-                Node<E> trail = head;
-                Node<E> p = head.next;
-                while (p != null && p != node) {
-                    trail = p;
-                    p = p.next;
-                }
-                if (p == node) {
-                    p.item = null;
-                    trail.next = p.next;
-                    if (last == p)
-                        last = trail;
-                    int c = count.getAndDecrement();
-                    if (c == capacity)
-                        notFull.signalAll();
+                for (Node<E> trail = head, p = trail.next;
+                     p != null;
+                     trail = p, p = p.next) {
+                    if (p == node) {
+                        unlink(p, trail);
+                        break;
+                    }
                 }
             } finally {
-                takeLock.unlock();
-                putLock.unlock();
+                fullyUnlock();
             }
         }
     }
@@ -762,7 +794,7 @@
      * Save the state to a stream (that is, serialize it).
      *
      * @serialData The capacity is emitted (int), followed by all of
-     * its elements (each an <tt>Object</tt>) in the proper order,
+     * its elements (each an {@code Object}) in the proper order,
      * followed by a null
      * @param s the stream
      */
@@ -788,6 +820,7 @@
     /**
      * Reconstitute this queue instance from a stream (that is,
      * deserialize it).
+     *
      * @param s the stream
      */
     private void readObject(java.io.ObjectInputStream s)
@@ -800,6 +833,7 @@
 
         // Read in all elements and place in queue
         for (;;) {
+            @SuppressWarnings("unchecked")
             E item = (E)s.readObject();
             if (item == null)
                 break;
diff --git a/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java b/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
index 7a33dc7..35d7b89 100644
--- a/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
+++ b/concurrent/src/main/java/java/util/concurrent/PriorityBlockingQueue.java
@@ -146,7 +146,6 @@
         return offer(e);
     }
 
-    // BEGIN android-changed
     /**
      * Inserts the specified element into this priority queue.
      *
diff --git a/concurrent/src/main/java/java/util/concurrent/RunnableFuture.java b/concurrent/src/main/java/java/util/concurrent/RunnableFuture.java
new file mode 100644
index 0000000..d74211d
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/RunnableFuture.java
@@ -0,0 +1,25 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A {@link Future} that is {@link Runnable}. Successful execution of
+ * the <tt>run</tt> method causes completion of the <tt>Future</tt>
+ * and allows access to its results.
+ * @see FutureTask
+ * @see Executor
+ * @since 1.6
+ * @author Doug Lea
+ * @param <V> The result type returned by this Future's <tt>get</tt> method
+ */
+public interface RunnableFuture<V> extends Runnable, Future<V> {
+    /**
+     * Sets this Future to the result of its computation
+     * unless it has been cancelled.
+     */
+    void run();
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/RunnableScheduledFuture.java b/concurrent/src/main/java/java/util/concurrent/RunnableScheduledFuture.java
new file mode 100644
index 0000000..0e8cc32
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/RunnableScheduledFuture.java
@@ -0,0 +1,29 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+
+/**
+ * A {@link ScheduledFuture} that is {@link Runnable}. Successful
+ * execution of the <tt>run</tt> method causes completion of the
+ * <tt>Future</tt> and allows access to its results.
+ * @see FutureTask
+ * @see Executor
+ * @since 1.6
+ * @author Doug Lea
+ * @param <V> The result type returned by this Future's <tt>get</tt> method
+ */
+public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> {
+
+    /**
+     * Returns true if this is a periodic task. A periodic task may
+     * re-run according to some schedule. A non-periodic task can be
+     * run only once.
+     *
+     * @return true if this task is periodic
+     */
+    boolean isPeriodic();
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java b/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
index 83ffb99..7e69936 100644
--- a/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
+++ b/concurrent/src/main/java/java/util/concurrent/ScheduledThreadPoolExecutor.java
@@ -4,10 +4,6 @@
  * http://creativecommons.org/licenses/publicdomain
  */
 
-/*
- * Modified in Apache Harmony.
- */
-
 package java.util.concurrent;
 import java.util.concurrent.atomic.*;
 import java.util.concurrent.locks.*;
@@ -27,6 +23,15 @@
  * execution time are enabled in first-in-first-out (FIFO) order of
  * submission.
  *
+ * <p>When a submitted task is cancelled before it is run, execution
+ * is suppressed. By default, such a cancelled task is not
+ * automatically removed from the work queue until its delay
+ * elapses. While this enables further inspection and monitoring, it
+ * may also cause unbounded retention of cancelled tasks. To avoid
+ * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which
+ * causes tasks to be immediately removed from the work queue at
+ * time of cancellation.
+ *
  * <p>Successive executions of a task scheduled via
  * <code>scheduleAtFixedRate</code> or
  * <code>scheduleWithFixedDelay</code> do not overlap. While different
@@ -37,9 +42,47 @@
  *
  * <p>While this class inherits from {@link ThreadPoolExecutor}, a few
  * of the inherited tuning methods are not useful for it. In
- * particular, because it acts as a fixed-sized pool using {@code
- * corePoolSize} threads and an unbounded queue, adjustments to {@code
- * maximumPoolSize} have no useful effect.
+ * particular, because it acts as a fixed-sized pool using
+ * {@code corePoolSize} threads and an unbounded queue, adjustments
+ * to {@code maximumPoolSize} have no useful effect. Additionally, it
+ * is almost never a good idea to set {@code corePoolSize} to zero or
+ * use {@code allowCoreThreadTimeOut} because this may leave the pool
+ * without threads to handle tasks once they become eligible to run.
+ *
+ * <p><b>Extension notes:</b> This class overrides the
+ * {@link ThreadPoolExecutor#execute execute} and
+ * {@link AbstractExecutorService#submit(Runnable) submit}
+ * methods to generate internal {@link ScheduledFuture} objects to
+ * control per-task delays and scheduling.  To preserve
+ * functionality, any further overrides of these methods in
+ * subclasses must invoke superclass versions, which effectively
+ * disables additional task customization.  However, this class
+ * provides alternative protected extension method
+ * {@code decorateTask} (one version each for {@code Runnable} and
+ * {@code Callable}) that can be used to customize the concrete task
+ * types used to execute commands entered via {@code execute},
+ * {@code submit}, {@code schedule}, {@code scheduleAtFixedRate},
+ * and {@code scheduleWithFixedDelay}.  By default, a
+ * {@code ScheduledThreadPoolExecutor} uses a task type extending
+ * {@link FutureTask}. However, this may be modified or replaced using
+ * subclasses of the form:
+ *
+ *  <pre> {@code
+ * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor {
+ *
+ *   static class CustomTask<V> implements RunnableScheduledFuture<V> { ... }
+ *
+ *   protected <V> RunnableScheduledFuture<V> decorateTask(
+ *                Runnable r, RunnableScheduledFuture<V> task) {
+ *       return new CustomTask<V>(r, task);
+ *   }
+ *
+ *   protected <V> RunnableScheduledFuture<V> decorateTask(
+ *                Callable<V> c, RunnableScheduledFuture<V> task) {
+ *       return new CustomTask<V>(c, task);
+ *   }
+ *   // ... add constructors, etc.
+ * }}</pre>
  *
  * @since 1.5
  * @author Doug Lea
@@ -96,23 +139,15 @@
      */
     private static final AtomicLong sequencer = new AtomicLong(0);
 
-
-    /**
-     * Value of System.nanoTime upon static initialization.  This is
-     * used as an offset by now() to avoid wraparound of time values
-     * that would make them appear negative.
-     */
-    static final long initialNanoTime = System.nanoTime();
-
     /**
      * Returns current nanosecond time.
      */
-    static long now() {
-        return System.nanoTime() - initialNanoTime;
+    final long now() {
+        return System.nanoTime();
     }
 
     private class ScheduledFutureTask<V>
-            extends FutureTask<V> implements ScheduledFuture<V> {
+            extends FutureTask<V> implements RunnableScheduledFuture<V> {
 
         /** Sequence number to break ties FIFO */
         private final long sequenceNumber;
@@ -129,7 +164,7 @@
         private final long period;
 
         /** The actual task to be re-enqueued by reExecutePeriodic */
-        ScheduledFutureTask<V> outerTask = this;
+        RunnableScheduledFuture<V> outerTask = this;
 
         /**
          * Index into delay queue, to support faster cancellation.
@@ -167,8 +202,7 @@
         }
 
         public long getDelay(TimeUnit unit) {
-            long d = time - now();
-            return d<=0? 0 : unit.convert(d, TimeUnit.NANOSECONDS);
+            return unit.convert(time - now(), TimeUnit.NANOSECONDS);
         }
 
         public int compareTo(Delayed other) {
@@ -208,7 +242,7 @@
             if (p > 0)
                 time += p;
             else
-                time = now() - p;
+                time = triggerTime(-p);
         }
 
         public boolean cancel(boolean mayInterruptIfRunning) {
@@ -257,7 +291,7 @@
      *
      * @param task the task
      */
-    private void delayedExecute(ScheduledFutureTask<?> task) {
+    private void delayedExecute(RunnableScheduledFuture<?> task) {
         if (isShutdown())
             reject(task);
         else {
@@ -277,7 +311,7 @@
      *
      * @param task the task
      */
-    void reExecutePeriodic(ScheduledFutureTask<?> task) {
+    void reExecutePeriodic(RunnableScheduledFuture<?> task) {
         if (canRunInCurrentRunState(true)) {
             super.getQueue().add(task);
             if (!canRunInCurrentRunState(true) && remove(task))
@@ -302,9 +336,9 @@
         else {
             // Traverse snapshot to avoid iterator exceptions
             for (Object e : q.toArray()) {
-                if (e instanceof ScheduledFutureTask) {
-                    ScheduledFutureTask<?> t =
-                        (ScheduledFutureTask<?>)e;
+                if (e instanceof RunnableScheduledFuture) {
+                    RunnableScheduledFuture<?> t =
+                        (RunnableScheduledFuture<?>)e;
                     if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) ||
                         t.isCancelled()) { // also remove if already cancelled
                         if (q.remove(t))
@@ -317,11 +351,43 @@
     }
 
     /**
+     * Modifies or replaces the task used to execute a runnable.
+     * This method can be used to override the concrete
+     * class used for managing internal tasks.
+     * The default implementation simply returns the given task.
+     *
+     * @param runnable the submitted Runnable
+     * @param task the task created to execute the runnable
+     * @return a task that can execute the runnable
+     * @since 1.6
+     */
+    protected <V> RunnableScheduledFuture<V> decorateTask(
+        Runnable runnable, RunnableScheduledFuture<V> task) {
+        return task;
+    }
+
+    /**
+     * Modifies or replaces the task used to execute a callable.
+     * This method can be used to override the concrete
+     * class used for managing internal tasks.
+     * The default implementation simply returns the given task.
+     *
+     * @param callable the submitted Callable
+     * @param task the task created to execute the callable
+     * @return a task that can execute the callable
+     * @since 1.6
+     */
+    protected <V> RunnableScheduledFuture<V> decorateTask(
+        Callable<V> callable, RunnableScheduledFuture<V> task) {
+        return task;
+    }
+
+    /**
      * Creates a new {@code ScheduledThreadPoolExecutor} with the
      * given core pool size.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @throws IllegalArgumentException if {@code corePoolSize < 0}
      */
     public ScheduledThreadPoolExecutor(int corePoolSize) {
@@ -334,7 +400,7 @@
      * given initial parameters.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param threadFactory the factory to use when the executor
      *        creates a new thread
      * @throws IllegalArgumentException if {@code corePoolSize < 0}
@@ -351,7 +417,7 @@
      * initial parameters.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param handler the handler to use when execution is blocked
      *        because the thread bounds and queue capacities are reached
      * @throws IllegalArgumentException if {@code corePoolSize < 0}
@@ -368,7 +434,7 @@
      * initial parameters.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param threadFactory the factory to use when the executor
      *        creates a new thread
      * @param handler the handler to use when execution is blocked
@@ -385,17 +451,35 @@
     }
 
     /**
-     * Returns the trigger time of a delayed action
+     * Returns the trigger time of a delayed action.
      */
-    private static long nextTriggerTime(long delay, TimeUnit unit) {
-        long triggerTime;
-        long now = now();
-        if (delay <= 0)
-            return now;            // avoid negative trigger times
-        else if ((triggerTime = now + unit.toNanos(delay)) < 0)
-            return Long.MAX_VALUE; // avoid numerical overflow
-        else
-            return triggerTime;
+    private long triggerTime(long delay, TimeUnit unit) {
+        return triggerTime(unit.toNanos((delay < 0) ? 0 : delay));
+    }
+
+    /**
+     * Returns the trigger time of a delayed action.
+     */
+    long triggerTime(long delay) {
+        return now() +
+            ((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
+    }
+
+    /**
+     * Constrains the values of all delays in the queue to be within
+     * Long.MAX_VALUE of each other, to avoid overflow in compareTo.
+     * This may occur if a task is eligible to be dequeued, but has
+     * not yet been, while some other task is added with a delay of
+     * Long.MAX_VALUE.
+     */
+    private long overflowFree(long delay) {
+        Delayed head = (Delayed) super.getQueue().peek();
+        if (head != null) {
+            long headDelay = head.getDelay(TimeUnit.NANOSECONDS);
+            if (headDelay < 0 && (delay - headDelay < 0))
+                delay = Long.MAX_VALUE + headDelay;
+        }
+        return delay;
     }
 
     /**
@@ -407,9 +491,9 @@
                                        TimeUnit unit) {
         if (command == null || unit == null)
             throw new NullPointerException();
-        long triggerTime = nextTriggerTime(delay, unit);
-        ScheduledFutureTask<?> t
-                = new ScheduledFutureTask<Void>(command, null, triggerTime);
+        RunnableScheduledFuture<?> t = decorateTask(command,
+            new ScheduledFutureTask<Void>(command, null,
+                                          triggerTime(delay, unit)));
         delayedExecute(t);
         return t;
     }
@@ -423,9 +507,9 @@
                                            TimeUnit unit) {
         if (callable == null || unit == null)
             throw new NullPointerException();
-        long triggerTime = nextTriggerTime(delay, unit);
-        ScheduledFutureTask<V> t
-                = new ScheduledFutureTask<V>(callable, triggerTime);
+        RunnableScheduledFuture<V> t = decorateTask(callable,
+            new ScheduledFutureTask<V>(callable,
+                                       triggerTime(delay, unit)));
         delayedExecute(t);
         return t;
     }
@@ -443,16 +527,15 @@
             throw new NullPointerException();
         if (period <= 0)
             throw new IllegalArgumentException();
-        if (initialDelay < 0) initialDelay = 0;
-        long triggerTime = nextTriggerTime(initialDelay, unit);
         ScheduledFutureTask<Void> sft =
             new ScheduledFutureTask<Void>(command,
                                           null,
-                                          triggerTime,
+                                          triggerTime(initialDelay, unit),
                                           unit.toNanos(period));
-        sft.outerTask = sft;
-        delayedExecute(sft);
-        return sft;
+        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
+        sft.outerTask = t;
+        delayedExecute(t);
+        return t;
     }
 
     /**
@@ -468,15 +551,15 @@
             throw new NullPointerException();
         if (delay <= 0)
             throw new IllegalArgumentException();
-        long triggerTime = nextTriggerTime(initialDelay, unit);
         ScheduledFutureTask<Void> sft =
             new ScheduledFutureTask<Void>(command,
                                           null,
-                                          triggerTime,
+                                          triggerTime(initialDelay, unit),
                                           unit.toNanos(-delay));
-        sft.outerTask = sft;
-        delayedExecute(sft);
-        return sft;
+        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
+        sft.outerTask = t;
+        delayedExecute(t);
+        return t;
     }
 
     /**
@@ -595,6 +678,33 @@
     }
 
     /**
+     * Sets the policy on whether cancelled tasks should be immediately
+     * removed from the work queue at time of cancellation.  This value is
+     * by default {@code false}.
+     *
+     * @param value if {@code true}, remove on cancellation, else don't
+     * @see #getRemoveOnCancelPolicy
+     * @since 1.7
+     */
+    /*public*/ void setRemoveOnCancelPolicy(boolean value) { // android-changed
+        removeOnCancel = value;
+    }
+
+    /**
+     * Gets the policy on whether cancelled tasks should be immediately
+     * removed from the work queue at time of cancellation.  This value is
+     * by default {@code false}.
+     *
+     * @return {@code true} if cancelled tasks are immediately removed
+     *         from the queue
+     * @see #setRemoveOnCancelPolicy
+     * @since 1.7
+     */
+    /*public*/ boolean getRemoveOnCancelPolicy() { // android-changed
+        return removeOnCancel;
+    }
+
+    /**
      * Initiates an orderly shutdown in which previously submitted
      * tasks are executed, but no new tasks will be accepted.
      * Invocation has no additional effect if already shut down.
@@ -688,8 +798,8 @@
          */
 
         private static final int INITIAL_CAPACITY = 16;
-        private ScheduledFutureTask[] queue =
-            new ScheduledFutureTask[INITIAL_CAPACITY];
+        private RunnableScheduledFuture[] queue =
+            new RunnableScheduledFuture[INITIAL_CAPACITY];
         private final ReentrantLock lock = new ReentrantLock();
         private int size = 0;
 
@@ -720,7 +830,7 @@
         /**
          * Set f's heapIndex if it is a ScheduledFutureTask.
          */
-        private void setIndex(ScheduledFutureTask f, int idx) {
+        private void setIndex(RunnableScheduledFuture f, int idx) {
             if (f instanceof ScheduledFutureTask)
                 ((ScheduledFutureTask)f).heapIndex = idx;
         }
@@ -729,10 +839,10 @@
          * Sift element added at bottom up to its heap-ordered spot.
          * Call only when holding lock.
          */
-        private void siftUp(int k, ScheduledFutureTask key) {
+        private void siftUp(int k, RunnableScheduledFuture key) {
             while (k > 0) {
                 int parent = (k - 1) >>> 1;
-                ScheduledFutureTask e = queue[parent];
+                RunnableScheduledFuture e = queue[parent];
                 if (key.compareTo(e) >= 0)
                     break;
                 queue[k] = e;
@@ -747,11 +857,11 @@
          * Sift element added at top down to its heap-ordered spot.
          * Call only when holding lock.
          */
-        private void siftDown(int k, ScheduledFutureTask key) {
+        private void siftDown(int k, RunnableScheduledFuture key) {
             int half = size >>> 1;
             while (k < half) {
                 int child = (k << 1) + 1;
-                ScheduledFutureTask c = queue[child];
+                RunnableScheduledFuture c = queue[child];
                 int right = child + 1;
                 if (right < size && c.compareTo(queue[right]) > 0)
                     c = queue[child = right];
@@ -773,7 +883,7 @@
             int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50%
             if (newCapacity < 0) // overflow
                 newCapacity = Integer.MAX_VALUE;
-            queue = Java6Arrays.copyOf(queue, newCapacity);
+            queue = Arrays.copyOf(queue, newCapacity);
         }
 
         /**
@@ -816,7 +926,7 @@
 
                 setIndex(queue[i], -1);
                 int s = --size;
-                ScheduledFutureTask replacement = queue[s];
+                RunnableScheduledFuture replacement = queue[s];
                 queue[s] = null;
                 if (s != i) {
                     siftDown(i, replacement);
@@ -847,7 +957,7 @@
             return Integer.MAX_VALUE;
         }
 
-        public ScheduledFutureTask peek() {
+        public RunnableScheduledFuture peek() {
             final ReentrantLock lock = this.lock;
             lock.lock();
             try {
@@ -860,7 +970,7 @@
         public boolean offer(Runnable x) {
             if (x == null)
                 throw new NullPointerException();
-            ScheduledFutureTask e = (ScheduledFutureTask)x;
+            RunnableScheduledFuture e = (RunnableScheduledFuture)x;
             final ReentrantLock lock = this.lock;
             lock.lock();
             try {
@@ -902,9 +1012,9 @@
          * holding lock.
          * @param f the task to remove and return
          */
-        private ScheduledFutureTask finishPoll(ScheduledFutureTask f) {
+        private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) {
             int s = --size;
-            ScheduledFutureTask x = queue[s];
+            RunnableScheduledFuture x = queue[s];
             queue[s] = null;
             if (s != 0)
                 siftDown(0, x);
@@ -912,11 +1022,11 @@
             return f;
         }
 
-        public ScheduledFutureTask poll() {
+        public RunnableScheduledFuture poll() {
             final ReentrantLock lock = this.lock;
             lock.lock();
             try {
-                ScheduledFutureTask first = queue[0];
+                RunnableScheduledFuture first = queue[0];
                 if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
                     return null;
                 else
@@ -926,12 +1036,12 @@
             }
         }
 
-        public ScheduledFutureTask take() throws InterruptedException {
+        public RunnableScheduledFuture take() throws InterruptedException {
             final ReentrantLock lock = this.lock;
             lock.lockInterruptibly();
             try {
                 for (;;) {
-                    ScheduledFutureTask first = queue[0];
+                    RunnableScheduledFuture first = queue[0];
                     if (first == null)
                         available.await();
                     else {
@@ -959,14 +1069,14 @@
             }
         }
 
-        public ScheduledFutureTask poll(long timeout, TimeUnit unit)
+        public RunnableScheduledFuture poll(long timeout, TimeUnit unit)
             throws InterruptedException {
             long nanos = unit.toNanos(timeout);
             final ReentrantLock lock = this.lock;
             lock.lockInterruptibly();
             try {
                 for (;;) {
-                    ScheduledFutureTask first = queue[0];
+                    RunnableScheduledFuture first = queue[0];
                     if (first == null) {
                         if (nanos <= 0)
                             return null;
@@ -1005,7 +1115,7 @@
             lock.lock();
             try {
                 for (int i = 0; i < size; i++) {
-                    ScheduledFutureTask t = queue[i];
+                    RunnableScheduledFuture t = queue[i];
                     if (t != null) {
                         queue[i] = null;
                         setIndex(t, -1);
@@ -1021,8 +1131,8 @@
          * Return and remove first element only if it is expired.
          * Used only by drainTo.  Call only when holding lock.
          */
-        private ScheduledFutureTask pollExpired() {
-            ScheduledFutureTask first = queue[0];
+        private RunnableScheduledFuture pollExpired() {
+            RunnableScheduledFuture first = queue[0];
             if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
                 return null;
             return finishPoll(first);
@@ -1036,7 +1146,7 @@
             final ReentrantLock lock = this.lock;
             lock.lock();
             try {
-                ScheduledFutureTask first;
+                RunnableScheduledFuture first;
                 int n = 0;
                 while ((first = pollExpired()) != null) {
                     c.add(first);
@@ -1058,7 +1168,7 @@
             final ReentrantLock lock = this.lock;
             lock.lock();
             try {
-                ScheduledFutureTask first;
+                RunnableScheduledFuture first;
                 int n = 0;
                 while (n < maxElements && (first = pollExpired()) != null) {
                     c.add(first);
@@ -1074,7 +1184,7 @@
             final ReentrantLock lock = this.lock;
             lock.lock();
             try {
-                return Java6Arrays.copyOf(queue, size, Object[].class);
+                return Arrays.copyOf(queue, size, Object[].class);
             } finally {
                 lock.unlock();
             }
@@ -1086,7 +1196,7 @@
             lock.lock();
             try {
                 if (a.length < size)
-                    return (T[]) Java6Arrays.copyOf(queue, size, a.getClass());
+                    return (T[]) Arrays.copyOf(queue, size, a.getClass());
                 System.arraycopy(queue, 0, a, 0, size);
                 if (a.length > size)
                     a[size] = null;
@@ -1097,18 +1207,18 @@
         }
 
         public Iterator<Runnable> iterator() {
-            return new Itr(Java6Arrays.copyOf(queue, size));
+            return new Itr(Arrays.copyOf(queue, size));
         }
 
         /**
          * Snapshot iterator that works off copy of underlying q array.
          */
         private class Itr implements Iterator<Runnable> {
-            final ScheduledFutureTask[] array;
+            final RunnableScheduledFuture[] array;
             int cursor = 0;     // index of next element to return
             int lastRet = -1;   // index of last element, or -1 if no such
 
-            Itr(ScheduledFutureTask[] array) {
+            Itr(RunnableScheduledFuture[] array) {
                 this.array = array;
             }
 
diff --git a/concurrent/src/main/java/java/util/concurrent/Semaphore.java b/concurrent/src/main/java/java/util/concurrent/Semaphore.java
index 1052364..1f5c00e 100644
--- a/concurrent/src/main/java/java/util/concurrent/Semaphore.java
+++ b/concurrent/src/main/java/java/util/concurrent/Semaphore.java
@@ -212,10 +212,8 @@
         }
 
         protected int tryAcquireShared(int acquires) {
-            Thread current = Thread.currentThread();
             for (;;) {
-                Thread first = getFirstQueuedThread();
-                if (first != null && first != current)
+                if (hasQueuedPredecessors())
                     return -1;
                 int available = getState();
                 int remaining = available - acquires;
diff --git a/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java b/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
index 0d297ff..5f9e8d7 100644
--- a/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
+++ b/concurrent/src/main/java/java/util/concurrent/SynchronousQueue.java
@@ -419,9 +419,9 @@
                 else if (s.waiter == null)
                     s.waiter = w; // establish waiter so can park next iter
                 else if (!timed)
-                    LockSupport.park();
+                    LockSupport.park(this);
                 else if (nanos > spinForTimeoutThreshold)
-                    LockSupport.parkNanos(nanos);
+                    LockSupport.parkNanos(this, nanos);
             }
         }
 
@@ -711,9 +711,9 @@
                 else if (s.waiter == null)
                     s.waiter = w;
                 else if (!timed)
-                    LockSupport.park();
+                    LockSupport.park(this);
                 else if (nanos > spinForTimeoutThreshold)
-                    LockSupport.parkNanos(nanos);
+                    LockSupport.parkNanos(this, nanos);
             }
         }
 
@@ -991,19 +991,6 @@
         return null;
     }
 
-
-    static class EmptyIterator<E> implements Iterator<E> {
-        public boolean hasNext() {
-            return false;
-        }
-        public E next() {
-            throw new NoSuchElementException();
-        }
-        public void remove() {
-            throw new IllegalStateException();
-        }
-    }
-
     /**
      * Returns an empty iterator in which <tt>hasNext</tt> always returns
      * <tt>false</tt>.
@@ -1011,7 +998,7 @@
      * @return an empty iterator
      */
     public Iterator<E> iterator() {
-        return new EmptyIterator<E>();
+        return Collections.<E>emptySet().iterator(); // android-changed
     }
 
     /**
diff --git a/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java b/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
index d0c934d..c362c99 100644
--- a/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
+++ b/concurrent/src/main/java/java/util/concurrent/ThreadPoolExecutor.java
@@ -92,9 +92,12 @@
  * threads will be constructed. This parameter can also be changed
  * dynamically using method {@link #setKeepAliveTime}. Using a value
  * of {@code Long.MAX_VALUE} {@link TimeUnit#NANOSECONDS} effectively
- * disables idle threads from ever terminating prior to shut down. The
- * keep-alive policy applies only when there are more than
- * corePoolSizeThreads.</dd>
+ * disables idle threads from ever terminating prior to shut down. By
+ * default, the keep-alive policy applies only when there are more
+ * than corePoolSizeThreads. But method {@link
+ * #allowCoreThreadTimeOut(boolean)} can be used to apply this
+ * time-out policy to core threads as well, so long as the
+ * keepAliveTime value is non-zero. </dd>
  *
  * <dt>Queuing</dt>
  *
@@ -228,7 +231,8 @@
  * you would like to ensure that unreferenced pools are reclaimed even
  * if users forget to call {@link #shutdown}, then you must arrange
  * that unused threads eventually die, by setting appropriate
- * keep-alive times using a lower bound of zero core threads.  </dd>
+ * keep-alive times, using a lower bound of zero core threads and/or
+ * setting {@link #allowCoreThreadTimeOut(boolean)}.  </dd>
  *
  * </dl>
  *
@@ -473,13 +477,22 @@
     /**
      * Timeout in nanoseconds for idle threads waiting for work.
      * Threads use this timeout when there are more than corePoolSize
-     * present. Otherwise they wait forever for new work.
+     * present or if allowCoreThreadTimeOut. Otherwise they wait
+     * forever for new work.
      */
     private volatile long keepAliveTime;
 
     /**
+     * If false (default), core threads stay alive even when idle.
+     * If true, core threads use keepAliveTime to time out waiting
+     * for work.
+     */
+    private volatile boolean allowCoreThreadTimeOut;
+
+    /**
      * Core pool size is the minimum number of workers to keep alive
-     * (and not allow to time out etc).
+     * (and not allow to time out etc) unless allowCoreThreadTimeOut
+     * is set, in which case the minimum is zero.
      */
     private volatile int corePoolSize;
 
@@ -941,7 +954,7 @@
         int c = ctl.get();
         if (runStateLessThan(c, STOP)) {
             if (!completedAbruptly) {
-                int min = corePoolSize;
+                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                 if (min == 0 && ! workQueue.isEmpty())
                     min = 1;
                 if (workerCountOf(c) >= min)
@@ -961,7 +974,7 @@
      * 3. The pool is shutdown and the queue is empty.
      * 4. This worker timed out waiting for a task, and timed-out
      *    workers are subject to termination (that is,
-     *    {@code workerCount > corePoolSize})
+     *    {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
      *    both before and after the timed wait.
      *
      * @return task, or null if the worker must exit, in which case
@@ -985,7 +998,7 @@
 
             for (;;) {
                 int wc = workerCountOf(c);
-                timed = wc > corePoolSize;
+                timed = allowCoreThreadTimeOut || wc > corePoolSize;
 
                 if (wc <= maximumPoolSize && ! (timedOut && timed))
                     break;
@@ -1096,7 +1109,7 @@
      * methods instead of this general purpose constructor.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param maximumPoolSize the maximum number of threads to allow in the
      *        pool
      * @param keepAliveTime when the number of threads is greater than
@@ -1127,7 +1140,7 @@
      * parameters and default rejected execution handler.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param maximumPoolSize the maximum number of threads to allow in the
      *        pool
      * @param keepAliveTime when the number of threads is greater than
@@ -1162,7 +1175,7 @@
      * parameters and default thread factory.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param maximumPoolSize the maximum number of threads to allow in the
      *        pool
      * @param keepAliveTime when the number of threads is greater than
@@ -1197,7 +1210,7 @@
      * parameters.
      *
      * @param corePoolSize the number of threads to keep in the pool, even
-     *        if they are idle
+     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
      * @param maximumPoolSize the maximum number of threads to allow in the
      *        pool
      * @param keepAliveTime when the number of threads is greater than
@@ -1518,6 +1531,50 @@
     }
 
     /**
+     * Returns true if this pool allows core threads to time out and
+     * terminate if no tasks arrive within the keepAlive time, being
+     * replaced if needed when new tasks arrive. When true, the same
+     * keep-alive policy applying to non-core threads applies also to
+     * core threads. When false (the default), core threads are never
+     * terminated due to lack of incoming tasks.
+     *
+     * @return {@code true} if core threads are allowed to time out,
+     *         else {@code false}
+     *
+     * @since 1.6
+     */
+    public boolean allowsCoreThreadTimeOut() {
+        return allowCoreThreadTimeOut;
+    }
+
+    /**
+     * Sets the policy governing whether core threads may time out and
+     * terminate if no tasks arrive within the keep-alive time, being
+     * replaced if needed when new tasks arrive. When false, core
+     * threads are never terminated due to lack of incoming
+     * tasks. When true, the same keep-alive policy applying to
+     * non-core threads applies also to core threads. To avoid
+     * continual thread replacement, the keep-alive time must be
+     * greater than zero when setting {@code true}. This method
+     * should in general be called before the pool is actively used.
+     *
+     * @param value {@code true} if should time out, else {@code false}
+     * @throws IllegalArgumentException if value is {@code true}
+     *         and the current keep-alive time is not greater than zero
+     *
+     * @since 1.6
+     */
+    public void allowCoreThreadTimeOut(boolean value) {
+        if (value && keepAliveTime <= 0)
+            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
+        if (value != allowCoreThreadTimeOut) {
+            allowCoreThreadTimeOut = value;
+            if (value)
+                interruptIdleWorkers();
+        }
+    }
+
+    /**
      * Sets the maximum allowed number of threads. This overrides any
      * value set in the constructor. If the new value is smaller than
      * the current value, excess existing threads will be
@@ -1564,6 +1621,8 @@
     public void setKeepAliveTime(long time, TimeUnit unit) {
         if (time < 0)
             throw new IllegalArgumentException();
+        if (time == 0 && allowsCoreThreadTimeOut())
+            throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
         long keepAliveTime = unit.toNanos(time);
         long delta = keepAliveTime - this.keepAliveTime;
         this.keepAliveTime = keepAliveTime;
diff --git a/concurrent/src/main/java/java/util/concurrent/TimeUnit.java b/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
index 412d28a..ae78fda 100644
--- a/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
+++ b/concurrent/src/main/java/java/util/concurrent/TimeUnit.java
@@ -40,7 +40,6 @@
  * @author Doug Lea
  */
 public enum TimeUnit {
-    /** TimeUnit which represents one nanosecond. */
     NANOSECONDS {
         public long toNanos(long d)   { return d; }
         public long toMicros(long d)  { return d/(C1/C0); }
@@ -52,7 +51,6 @@
         public long convert(long d, TimeUnit u) { return u.toNanos(d); }
         int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
     },
-    /** TimeUnit which represents one microsecond. */
     MICROSECONDS {
         public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
         public long toMicros(long d)  { return d; }
@@ -64,7 +62,6 @@
         public long convert(long d, TimeUnit u) { return u.toMicros(d); }
         int excessNanos(long d, long m) { return (int)((d*C1) - (m*C2)); }
     },
-    /** TimeUnit which represents one millisecond. */
     MILLISECONDS {
         public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
         public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
@@ -76,7 +73,6 @@
         public long convert(long d, TimeUnit u) { return u.toMillis(d); }
         int excessNanos(long d, long m) { return 0; }
     },
-    /** TimeUnit which represents one second. */
     SECONDS {
         public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
         public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
@@ -87,6 +83,39 @@
         public long toDays(long d)    { return d/(C6/C3); }
         public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
         int excessNanos(long d, long m) { return 0; }
+    },
+    MINUTES {
+        public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }
+        public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }
+        public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }
+        public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
+        public long toMinutes(long d) { return d; }
+        public long toHours(long d)   { return d/(C5/C4); }
+        public long toDays(long d)    { return d/(C6/C4); }
+        public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
+        int excessNanos(long d, long m) { return 0; }
+    },
+    HOURS {
+        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
+        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
+        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
+        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
+        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
+        public long toHours(long d)   { return d; }
+        public long toDays(long d)    { return d/(C6/C5); }
+        public long convert(long d, TimeUnit u) { return u.toHours(d); }
+        int excessNanos(long d, long m) { return 0; }
+    },
+    DAYS {
+        public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }
+        public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }
+        public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }
+        public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
+        public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
+        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
+        public long toDays(long d)    { return d; }
+        public long convert(long d, TimeUnit u) { return u.toDays(d); }
+        int excessNanos(long d, long m) { return 0; }
     };
 
     // Handy constants for conversion methods
@@ -193,8 +222,9 @@
      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
      * @see #convert
+     * @since 1.6
      */
-    long toMinutes(long duration) {
+    public long toMinutes(long duration) {
         throw new AbstractMethodError();
     }
 
@@ -205,8 +235,9 @@
      * or <tt>Long.MIN_VALUE</tt> if conversion would negatively
      * overflow, or <tt>Long.MAX_VALUE</tt> if it would positively overflow.
      * @see #convert
+     * @since 1.6
      */
-    long toHours(long duration) {
+    public long toHours(long duration) {
         throw new AbstractMethodError();
     }
 
@@ -215,8 +246,9 @@
      * @param duration the duration
      * @return the converted duration
      * @see #convert
+     * @since 1.6
      */
-    long toDays(long duration) {
+    public long toDays(long duration) {
         throw new AbstractMethodError();
     }
 
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
index ba60556..c774d21 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicBoolean.java
@@ -21,10 +21,7 @@
 public class AtomicBoolean implements java.io.Serializable {
     private static final long serialVersionUID = 4654671469794556979L;
     // setup to use Unsafe.compareAndSwapInt for updates
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
-
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final long valueOffset;
 
     static {
@@ -103,6 +100,17 @@
     }
 
     /**
+     * Eventually sets to the given value.
+     *
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(boolean newValue) {
+        int v = newValue ? 1 : 0;
+        unsafe.putOrderedInt(this, valueOffset, v);
+    }
+
+    /**
      * Atomically sets to the given value and returns the previous value.
      *
      * @param newValue the new value
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
index 1aa32f4..16dd568 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicInteger.java
@@ -24,9 +24,7 @@
     private static final long serialVersionUID = 6214790243416807050L;
 
     // setup to use Unsafe.compareAndSwapInt for updates
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final long valueOffset;
 
     static {
@@ -72,6 +70,16 @@
     }
 
     /**
+     * Eventually sets to the given value.
+     *
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(int newValue) {
+        unsafe.putOrderedInt(this, valueOffset, newValue);
+    }
+
+    /**
      * Atomically sets to the given value and returns the old value.
      *
      * @param newValue the new value
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
index 312c76d..b6d6cc5 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerArray.java
@@ -19,33 +19,30 @@
 public class AtomicIntegerArray implements java.io.Serializable {
     private static final long serialVersionUID = 2862133569453604235L;
 
-   // setup to use Unsafe.compareAndSwapInt for updates
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final int base = unsafe.arrayBaseOffset(int[].class);
     private static final int scale = unsafe.arrayIndexScale(int[].class);
     private final int[] array;
 
-    private long rawIndex(int i) {
+    private long checkedByteOffset(int i) {
         if (i < 0 || i >= array.length)
             throw new IndexOutOfBoundsException("index " + i);
-        // BEGIN android-changed
-        // avoid memory corruption
+
+        return byteOffset(i);
+    }
+
+    private static long byteOffset(int i) {
         return base + (long) i * scale;
-        // END android-changed
     }
 
     /**
-     * Creates a new AtomicIntegerArray of given length.
+     * Creates a new AtomicIntegerArray of the given length, with all
+     * elements initially zero.
      *
      * @param length the length of the array
      */
     public AtomicIntegerArray(int length) {
         array = new int[length];
-        // must perform at least one volatile write to conform to JMM
-        if (length > 0)
-            unsafe.putIntVolatile(array, rawIndex(0), 0);
     }
 
     /**
@@ -56,17 +53,8 @@
      * @throws NullPointerException if array is null
      */
     public AtomicIntegerArray(int[] array) {
-        if (array == null)
-            throw new NullPointerException();
-        int length = array.length;
-        this.array = new int[length];
-        if (length > 0) {
-            int last = length-1;
-            for (int i = 0; i < last; ++i)
-                this.array[i] = array[i];
-            // Do the last write as volatile
-            unsafe.putIntVolatile(this.array, rawIndex(last), array[last]);
-        }
+        // Visibility guaranteed by final field guarantees
+        this.array = array.clone();
     }
 
     /**
@@ -85,7 +73,11 @@
      * @return the current value
      */
     public final int get(int i) {
-        return unsafe.getIntVolatile(array, rawIndex(i));
+        return getRaw(checkedByteOffset(i));
+    }
+
+    private int getRaw(long offset) {
+        return unsafe.getIntVolatile(array, offset);
     }
 
     /**
@@ -95,7 +87,18 @@
      * @param newValue the new value
      */
     public final void set(int i, int newValue) {
-        unsafe.putIntVolatile(array, rawIndex(i), newValue);
+        unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
+    }
+
+    /**
+     * Eventually sets the element at position {@code i} to the given value.
+     *
+     * @param i the index
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(int i, int newValue) {
+        unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -107,9 +110,10 @@
      * @return the previous value
      */
     public final int getAndSet(int i, int newValue) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            int current = get(i);
-            if (compareAndSet(i, current, newValue))
+            int current = getRaw(offset);
+            if (compareAndSetRaw(offset, current, newValue))
                 return current;
         }
     }
@@ -125,8 +129,11 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, int expect, int update) {
-        return unsafe.compareAndSwapInt(array, rawIndex(i),
-                                        expect, update);
+        return compareAndSetRaw(checkedByteOffset(i), expect, update);
+    }
+
+    private boolean compareAndSetRaw(long offset, int expect, int update) {
+        return unsafe.compareAndSwapInt(array, offset, expect, update);
     }
 
     /**
@@ -153,12 +160,7 @@
      * @return the previous value
      */
     public final int getAndIncrement(int i) {
-        while (true) {
-            int current = get(i);
-            int next = current + 1;
-            if (compareAndSet(i, current, next))
-                return current;
-        }
+        return getAndAdd(i, 1);
     }
 
     /**
@@ -168,12 +170,7 @@
      * @return the previous value
      */
     public final int getAndDecrement(int i) {
-        while (true) {
-            int current = get(i);
-            int next = current - 1;
-            if (compareAndSet(i, current, next))
-                return current;
-        }
+        return getAndAdd(i, -1);
     }
 
     /**
@@ -184,10 +181,10 @@
      * @return the previous value
      */
     public final int getAndAdd(int i, int delta) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            int current = get(i);
-            int next = current + delta;
-            if (compareAndSet(i, current, next))
+            int current = getRaw(offset);
+            if (compareAndSetRaw(offset, current, current + delta))
                 return current;
         }
     }
@@ -199,12 +196,7 @@
      * @return the updated value
      */
     public final int incrementAndGet(int i) {
-        while (true) {
-            int current = get(i);
-            int next = current + 1;
-            if (compareAndSet(i, current, next))
-                return next;
-        }
+        return addAndGet(i, 1);
     }
 
     /**
@@ -214,12 +206,7 @@
      * @return the updated value
      */
     public final int decrementAndGet(int i) {
-        while (true) {
-            int current = get(i);
-            int next = current - 1;
-            if (compareAndSet(i, current, next))
-                return next;
-        }
+        return addAndGet(i, -1);
     }
 
     /**
@@ -230,22 +217,32 @@
      * @return the updated value
      */
     public final int addAndGet(int i, int delta) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            int current = get(i);
+            int current = getRaw(offset);
             int next = current + delta;
-            if (compareAndSet(i, current, next))
+            if (compareAndSetRaw(offset, current, next))
                 return next;
         }
     }
 
     /**
      * Returns the String representation of the current values of array.
-     * @return the String representation of the current values of array.
+     * @return the String representation of the current values of array
      */
     public String toString() {
-        if (array.length > 0) // force volatile read
-            get(0);
-        return Arrays.toString(array);
+        int iMax = array.length - 1;
+        if (iMax == -1)
+            return "[]";
+
+        StringBuilder b = new StringBuilder();
+        b.append('[');
+        for (int i = 0; ; i++) {
+            b.append(getRaw(byteOffset(i)));
+            if (i == iMax)
+                return b.append(']').toString();
+            b.append(", ");
+        }
     }
 
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index f8d2c81..476bb0a 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -5,12 +5,10 @@
  */
 
 package java.util.concurrent.atomic;
+import dalvik.system.VMStack;
 import sun.misc.Unsafe;
 import java.lang.reflect.*;
 
-import org.apache.harmony.kernel.vm.VM;
-import dalvik.system.VMStack;
-
 /**
  * A reflection-based utility that enables atomic updates to
  * designated {@code volatile int} fields of designated classes.
@@ -100,6 +98,17 @@
     public abstract void set(T obj, int newValue);
 
     /**
+     * Eventually sets the field of the given object managed by this
+     * updater to the given updated value.
+     *
+     * @param obj An object whose field to set
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public abstract void lazySet(T obj, int newValue);
+
+
+    /**
      * Gets the current value held in the field of the given object managed
      * by this updater.
      *
@@ -226,9 +235,7 @@
      * Standard hotspot implementation using intrinsics
      */
     private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
-        // BEGIN android-changed
-        private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-        // END android-changed
+        private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
         private final long offset;
         private final Class<T> tclass;
         private final Class cclass;
@@ -244,6 +251,7 @@
                 // END android-changed
                 modifiers = field.getModifiers();
 
+                // BEGIN android-added
                 SecurityManager smgr = System.getSecurityManager();
                 if (smgr != null) {
                     int type = Modifier.isPublic(modifiers)
@@ -251,6 +259,13 @@
                     smgr.checkMemberAccess(tclass, type);
                     smgr.checkPackageAccess(tclass.getPackage().getName());
                 }
+                // END android-added
+                // BEGIN android-removed
+                // modifiers = field.getModifiers();
+                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                //     caller, tclass, null, modifiers);
+                // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                // END android-removed
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -290,6 +305,11 @@
             unsafe.putIntVolatile(obj, offset, newValue);
         }
 
+        public void lazySet(T obj, int newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            unsafe.putOrderedInt(obj, offset, newValue);
+        }
+
         public final int get(T obj) {
             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.getIntVolatile(obj, offset);
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
index 9b56002..e1f5dc7 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLong.java
@@ -24,9 +24,7 @@
     private static final long serialVersionUID = 1927816293512124184L;
 
     // setup to use Unsafe.compareAndSwapLong for updates
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final long valueOffset;
 
     /**
@@ -97,6 +95,16 @@
     }
 
     /**
+     * Eventually sets to the given value.
+     *
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(long newValue) {
+        unsafe.putOrderedLong(this, valueOffset, newValue);
+    }
+
+    /**
      * Atomically sets to the given value and returns the old value.
      *
      * @param newValue the new value
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
index 187acbc..33e6914 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongArray.java
@@ -18,33 +18,30 @@
 public class AtomicLongArray implements java.io.Serializable {
     private static final long serialVersionUID = -2308431214976778248L;
 
-    // setup to use Unsafe.compareAndSwapInt for updates
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final int base = unsafe.arrayBaseOffset(long[].class);
     private static final int scale = unsafe.arrayIndexScale(long[].class);
     private final long[] array;
 
-    private long rawIndex(int i) {
+    private long checkedByteOffset(int i) {
         if (i < 0 || i >= array.length)
             throw new IndexOutOfBoundsException("index " + i);
-        // BEGIN android-changed
-        // avoid memory corruption
+
+        return byteOffset(i);
+    }
+
+    private static long byteOffset(int i) {
         return base + (long) i * scale;
-        // END android-changed
     }
 
     /**
-     * Creates a new AtomicLongArray of given length.
+     * Creates a new AtomicLongArray of the given length, with all
+     * elements initially zero.
      *
      * @param length the length of the array
      */
     public AtomicLongArray(int length) {
         array = new long[length];
-        // must perform at least one volatile write to conform to JMM
-        if (length > 0)
-            unsafe.putLongVolatile(array, rawIndex(0), 0);
     }
 
     /**
@@ -55,17 +52,8 @@
      * @throws NullPointerException if array is null
      */
     public AtomicLongArray(long[] array) {
-        if (array == null)
-            throw new NullPointerException();
-        int length = array.length;
-        this.array = new long[length];
-        if (length > 0) {
-            int last = length-1;
-            for (int i = 0; i < last; ++i)
-                this.array[i] = array[i];
-            // Do the last write as volatile
-            unsafe.putLongVolatile(this.array, rawIndex(last), array[last]);
-        }
+        // Visibility guaranteed by final field guarantees
+        this.array = array.clone();
     }
 
     /**
@@ -84,7 +72,11 @@
      * @return the current value
      */
     public final long get(int i) {
-        return unsafe.getLongVolatile(array, rawIndex(i));
+        return getRaw(checkedByteOffset(i));
+    }
+
+    private long getRaw(long offset) {
+        return unsafe.getLongVolatile(array, offset);
     }
 
     /**
@@ -94,10 +86,22 @@
      * @param newValue the new value
      */
     public final void set(int i, long newValue) {
-        unsafe.putLongVolatile(array, rawIndex(i), newValue);
+        unsafe.putLongVolatile(array, checkedByteOffset(i), newValue);
     }
 
     /**
+     * Eventually sets the element at position {@code i} to the given value.
+     *
+     * @param i the index
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(int i, long newValue) {
+        unsafe.putOrderedLong(array, checkedByteOffset(i), newValue);
+    }
+
+
+    /**
      * Atomically sets the element at position {@code i} to the given value
      * and returns the old value.
      *
@@ -106,16 +110,17 @@
      * @return the previous value
      */
     public final long getAndSet(int i, long newValue) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            long current = get(i);
-            if (compareAndSet(i, current, newValue))
+            long current = getRaw(offset);
+            if (compareAndSetRaw(offset, current, newValue))
                 return current;
         }
     }
 
     /**
-     * Atomically sets the value to the given updated value
-     * if the current value {@code ==} the expected value.
+     * Atomically sets the element at position {@code i} to the given
+     * updated value if the current value {@code ==} the expected value.
      *
      * @param i the index
      * @param expect the expected value
@@ -124,13 +129,16 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, long expect, long update) {
-        return unsafe.compareAndSwapLong(array, rawIndex(i),
-                                         expect, update);
+        return compareAndSetRaw(checkedByteOffset(i), expect, update);
+    }
+
+    private boolean compareAndSetRaw(long offset, long expect, long update) {
+        return unsafe.compareAndSwapLong(array, offset, expect, update);
     }
 
     /**
-     * Atomically sets the value to the given updated value
-     * if the current value {@code ==} the expected value.
+     * Atomically sets the element at position {@code i} to the given
+     * updated value if the current value {@code ==} the expected value.
      *
      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
      * and does not provide ordering guarantees, so is only rarely an
@@ -152,12 +160,7 @@
      * @return the previous value
      */
     public final long getAndIncrement(int i) {
-        while (true) {
-            long current = get(i);
-            long next = current + 1;
-            if (compareAndSet(i, current, next))
-                return current;
-        }
+        return getAndAdd(i, 1);
     }
 
     /**
@@ -167,12 +170,7 @@
      * @return the previous value
      */
     public final long getAndDecrement(int i) {
-        while (true) {
-            long current = get(i);
-            long next = current - 1;
-            if (compareAndSet(i, current, next))
-                return current;
-        }
+        return getAndAdd(i, -1);
     }
 
     /**
@@ -183,10 +181,10 @@
      * @return the previous value
      */
     public final long getAndAdd(int i, long delta) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            long current = get(i);
-            long next = current + delta;
-            if (compareAndSet(i, current, next))
+            long current = getRaw(offset);
+            if (compareAndSetRaw(offset, current, current + delta))
                 return current;
         }
     }
@@ -198,12 +196,7 @@
      * @return the updated value
      */
     public final long incrementAndGet(int i) {
-        while (true) {
-            long current = get(i);
-            long next = current + 1;
-            if (compareAndSet(i, current, next))
-                return next;
-        }
+        return addAndGet(i, 1);
     }
 
     /**
@@ -213,12 +206,7 @@
      * @return the updated value
      */
     public final long decrementAndGet(int i) {
-        while (true) {
-            long current = get(i);
-            long next = current - 1;
-            if (compareAndSet(i, current, next))
-                return next;
-        }
+        return addAndGet(i, -1);
     }
 
     /**
@@ -229,22 +217,32 @@
      * @return the updated value
      */
     public long addAndGet(int i, long delta) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            long current = get(i);
+            long current = getRaw(offset);
             long next = current + delta;
-            if (compareAndSet(i, current, next))
+            if (compareAndSetRaw(offset, current, next))
                 return next;
         }
     }
 
     /**
      * Returns the String representation of the current values of array.
-     * @return the String representation of the current values of array.
+     * @return the String representation of the current values of array
      */
     public String toString() {
-        if (array.length > 0) // force volatile read
-            get(0);
-        return Arrays.toString(array);
+        int iMax = array.length - 1;
+        if (iMax == -1)
+            return "[]";
+
+        StringBuilder b = new StringBuilder();
+        b.append('[');
+        for (int i = 0; ; i++) {
+            b.append(getRaw(byteOffset(i)));
+            if (i == iMax)
+                return b.append(']').toString();
+            b.append(", ");
+        }
     }
 
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index d97c2e4..427a9e1 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -5,12 +5,10 @@
  */
 
 package java.util.concurrent.atomic;
+import dalvik.system.VMStack;
 import sun.misc.Unsafe;
 import java.lang.reflect.*;
 
-import org.apache.harmony.kernel.vm.VM;
-import dalvik.system.VMStack;
-
 /**
  * A reflection-based utility that enables atomic updates to
  * designated {@code volatile long} fields of designated classes.
@@ -103,6 +101,16 @@
     public abstract void set(T obj, long newValue);
 
     /**
+     * Eventually sets the field of the given object managed by this
+     * updater to the given updated value.
+     *
+     * @param obj An object whose field to set
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public abstract void lazySet(T obj, long newValue);
+
+    /**
      * Gets the current value held in the field of the given object managed
      * by this updater.
      *
@@ -226,9 +234,7 @@
     }
 
     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
-        // BEGIN android-changed
-        private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-        // END android-changed
+        private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
         private final long offset;
         private final Class<T> tclass;
         private final Class cclass;
@@ -239,10 +245,9 @@
             int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
-                // BEGIN android-changed
-                caller = VMStack.getStackClass2();
-                // END android-changed
+                caller = VMStack.getStackClass2(); // android-changed
                 modifiers = field.getModifiers();
+                // BEGIN android-added
                 SecurityManager smgr = System.getSecurityManager();
                 if (smgr != null) {
                     int type = Modifier.isPublic(modifiers)
@@ -250,6 +255,12 @@
                     smgr.checkMemberAccess(tclass, type);
                     smgr.checkPackageAccess(tclass.getPackage().getName());
                 }
+                // END android-added
+                // BEGIN android-removed
+                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                //     caller, tclass, null, modifiers);
+                // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                // END android-removed
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
@@ -289,6 +300,11 @@
             unsafe.putLongVolatile(obj, offset, newValue);
         }
 
+        public void lazySet(T obj, long newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            unsafe.putOrderedLong(obj, offset, newValue);
+        }
+
         public long get(T obj) {
             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
             return unsafe.getLongVolatile(obj, offset);
@@ -312,9 +328,7 @@
 
 
     private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
-        // BEGIN android-changed
-        private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-        // END android-changed
+        private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
         private final long offset;
         private final Class<T> tclass;
         private final Class cclass;
@@ -325,10 +339,9 @@
             int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
-                // BEGIN android-changed
-                caller = VMStack.getStackClass2();
-                // END android-changed
+                caller = VMStack.getStackClass2(); // android-changed
                 modifiers = field.getModifiers();
+                // BEGIN android-added
                 SecurityManager smgr = System.getSecurityManager();
                 if (smgr != null) {
                     int type = Modifier.isPublic(modifiers)
@@ -336,6 +349,12 @@
                     smgr.checkMemberAccess(tclass, type);
                     smgr.checkPackageAccess(tclass.getPackage().getName());
                 }
+                // END android-added
+                // BEGIN android-removed
+                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                //     caller, tclass, null, modifiers);
+                // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                // END android-removed
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
             }
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
index 1de9b1c..f041bbd 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReference.java
@@ -18,9 +18,7 @@
 public class AtomicReference<V>  implements java.io.Serializable {
     private static final long serialVersionUID = -1848883965231344442L;
 
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final long valueOffset;
 
     static {
@@ -66,6 +64,16 @@
     }
 
     /**
+     * Eventually sets to the given value.
+     *
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(V newValue) {
+        unsafe.putOrderedObject(this, valueOffset, newValue);
+    }
+
+    /**
      * Atomically sets the value to the given updated value
      * if the current value {@code ==} the expected value.
      * @param expect the expected value
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
index fff6a1e..2501c2b 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceArray.java
@@ -20,31 +20,30 @@
 public class AtomicReferenceArray<E> implements java.io.Serializable {
     private static final long serialVersionUID = -6209656149925076980L;
 
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
     private static final int base = unsafe.arrayBaseOffset(Object[].class);
     private static final int scale = unsafe.arrayIndexScale(Object[].class);
     private final Object[] array;
 
-    private long rawIndex(int i) {
+    private long checkedByteOffset(int i) {
         if (i < 0 || i >= array.length)
             throw new IndexOutOfBoundsException("index " + i);
-        // BEGIN android-changed
-        // avoid memory corruption
+
+        return byteOffset(i);
+    }
+
+    private static long byteOffset(int i) {
         return base + (long) i * scale;
-        // END android-changed
     }
 
     /**
-     * Creates a new AtomicReferenceArray of given length.
+     * Creates a new AtomicReferenceArray of the given length, with all
+     * elements initially zero.
+     *
      * @param length the length of the array
      */
     public AtomicReferenceArray(int length) {
         array = new Object[length];
-        // must perform at least one volatile write to conform to JMM
-        if (length > 0)
-            unsafe.putObjectVolatile(array, rawIndex(0), null);
     }
 
     /**
@@ -55,18 +54,8 @@
      * @throws NullPointerException if array is null
      */
     public AtomicReferenceArray(E[] array) {
-        if (array == null)
-            throw new NullPointerException();
-        int length = array.length;
-        this.array = new Object[length];
-        if (length > 0) {
-            int last = length-1;
-            for (int i = 0; i < last; ++i)
-                this.array[i] = array[i];
-            // Do the last write as volatile
-            E e = array[last];
-            unsafe.putObjectVolatile(this.array, rawIndex(last), e);
-        }
+        // Visibility guaranteed by final field guarantees
+        this.array = array.clone();
     }
 
     /**
@@ -85,7 +74,11 @@
      * @return the current value
      */
     public final E get(int i) {
-        return (E) unsafe.getObjectVolatile(array, rawIndex(i));
+        return getRaw(checkedByteOffset(i));
+    }
+
+    private E getRaw(long offset) {
+        return (E) unsafe.getObjectVolatile(array, offset);
     }
 
     /**
@@ -95,10 +88,22 @@
      * @param newValue the new value
      */
     public final void set(int i, E newValue) {
-        unsafe.putObjectVolatile(array, rawIndex(i), newValue);
+        unsafe.putObjectVolatile(array, checkedByteOffset(i), newValue);
     }
 
     /**
+     * Eventually sets the element at position {@code i} to the given value.
+     *
+     * @param i the index
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public final void lazySet(int i, E newValue) {
+        unsafe.putOrderedObject(array, checkedByteOffset(i), newValue);
+    }
+
+
+    /**
      * Atomically sets the element at position {@code i} to the given
      * value and returns the old value.
      *
@@ -107,9 +112,10 @@
      * @return the previous value
      */
     public final E getAndSet(int i, E newValue) {
+        long offset = checkedByteOffset(i);
         while (true) {
-            E current = get(i);
-            if (compareAndSet(i, current, newValue))
+            E current = (E) getRaw(offset);
+            if (compareAndSetRaw(offset, current, newValue))
                 return current;
         }
     }
@@ -117,6 +123,7 @@
     /**
      * Atomically sets the element at position {@code i} to the given
      * updated value if the current value {@code ==} the expected value.
+     *
      * @param i the index
      * @param expect the expected value
      * @param update the new value
@@ -124,8 +131,11 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int i, E expect, E update) {
-        return unsafe.compareAndSwapObject(array, rawIndex(i),
-                                         expect, update);
+        return compareAndSetRaw(checkedByteOffset(i), expect, update);
+    }
+
+    private boolean compareAndSetRaw(long offset, E expect, E update) {
+        return unsafe.compareAndSwapObject(array, offset, expect, update);
     }
 
     /**
@@ -147,12 +157,21 @@
 
     /**
      * Returns the String representation of the current values of array.
-     * @return the String representation of the current values of array.
+     * @return the String representation of the current values of array
      */
     public String toString() {
-        if (array.length > 0) // force volatile read
-            get(0);
-        return Arrays.toString(array);
+           int iMax = array.length - 1;
+        if (iMax == -1)
+            return "[]";
+
+        StringBuilder b = new StringBuilder();
+        b.append('[');
+        for (int i = 0; ; i++) {
+            b.append(getRaw(byteOffset(i)));
+            if (i == iMax)
+                return b.append(']').toString();
+            b.append(", ");
+        }
     }
 
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
index fae134f..e53f2e9 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java
@@ -5,12 +5,10 @@
  */
 
 package java.util.concurrent.atomic;
+import dalvik.system.VMStack;
 import sun.misc.Unsafe;
 import java.lang.reflect.*;
 
-import org.apache.harmony.kernel.vm.VM;
-import dalvik.system.VMStack;
-
 /**
  * A reflection-based utility that enables atomic updates to
  * designated {@code volatile} reference fields of designated
@@ -118,6 +116,16 @@
     public abstract void set(T obj, V newValue);
 
     /**
+     * Eventually sets the field of the given object managed by this
+     * updater to the given updated value.
+     *
+     * @param obj An object whose field to set
+     * @param newValue the new value
+     * @since 1.6
+     */
+    public abstract void lazySet(T obj, V newValue);
+
+    /**
      * Gets the current value held in the field of the given object managed
      * by this updater.
      *
@@ -144,9 +152,7 @@
 
     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
         extends AtomicReferenceFieldUpdater<T,V> {
-        // BEGIN android-changed
-        private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-        // END android-changed
+        private static final Unsafe unsafe = Unsafe.getUnsafe();
         private final long offset;
         private final Class<T> tclass;
         private final Class<V> vclass;
@@ -173,10 +179,9 @@
             int modifiers = 0;
             try {
                 field = tclass.getDeclaredField(fieldName);
-                // BEGIN android-changed
-                caller = VMStack.getStackClass2();
-                // END android-changed
+                caller = VMStack.getStackClass2(); // android-changed
                 modifiers = field.getModifiers();
+                // BEGIN android-added
                 SecurityManager smgr = System.getSecurityManager();
                 if (smgr != null) {
                     int type = Modifier.isPublic(modifiers)
@@ -184,6 +189,12 @@
                     smgr.checkMemberAccess(tclass, type);
                     smgr.checkPackageAccess(tclass.getPackage().getName());
                 }
+                // END android-added
+                // BEGIN android-removed
+                // sun.reflect.misc.ReflectUtil.ensureMemberAccess(
+                //     caller, tclass, null, modifiers);
+                // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
+                // END android-removed
                 fieldClass = field.getType();
             } catch (Exception ex) {
                 throw new RuntimeException(ex);
@@ -245,6 +256,14 @@
             unsafe.putObjectVolatile(obj, offset, newValue);
         }
 
+        public void lazySet(T obj, V newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null ||
+                (newValue != null && vclass != null &&
+                 vclass != newValue.getClass()))
+                updateCheck(obj, newValue);
+            unsafe.putOrderedObject(obj, offset, newValue);
+        }
+
         public V get(T obj) {
             if (obj == null || obj.getClass() != tclass || cclass != null)
                 targetCheck(obj);
diff --git a/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java b/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java
index 2252e5c..4a4375d 100644
--- a/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java
+++ b/concurrent/src/main/java/java/util/concurrent/atomic/package-info.java
@@ -63,6 +63,14 @@
  *   <li> {@code set} has the memory effects of writing (assigning) a
  * {@code volatile} variable.
  *
+ *   <li> {@code lazySet} has the memory effects of writing (assigning)
+ *   a {@code volatile} variable except that it permits reorderings with
+ *   subsequent (but not previous) memory actions that do not themselves
+ *   impose reordering constraints with ordinary non-{@code volatile}
+ *   writes.  Among other usage contexts, {@code lazySet} may apply when
+ *   nulling out, for the sake of garbage collection, a reference that is
+ *   never accessed again.
+ *
  *   <li>{@code weakCompareAndSet} atomically reads and conditionally
  *   writes a variable but does <em>not</em>
  *   create any happens-before orderings, so provides no guarantees
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java b/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
index bf2fe16..f3780e5 100644
--- a/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
+++ b/concurrent/src/main/java/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
@@ -15,10 +15,11 @@
  * appropriately maintained values to help control and monitor access
  * and provide diagnostics.
  *
+ * @since 1.6
  * @author Doug Lea
  */
-abstract class AbstractOwnableSynchronizer
-        implements java.io.Serializable {
+public abstract class AbstractOwnableSynchronizer
+    implements java.io.Serializable {
 
     /** Use serial ID even though all fields transient. */
     private static final long serialVersionUID = 3737899427754241961L;
@@ -53,4 +54,4 @@
     protected final Thread getExclusiveOwnerThread() {
         return exclusiveOwnerThread;
     }
-}
\ No newline at end of file
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
new file mode 100644
index 0000000..d805259
--- /dev/null
+++ b/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
@@ -0,0 +1,2073 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import sun.misc.Unsafe;
+
+/**
+ * A version of {@link AbstractQueuedSynchronizer} in
+ * which synchronization state is maintained as a <tt>long</tt>.
+ * This class has exactly the same structure, properties, and methods
+ * as <tt>AbstractQueuedSynchronizer</tt> with the exception
+ * that all state-related parameters and results are defined
+ * as <tt>long</tt> rather than <tt>int</tt>. This class
+ * may be useful when creating synchronizers such as
+ * multilevel locks and barriers that require
+ * 64 bits of state.
+ *
+ * <p>See {@link AbstractQueuedSynchronizer} for usage
+ * notes and examples.
+ *
+ * @since 1.6
+ * @author Doug Lea
+ */
+public abstract class AbstractQueuedLongSynchronizer
+    extends AbstractOwnableSynchronizer
+    implements java.io.Serializable {
+
+    private static final long serialVersionUID = 7373984972572414692L;
+
+    /*
+      To keep sources in sync, the remainder of this source file is
+      exactly cloned from AbstractQueuedSynchronizer, replacing class
+      name and changing ints related with sync state to longs. Please
+      keep it that way.
+    */
+
+    /**
+     * Creates a new <tt>AbstractQueuedLongSynchronizer</tt> instance
+     * with initial synchronization state of zero.
+     */
+    protected AbstractQueuedLongSynchronizer() { }
+
+    /**
+     * Wait queue node class.
+     *
+     * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
+     * Hagersten) lock queue. CLH locks are normally used for
+     * spinlocks.  We instead use them for blocking synchronizers, but
+     * use the same basic tactic of holding some of the control
+     * information about a thread in the predecessor of its node.  A
+     * "status" field in each node keeps track of whether a thread
+     * should block.  A node is signalled when its predecessor
+     * releases.  Each node of the queue otherwise serves as a
+     * specific-notification-style monitor holding a single waiting
+     * thread. The status field does NOT control whether threads are
+     * granted locks etc though.  A thread may try to acquire if it is
+     * first in the queue. But being first does not guarantee success;
+     * it only gives the right to contend.  So the currently released
+     * contender thread may need to rewait.
+     *
+     * <p>To enqueue into a CLH lock, you atomically splice it in as new
+     * tail. To dequeue, you just set the head field.
+     * <pre>
+     *      +------+  prev +-----+       +-----+
+     * head |      | <---- |     | <---- |     |  tail
+     *      +------+       +-----+       +-----+
+     * </pre>
+     *
+     * <p>Insertion into a CLH queue requires only a single atomic
+     * operation on "tail", so there is a simple atomic point of
+     * demarcation from unqueued to queued. Similarly, dequeing
+     * involves only updating the "head". However, it takes a bit
+     * more work for nodes to determine who their successors are,
+     * in part to deal with possible cancellation due to timeouts
+     * and interrupts.
+     *
+     * <p>The "prev" links (not used in original CLH locks), are mainly
+     * needed to handle cancellation. If a node is cancelled, its
+     * successor is (normally) relinked to a non-cancelled
+     * predecessor. For explanation of similar mechanics in the case
+     * of spin locks, see the papers by Scott and Scherer at
+     * http://www.cs.rochester.edu/u/scott/synchronization/
+     *
+     * <p>We also use "next" links to implement blocking mechanics.
+     * The thread id for each node is kept in its own node, so a
+     * predecessor signals the next node to wake up by traversing
+     * next link to determine which thread it is.  Determination of
+     * successor must avoid races with newly queued nodes to set
+     * the "next" fields of their predecessors.  This is solved
+     * when necessary by checking backwards from the atomically
+     * updated "tail" when a node's successor appears to be null.
+     * (Or, said differently, the next-links are an optimization
+     * so that we don't usually need a backward scan.)
+     *
+     * <p>Cancellation introduces some conservatism to the basic
+     * algorithms.  Since we must poll for cancellation of other
+     * nodes, we can miss noticing whether a cancelled node is
+     * ahead or behind us. This is dealt with by always unparking
+     * successors upon cancellation, allowing them to stabilize on
+     * a new predecessor, unless we can identify an uncancelled
+     * predecessor who will carry this responsibility.
+     *
+     * <p>CLH queues need a dummy header node to get started. But
+     * we don't create them on construction, because it would be wasted
+     * effort if there is never contention. Instead, the node
+     * is constructed and head and tail pointers are set upon first
+     * contention.
+     *
+     * <p>Threads waiting on Conditions use the same nodes, but
+     * use an additional link. Conditions only need to link nodes
+     * in simple (non-concurrent) linked queues because they are
+     * only accessed when exclusively held.  Upon await, a node is
+     * inserted into a condition queue.  Upon signal, the node is
+     * transferred to the main queue.  A special value of status
+     * field is used to mark which queue a node is on.
+     *
+     * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
+     * Scherer and Michael Scott, along with members of JSR-166
+     * expert group, for helpful ideas, discussions, and critiques
+     * on the design of this class.
+     */
+    static final class Node {
+        /** Marker to indicate a node is waiting in shared mode */
+        static final Node SHARED = new Node();
+        /** Marker to indicate a node is waiting in exclusive mode */
+        static final Node EXCLUSIVE = null;
+
+        /** waitStatus value to indicate thread has cancelled */
+        static final int CANCELLED =  1;
+        /** waitStatus value to indicate successor's thread needs unparking */
+        static final int SIGNAL    = -1;
+        /** waitStatus value to indicate thread is waiting on condition */
+        static final int CONDITION = -2;
+        /**
+         * waitStatus value to indicate the next acquireShared should
+         * unconditionally propagate
+         */
+        static final int PROPAGATE = -3;
+
+        /**
+         * Status field, taking on only the values:
+         *   SIGNAL:     The successor of this node is (or will soon be)
+         *               blocked (via park), so the current node must
+         *               unpark its successor when it releases or
+         *               cancels. To avoid races, acquire methods must
+         *               first indicate they need a signal,
+         *               then retry the atomic acquire, and then,
+         *               on failure, block.
+         *   CANCELLED:  This node is cancelled due to timeout or interrupt.
+         *               Nodes never leave this state. In particular,
+         *               a thread with cancelled node never again blocks.
+         *   CONDITION:  This node is currently on a condition queue.
+         *               It will not be used as a sync queue node
+         *               until transferred, at which time the status
+         *               will be set to 0. (Use of this value here has
+         *               nothing to do with the other uses of the
+         *               field, but simplifies mechanics.)
+         *   PROPAGATE:  A releaseShared should be propagated to other
+         *               nodes. This is set (for head node only) in
+         *               doReleaseShared to ensure propagation
+         *               continues, even if other operations have
+         *               since intervened.
+         *   0:          None of the above
+         *
+         * The values are arranged numerically to simplify use.
+         * Non-negative values mean that a node doesn't need to
+         * signal. So, most code doesn't need to check for particular
+         * values, just for sign.
+         *
+         * The field is initialized to 0 for normal sync nodes, and
+         * CONDITION for condition nodes.  It is modified using CAS
+         * (or when possible, unconditional volatile writes).
+         */
+        volatile int waitStatus;
+
+        /**
+         * Link to predecessor node that current node/thread relies on
+         * for checking waitStatus. Assigned during enqueing, and nulled
+         * out (for sake of GC) only upon dequeuing.  Also, upon
+         * cancellation of a predecessor, we short-circuit while
+         * finding a non-cancelled one, which will always exist
+         * because the head node is never cancelled: A node becomes
+         * head only as a result of successful acquire. A
+         * cancelled thread never succeeds in acquiring, and a thread only
+         * cancels itself, not any other node.
+         */
+        volatile Node prev;
+
+        /**
+         * Link to the successor node that the current node/thread
+         * unparks upon release. Assigned during enqueuing, adjusted
+         * when bypassing cancelled predecessors, and nulled out (for
+         * sake of GC) when dequeued.  The enq operation does not
+         * assign next field of a predecessor until after attachment,
+         * so seeing a null next field does not necessarily mean that
+         * node is at end of queue. However, if a next field appears
+         * to be null, we can scan prev's from the tail to
+         * double-check.  The next field of cancelled nodes is set to
+         * point to the node itself instead of null, to make life
+         * easier for isOnSyncQueue.
+         */
+        volatile Node next;
+
+        /**
+         * The thread that enqueued this node.  Initialized on
+         * construction and nulled out after use.
+         */
+        volatile Thread thread;
+
+        /**
+         * Link to next node waiting on condition, or the special
+         * value SHARED.  Because condition queues are accessed only
+         * when holding in exclusive mode, we just need a simple
+         * linked queue to hold nodes while they are waiting on
+         * conditions. They are then transferred to the queue to
+         * re-acquire. And because conditions can only be exclusive,
+         * we save a field by using special value to indicate shared
+         * mode.
+         */
+        Node nextWaiter;
+
+        /**
+         * Returns true if node is waiting in shared mode
+         */
+        final boolean isShared() {
+            return nextWaiter == SHARED;
+        }
+
+        /**
+         * Returns previous node, or throws NullPointerException if null.
+         * Use when predecessor cannot be null.  The null check could
+         * be elided, but is present to help the VM.
+         *
+         * @return the predecessor of this node
+         */
+        final Node predecessor() throws NullPointerException {
+            Node p = prev;
+            if (p == null)
+                throw new NullPointerException();
+            else
+                return p;
+        }
+
+        Node() {    // Used to establish initial head or SHARED marker
+        }
+
+        Node(Thread thread, Node mode) {     // Used by addWaiter
+            this.nextWaiter = mode;
+            this.thread = thread;
+        }
+
+        Node(Thread thread, int waitStatus) { // Used by Condition
+            this.waitStatus = waitStatus;
+            this.thread = thread;
+        }
+    }
+
+    /**
+     * Head of the wait queue, lazily initialized.  Except for
+     * initialization, it is modified only via method setHead.  Note:
+     * If head exists, its waitStatus is guaranteed not to be
+     * CANCELLED.
+     */
+    private transient volatile Node head;
+
+    /**
+     * Tail of the wait queue, lazily initialized.  Modified only via
+     * method enq to add new wait node.
+     */
+    private transient volatile Node tail;
+
+    /**
+     * The synchronization state.
+     */
+    private volatile long state;
+
+    /**
+     * Returns the current value of synchronization state.
+     * This operation has memory semantics of a <tt>volatile</tt> read.
+     * @return current state value
+     */
+    protected final long getState() {
+        return state;
+    }
+
+    /**
+     * Sets the value of synchronization state.
+     * This operation has memory semantics of a <tt>volatile</tt> write.
+     * @param newState the new state value
+     */
+    protected final void setState(long newState) {
+        state = newState;
+    }
+
+    /**
+     * Atomically sets synchronization state to the given updated
+     * value if the current state value equals the expected value.
+     * This operation has memory semantics of a <tt>volatile</tt> read
+     * and write.
+     *
+     * @param expect the expected value
+     * @param update the new value
+     * @return true if successful. False return indicates that the actual
+     *         value was not equal to the expected value.
+     */
+    protected final boolean compareAndSetState(long expect, long update) {
+        // See below for intrinsics setup to support this
+        return unsafe.compareAndSwapLong(this, stateOffset, expect, update);
+    }
+
+    // Queuing utilities
+
+    /**
+     * The number of nanoseconds for which it is faster to spin
+     * rather than to use timed park. A rough estimate suffices
+     * to improve responsiveness with very short timeouts.
+     */
+    static final long spinForTimeoutThreshold = 1000L;
+
+    /**
+     * Inserts node into queue, initializing if necessary. See picture above.
+     * @param node the node to insert
+     * @return node's predecessor
+     */
+    private Node enq(final Node node) {
+        for (;;) {
+            Node t = tail;
+            if (t == null) { // Must initialize
+                if (compareAndSetHead(new Node()))
+                    tail = head;
+            } else {
+                node.prev = t;
+                if (compareAndSetTail(t, node)) {
+                    t.next = node;
+                    return t;
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates and enqueues node for current thread and given mode.
+     *
+     * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
+     * @return the new node
+     */
+    private Node addWaiter(Node mode) {
+        Node node = new Node(Thread.currentThread(), mode);
+        // Try the fast path of enq; backup to full enq on failure
+        Node pred = tail;
+        if (pred != null) {
+            node.prev = pred;
+            if (compareAndSetTail(pred, node)) {
+                pred.next = node;
+                return node;
+            }
+        }
+        enq(node);
+        return node;
+    }
+
+    /**
+     * Sets head of queue to be node, thus dequeuing. Called only by
+     * acquire methods.  Also nulls out unused fields for sake of GC
+     * and to suppress unnecessary signals and traversals.
+     *
+     * @param node the node
+     */
+    private void setHead(Node node) {
+        head = node;
+        node.thread = null;
+        node.prev = null;
+    }
+
+    /**
+     * Wakes up node's successor, if one exists.
+     *
+     * @param node the node
+     */
+    private void unparkSuccessor(Node node) {
+        /*
+         * If status is negative (i.e., possibly needing signal) try
+         * to clear in anticipation of signalling.  It is OK if this
+         * fails or if status is changed by waiting thread.
+         */
+        int ws = node.waitStatus;
+        if (ws < 0)
+            compareAndSetWaitStatus(node, ws, 0);
+
+        /*
+         * Thread to unpark is held in successor, which is normally
+         * just the next node.  But if cancelled or apparently null,
+         * traverse backwards from tail to find the actual
+         * non-cancelled successor.
+         */
+        Node s = node.next;
+        if (s == null || s.waitStatus > 0) {
+            s = null;
+            for (Node t = tail; t != null && t != node; t = t.prev)
+                if (t.waitStatus <= 0)
+                    s = t;
+        }
+        if (s != null)
+            LockSupport.unpark(s.thread);
+    }
+
+    /**
+     * Release action for shared mode -- signal successor and ensure
+     * propagation. (Note: For exclusive mode, release just amounts
+     * to calling unparkSuccessor of head if it needs signal.)
+     */
+    private void doReleaseShared() {
+        /*
+         * Ensure that a release propagates, even if there are other
+         * in-progress acquires/releases.  This proceeds in the usual
+         * way of trying to unparkSuccessor of head if it needs
+         * signal. But if it does not, status is set to PROPAGATE to
+         * ensure that upon release, propagation continues.
+         * Additionally, we must loop in case a new node is added
+         * while we are doing this. Also, unlike other uses of
+         * unparkSuccessor, we need to know if CAS to reset status
+         * fails, if so rechecking.
+         */
+        for (;;) {
+            Node h = head;
+            if (h != null && h != tail) {
+                int ws = h.waitStatus;
+                if (ws == Node.SIGNAL) {
+                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
+                        continue;            // loop to recheck cases
+                    unparkSuccessor(h);
+                }
+                else if (ws == 0 &&
+                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
+                    continue;                // loop on failed CAS
+            }
+            if (h == head)                   // loop if head changed
+                break;
+        }
+    }
+
+    /**
+     * Sets head of queue, and checks if successor may be waiting
+     * in shared mode, if so propagating if either propagate > 0 or
+     * PROPAGATE status was set.
+     *
+     * @param node the node
+     * @param propagate the return value from a tryAcquireShared
+     */
+    private void setHeadAndPropagate(Node node, long propagate) {
+        Node h = head; // Record old head for check below
+        setHead(node);
+        /*
+         * Try to signal next queued node if:
+         *   Propagation was indicated by caller,
+         *     or was recorded (as h.waitStatus) by a previous operation
+         *     (note: this uses sign-check of waitStatus because
+         *      PROPAGATE status may transition to SIGNAL.)
+         * and
+         *   The next node is waiting in shared mode,
+         *     or we don't know, because it appears null
+         *
+         * The conservatism in both of these checks may cause
+         * unnecessary wake-ups, but only when there are multiple
+         * racing acquires/releases, so most need signals now or soon
+         * anyway.
+         */
+        if (propagate > 0 || h == null || h.waitStatus < 0) {
+            Node s = node.next;
+            if (s == null || s.isShared())
+                doReleaseShared();
+        }
+    }
+
+    // Utilities for various versions of acquire
+
+    /**
+     * Cancels an ongoing attempt to acquire.
+     *
+     * @param node the node
+     */
+    private void cancelAcquire(Node node) {
+        // Ignore if node doesn't exist
+        if (node == null)
+            return;
+
+        node.thread = null;
+
+        // Skip cancelled predecessors
+        Node pred = node.prev;
+        while (pred.waitStatus > 0)
+            node.prev = pred = pred.prev;
+
+        // predNext is the apparent node to unsplice. CASes below will
+        // fail if not, in which case, we lost race vs another cancel
+        // or signal, so no further action is necessary.
+        Node predNext = pred.next;
+
+        // Can use unconditional write instead of CAS here.
+        // After this atomic step, other Nodes can skip past us.
+        // Before, we are free of interference from other threads.
+        node.waitStatus = Node.CANCELLED;
+
+        // If we are the tail, remove ourselves.
+        if (node == tail && compareAndSetTail(node, pred)) {
+            compareAndSetNext(pred, predNext, null);
+        } else {
+            // If successor needs signal, try to set pred's next-link
+            // so it will get one. Otherwise wake it up to propagate.
+            int ws;
+            if (pred != head &&
+                ((ws = pred.waitStatus) == Node.SIGNAL ||
+                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
+                pred.thread != null) {
+                Node next = node.next;
+                if (next != null && next.waitStatus <= 0)
+                    compareAndSetNext(pred, predNext, next);
+            } else {
+                unparkSuccessor(node);
+            }
+
+            node.next = node; // help GC
+        }
+    }
+
+    /**
+     * Checks and updates status for a node that failed to acquire.
+     * Returns true if thread should block. This is the main signal
+     * control in all acquire loops.  Requires that pred == node.prev
+     *
+     * @param pred node's predecessor holding status
+     * @param node the node
+     * @return {@code true} if thread should block
+     */
+    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
+        int ws = pred.waitStatus;
+        if (ws == Node.SIGNAL)
+            /*
+             * This node has already set status asking a release
+             * to signal it, so it can safely park.
+             */
+            return true;
+        if (ws > 0) {
+            /*
+             * Predecessor was cancelled. Skip over predecessors and
+             * indicate retry.
+             */
+            do {
+                node.prev = pred = pred.prev;
+            } while (pred.waitStatus > 0);
+            pred.next = node;
+        } else {
+            /*
+             * waitStatus must be 0 or PROPAGATE.  Indicate that we
+             * need a signal, but don't park yet.  Caller will need to
+             * retry to make sure it cannot acquire before parking.
+             */
+            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
+        }
+        return false;
+    }
+
+    /**
+     * Convenience method to interrupt current thread.
+     */
+    private static void selfInterrupt() {
+        Thread.currentThread().interrupt();
+    }
+
+    /**
+     * Convenience method to park and then check if interrupted
+     *
+     * @return {@code true} if interrupted
+     */
+    private final boolean parkAndCheckInterrupt() {
+        LockSupport.park(this);
+        return Thread.interrupted();
+    }
+
+    /*
+     * Various flavors of acquire, varying in exclusive/shared and
+     * control modes.  Each is mostly the same, but annoyingly
+     * different.  Only a little bit of factoring is possible due to
+     * interactions of exception mechanics (including ensuring that we
+     * cancel if tryAcquire throws exception) and other control, at
+     * least not without hurting performance too much.
+     */
+
+    /**
+     * Acquires in exclusive uninterruptible mode for thread already in
+     * queue. Used by condition wait methods as well as acquire.
+     *
+     * @param node the node
+     * @param arg the acquire argument
+     * @return {@code true} if interrupted while waiting
+     */
+    final boolean acquireQueued(final Node node, long arg) {
+        boolean failed = true;
+        try {
+            boolean interrupted = false;
+            for (;;) {
+                final Node p = node.predecessor();
+                if (p == head && tryAcquire(arg)) {
+                    setHead(node);
+                    p.next = null; // help GC
+                    failed = false;
+                    return interrupted;
+                }
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
+                    interrupted = true;
+            }
+        } finally {
+            if (failed)
+                cancelAcquire(node);
+        }
+    }
+
+    /**
+     * Acquires in exclusive interruptible mode.
+     * @param arg the acquire argument
+     */
+    private void doAcquireInterruptibly(long arg)
+        throws InterruptedException {
+        final Node node = addWaiter(Node.EXCLUSIVE);
+        boolean failed = true;
+        try {
+            for (;;) {
+                final Node p = node.predecessor();
+                if (p == head && tryAcquire(arg)) {
+                    setHead(node);
+                    p.next = null; // help GC
+                    failed = false;
+                    return;
+                }
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
+                    throw new InterruptedException();
+            }
+        } finally {
+            if (failed)
+                cancelAcquire(node);
+        }
+    }
+
+    /**
+     * Acquires in exclusive timed mode.
+     *
+     * @param arg the acquire argument
+     * @param nanosTimeout max wait time
+     * @return {@code true} if acquired
+     */
+    private boolean doAcquireNanos(long arg, long nanosTimeout)
+        throws InterruptedException {
+        long lastTime = System.nanoTime();
+        final Node node = addWaiter(Node.EXCLUSIVE);
+        boolean failed = true;
+        try {
+            for (;;) {
+                final Node p = node.predecessor();
+                if (p == head && tryAcquire(arg)) {
+                    setHead(node);
+                    p.next = null; // help GC
+                    failed = false;
+                    return true;
+                }
+                if (nanosTimeout <= 0)
+                    return false;
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    nanosTimeout > spinForTimeoutThreshold)
+                    LockSupport.parkNanos(this, nanosTimeout);
+                long now = System.nanoTime();
+                nanosTimeout -= now - lastTime;
+                lastTime = now;
+                if (Thread.interrupted())
+                    throw new InterruptedException();
+            }
+        } finally {
+            if (failed)
+                cancelAcquire(node);
+        }
+    }
+
+    /**
+     * Acquires in shared uninterruptible mode.
+     * @param arg the acquire argument
+     */
+    private void doAcquireShared(long arg) {
+        final Node node = addWaiter(Node.SHARED);
+        boolean failed = true;
+        try {
+            boolean interrupted = false;
+            for (;;) {
+                final Node p = node.predecessor();
+                if (p == head) {
+                    long r = tryAcquireShared(arg);
+                    if (r >= 0) {
+                        setHeadAndPropagate(node, r);
+                        p.next = null; // help GC
+                        if (interrupted)
+                            selfInterrupt();
+                        failed = false;
+                        return;
+                    }
+                }
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
+                    interrupted = true;
+            }
+        } finally {
+            if (failed)
+                cancelAcquire(node);
+        }
+    }
+
+    /**
+     * Acquires in shared interruptible mode.
+     * @param arg the acquire argument
+     */
+    private void doAcquireSharedInterruptibly(long arg)
+        throws InterruptedException {
+        final Node node = addWaiter(Node.SHARED);
+        boolean failed = true;
+        try {
+            for (;;) {
+                final Node p = node.predecessor();
+                if (p == head) {
+                    long r = tryAcquireShared(arg);
+                    if (r >= 0) {
+                        setHeadAndPropagate(node, r);
+                        p.next = null; // help GC
+                        failed = false;
+                        return;
+                    }
+                }
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    parkAndCheckInterrupt())
+                    throw new InterruptedException();
+            }
+        } finally {
+            if (failed)
+                cancelAcquire(node);
+        }
+    }
+
+    /**
+     * Acquires in shared timed mode.
+     *
+     * @param arg the acquire argument
+     * @param nanosTimeout max wait time
+     * @return {@code true} if acquired
+     */
+    private boolean doAcquireSharedNanos(long arg, long nanosTimeout)
+        throws InterruptedException {
+
+        long lastTime = System.nanoTime();
+        final Node node = addWaiter(Node.SHARED);
+        boolean failed = true;
+        try {
+            for (;;) {
+                final Node p = node.predecessor();
+                if (p == head) {
+                    long r = tryAcquireShared(arg);
+                    if (r >= 0) {
+                        setHeadAndPropagate(node, r);
+                        p.next = null; // help GC
+                        failed = false;
+                        return true;
+                    }
+                }
+                if (nanosTimeout <= 0)
+                    return false;
+                if (shouldParkAfterFailedAcquire(p, node) &&
+                    nanosTimeout > spinForTimeoutThreshold)
+                    LockSupport.parkNanos(this, nanosTimeout);
+                long now = System.nanoTime();
+                nanosTimeout -= now - lastTime;
+                lastTime = now;
+                if (Thread.interrupted())
+                    throw new InterruptedException();
+            }
+        } finally {
+            if (failed)
+                cancelAcquire(node);
+        }
+    }
+
+    // Main exported methods
+
+    /**
+     * Attempts to acquire in exclusive mode. This method should query
+     * if the state of the object permits it to be acquired in the
+     * exclusive mode, and if so to acquire it.
+     *
+     * <p>This method is always invoked by the thread performing
+     * acquire.  If this method reports failure, the acquire method
+     * may queue the thread, if it is not already queued, until it is
+     * signalled by a release from some other thread. This can be used
+     * to implement method {@link Lock#tryLock()}.
+     *
+     * <p>The default
+     * implementation throws {@link UnsupportedOperationException}.
+     *
+     * @param arg the acquire argument. This value is always the one
+     *        passed to an acquire method, or is the value saved on entry
+     *        to a condition wait.  The value is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @return {@code true} if successful. Upon success, this object has
+     *         been acquired.
+     * @throws IllegalMonitorStateException if acquiring would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
+     * @throws UnsupportedOperationException if exclusive mode is not supported
+     */
+    protected boolean tryAcquire(long arg) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Attempts to set the state to reflect a release in exclusive
+     * mode.
+     *
+     * <p>This method is always invoked by the thread performing release.
+     *
+     * <p>The default implementation throws
+     * {@link UnsupportedOperationException}.
+     *
+     * @param arg the release argument. This value is always the one
+     *        passed to a release method, or the current state value upon
+     *        entry to a condition wait.  The value is otherwise
+     *        uninterpreted and can represent anything you like.
+     * @return {@code true} if this object is now in a fully released
+     *         state, so that any waiting threads may attempt to acquire;
+     *         and {@code false} otherwise.
+     * @throws IllegalMonitorStateException if releasing would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
+     * @throws UnsupportedOperationException if exclusive mode is not supported
+     */
+    protected boolean tryRelease(long arg) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Attempts to acquire in shared mode. This method should query if
+     * the state of the object permits it to be acquired in the shared
+     * mode, and if so to acquire it.
+     *
+     * <p>This method is always invoked by the thread performing
+     * acquire.  If this method reports failure, the acquire method
+     * may queue the thread, if it is not already queued, until it is
+     * signalled by a release from some other thread.
+     *
+     * <p>The default implementation throws {@link
+     * UnsupportedOperationException}.
+     *
+     * @param arg the acquire argument. This value is always the one
+     *        passed to an acquire method, or is the value saved on entry
+     *        to a condition wait.  The value is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @return a negative value on failure; zero if acquisition in shared
+     *         mode succeeded but no subsequent shared-mode acquire can
+     *         succeed; and a positive value if acquisition in shared
+     *         mode succeeded and subsequent shared-mode acquires might
+     *         also succeed, in which case a subsequent waiting thread
+     *         must check availability. (Support for three different
+     *         return values enables this method to be used in contexts
+     *         where acquires only sometimes act exclusively.)  Upon
+     *         success, this object has been acquired.
+     * @throws IllegalMonitorStateException if acquiring would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
+     * @throws UnsupportedOperationException if shared mode is not supported
+     */
+    protected long tryAcquireShared(long arg) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Attempts to set the state to reflect a release in shared mode.
+     *
+     * <p>This method is always invoked by the thread performing release.
+     *
+     * <p>The default implementation throws
+     * {@link UnsupportedOperationException}.
+     *
+     * @param arg the release argument. This value is always the one
+     *        passed to a release method, or the current state value upon
+     *        entry to a condition wait.  The value is otherwise
+     *        uninterpreted and can represent anything you like.
+     * @return {@code true} if this release of shared mode may permit a
+     *         waiting acquire (shared or exclusive) to succeed; and
+     *         {@code false} otherwise
+     * @throws IllegalMonitorStateException if releasing would place this
+     *         synchronizer in an illegal state. This exception must be
+     *         thrown in a consistent fashion for synchronization to work
+     *         correctly.
+     * @throws UnsupportedOperationException if shared mode is not supported
+     */
+    protected boolean tryReleaseShared(long arg) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns {@code true} if synchronization is held exclusively with
+     * respect to the current (calling) thread.  This method is invoked
+     * upon each call to a non-waiting {@link ConditionObject} method.
+     * (Waiting methods instead invoke {@link #release}.)
+     *
+     * <p>The default implementation throws {@link
+     * UnsupportedOperationException}. This method is invoked
+     * internally only within {@link ConditionObject} methods, so need
+     * not be defined if conditions are not used.
+     *
+     * @return {@code true} if synchronization is held exclusively;
+     *         {@code false} otherwise
+     * @throws UnsupportedOperationException if conditions are not supported
+     */
+    protected boolean isHeldExclusively() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Acquires in exclusive mode, ignoring interrupts.  Implemented
+     * by invoking at least once {@link #tryAcquire},
+     * returning on success.  Otherwise the thread is queued, possibly
+     * repeatedly blocking and unblocking, invoking {@link
+     * #tryAcquire} until success.  This method can be used
+     * to implement method {@link Lock#lock}.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquire} but is otherwise uninterpreted and
+     *        can represent anything you like.
+     */
+    public final void acquire(long arg) {
+        if (!tryAcquire(arg) &&
+            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
+            selfInterrupt();
+    }
+
+    /**
+     * Acquires in exclusive mode, aborting if interrupted.
+     * Implemented by first checking interrupt status, then invoking
+     * at least once {@link #tryAcquire}, returning on
+     * success.  Otherwise the thread is queued, possibly repeatedly
+     * blocking and unblocking, invoking {@link #tryAcquire}
+     * until success or the thread is interrupted.  This method can be
+     * used to implement method {@link Lock#lockInterruptibly}.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquire} but is otherwise uninterpreted and
+     *        can represent anything you like.
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public final void acquireInterruptibly(long arg) throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        if (!tryAcquire(arg))
+            doAcquireInterruptibly(arg);
+    }
+
+    /**
+     * Attempts to acquire in exclusive mode, aborting if interrupted,
+     * and failing if the given timeout elapses.  Implemented by first
+     * checking interrupt status, then invoking at least once {@link
+     * #tryAcquire}, returning on success.  Otherwise, the thread is
+     * queued, possibly repeatedly blocking and unblocking, invoking
+     * {@link #tryAcquire} until success or the thread is interrupted
+     * or the timeout elapses.  This method can be used to implement
+     * method {@link Lock#tryLock(long, TimeUnit)}.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquire} but is otherwise uninterpreted and
+     *        can represent anything you like.
+     * @param nanosTimeout the maximum number of nanoseconds to wait
+     * @return {@code true} if acquired; {@code false} if timed out
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public final boolean tryAcquireNanos(long arg, long nanosTimeout) throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        return tryAcquire(arg) ||
+            doAcquireNanos(arg, nanosTimeout);
+    }
+
+    /**
+     * Releases in exclusive mode.  Implemented by unblocking one or
+     * more threads if {@link #tryRelease} returns true.
+     * This method can be used to implement method {@link Lock#unlock}.
+     *
+     * @param arg the release argument.  This value is conveyed to
+     *        {@link #tryRelease} but is otherwise uninterpreted and
+     *        can represent anything you like.
+     * @return the value returned from {@link #tryRelease}
+     */
+    public final boolean release(long arg) {
+        if (tryRelease(arg)) {
+            Node h = head;
+            if (h != null && h.waitStatus != 0)
+                unparkSuccessor(h);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Acquires in shared mode, ignoring interrupts.  Implemented by
+     * first invoking at least once {@link #tryAcquireShared},
+     * returning on success.  Otherwise the thread is queued, possibly
+     * repeatedly blocking and unblocking, invoking {@link
+     * #tryAcquireShared} until success.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquireShared} but is otherwise uninterpreted
+     *        and can represent anything you like.
+     */
+    public final void acquireShared(long arg) {
+        if (tryAcquireShared(arg) < 0)
+            doAcquireShared(arg);
+    }
+
+    /**
+     * Acquires in shared mode, aborting if interrupted.  Implemented
+     * by first checking interrupt status, then invoking at least once
+     * {@link #tryAcquireShared}, returning on success.  Otherwise the
+     * thread is queued, possibly repeatedly blocking and unblocking,
+     * invoking {@link #tryAcquireShared} until success or the thread
+     * is interrupted.
+     * @param arg the acquire argument
+     * This value is conveyed to {@link #tryAcquireShared} but is
+     * otherwise uninterpreted and can represent anything
+     * you like.
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public final void acquireSharedInterruptibly(long arg) throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        if (tryAcquireShared(arg) < 0)
+            doAcquireSharedInterruptibly(arg);
+    }
+
+    /**
+     * Attempts to acquire in shared mode, aborting if interrupted, and
+     * failing if the given timeout elapses.  Implemented by first
+     * checking interrupt status, then invoking at least once {@link
+     * #tryAcquireShared}, returning on success.  Otherwise, the
+     * thread is queued, possibly repeatedly blocking and unblocking,
+     * invoking {@link #tryAcquireShared} until success or the thread
+     * is interrupted or the timeout elapses.
+     *
+     * @param arg the acquire argument.  This value is conveyed to
+     *        {@link #tryAcquireShared} but is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @param nanosTimeout the maximum number of nanoseconds to wait
+     * @return {@code true} if acquired; {@code false} if timed out
+     * @throws InterruptedException if the current thread is interrupted
+     */
+    public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout) throws InterruptedException {
+        if (Thread.interrupted())
+            throw new InterruptedException();
+        return tryAcquireShared(arg) >= 0 ||
+            doAcquireSharedNanos(arg, nanosTimeout);
+    }
+
+    /**
+     * Releases in shared mode.  Implemented by unblocking one or more
+     * threads if {@link #tryReleaseShared} returns true.
+     *
+     * @param arg the release argument.  This value is conveyed to
+     *        {@link #tryReleaseShared} but is otherwise uninterpreted
+     *        and can represent anything you like.
+     * @return the value returned from {@link #tryReleaseShared}
+     */
+    public final boolean releaseShared(long arg) {
+        if (tryReleaseShared(arg)) {
+            doReleaseShared();
+            return true;
+        }
+        return false;
+    }
+
+    // Queue inspection methods
+
+    /**
+     * Queries whether any threads are waiting to acquire. Note that
+     * because cancellations due to interrupts and timeouts may occur
+     * at any time, a {@code true} return does not guarantee that any
+     * other thread will ever acquire.
+     *
+     * <p>In this implementation, this operation returns in
+     * constant time.
+     *
+     * @return {@code true} if there may be other threads waiting to acquire
+     */
+    public final boolean hasQueuedThreads() {
+        return head != tail;
+    }
+
+    /**
+     * Queries whether any threads have ever contended to acquire this
+     * synchronizer; that is if an acquire method has ever blocked.
+     *
+     * <p>In this implementation, this operation returns in
+     * constant time.
+     *
+     * @return {@code true} if there has ever been contention
+     */
+    public final boolean hasContended() {
+        return head != null;
+    }
+
+    /**
+     * Returns the first (longest-waiting) thread in the queue, or
+     * {@code null} if no threads are currently queued.
+     *
+     * <p>In this implementation, this operation normally returns in
+     * constant time, but may iterate upon contention if other threads are
+     * concurrently modifying the queue.
+     *
+     * @return the first (longest-waiting) thread in the queue, or
+     *         {@code null} if no threads are currently queued
+     */
+    public final Thread getFirstQueuedThread() {
+        // handle only fast path, else relay
+        return (head == tail) ? null : fullGetFirstQueuedThread();
+    }
+
+    /**
+     * Version of getFirstQueuedThread called when fastpath fails
+     */
+    private Thread fullGetFirstQueuedThread() {
+        /*
+         * The first node is normally head.next. Try to get its
+         * thread field, ensuring consistent reads: If thread
+         * field is nulled out or s.prev is no longer head, then
+         * some other thread(s) concurrently performed setHead in
+         * between some of our reads. We try this twice before
+         * resorting to traversal.
+         */
+        Node h, s;
+        Thread st;
+        if (((h = head) != null && (s = h.next) != null &&
+             s.prev == head && (st = s.thread) != null) ||
+            ((h = head) != null && (s = h.next) != null &&
+             s.prev == head && (st = s.thread) != null))
+            return st;
+
+        /*
+         * Head's next field might not have been set yet, or may have
+         * been unset after setHead. So we must check to see if tail
+         * is actually first node. If not, we continue on, safely
+         * traversing from tail back to head to find first,
+         * guaranteeing termination.
+         */
+
+        Node t = tail;
+        Thread firstThread = null;
+        while (t != null && t != head) {
+            Thread tt = t.thread;
+            if (tt != null)
+                firstThread = tt;
+            t = t.prev;
+        }
+        return firstThread;
+    }
+
+    /**
+     * Returns true if the given thread is currently queued.
+     *
+     * <p>This implementation traverses the queue to determine
+     * presence of the given thread.
+     *
+     * @param thread the thread
+     * @return {@code true} if the given thread is on the queue
+     * @throws NullPointerException if the thread is null
+     */
+    public final boolean isQueued(Thread thread) {
+        if (thread == null)
+            throw new NullPointerException();
+        for (Node p = tail; p != null; p = p.prev)
+            if (p.thread == thread)
+                return true;
+        return false;
+    }
+
+    /**
+     * Returns {@code true} if the apparent first queued thread, if one
+     * exists, is waiting in exclusive mode.  If this method returns
+     * {@code true}, and the current thread is attempting to acquire in
+     * shared mode (that is, this method is invoked from {@link
+     * #tryAcquireShared}) then it is guaranteed that the current thread
+     * is not the first queued thread.  Used only as a heuristic in
+     * ReentrantReadWriteLock.
+     */
+    final boolean apparentlyFirstQueuedIsExclusive() {
+        Node h, s;
+        return (h = head) != null &&
+            (s = h.next)  != null &&
+            !s.isShared()         &&
+            s.thread != null;
+    }
+
+    /**
+     * Queries whether any threads have been waiting to acquire longer
+     * than the current thread.
+     *
+     * <p>An invocation of this method is equivalent to (but may be
+     * more efficient than):
+     *  <pre> {@code
+     * getFirstQueuedThread() != Thread.currentThread() &&
+     * hasQueuedThreads()}</pre>
+     *
+     * <p>Note that because cancellations due to interrupts and
+     * timeouts may occur at any time, a {@code true} return does not
+     * guarantee that some other thread will acquire before the current
+     * thread.  Likewise, it is possible for another thread to win a
+     * race to enqueue after this method has returned {@code false},
+     * due to the queue being empty.
+     *
+     * <p>This method is designed to be used by a fair synchronizer to
+     * avoid <a href="AbstractQueuedSynchronizer#barging">barging</a>.
+     * Such a synchronizer's {@link #tryAcquire} method should return
+     * {@code false}, and its {@link #tryAcquireShared} method should
+     * return a negative value, if this method returns {@code true}
+     * (unless this is a reentrant acquire).  For example, the {@code
+     * tryAcquire} method for a fair, reentrant, exclusive mode
+     * synchronizer might look like this:
+     *
+     *  <pre> {@code
+     * protected boolean tryAcquire(int arg) {
+     *   if (isHeldExclusively()) {
+     *     // A reentrant acquire; increment hold count
+     *     return true;
+     *   } else if (hasQueuedPredecessors()) {
+     *     return false;
+     *   } else {
+     *     // try to acquire normally
+     *   }
+     * }}</pre>
+     *
+     * @return {@code true} if there is a queued thread preceding the
+     *         current thread, and {@code false} if the current thread
+     *         is at the head of the queue or the queue is empty
+     * @since 1.7
+     */
+    /*public*/ final boolean hasQueuedPredecessors() { // android-changed
+        // The correctness of this depends on head being initialized
+        // before tail and on head.next being accurate if the current
+        // thread is first in queue.
+        Node t = tail; // Read fields in reverse initialization order
+        Node h = head;
+        Node s;
+        return h != t &&
+            ((s = h.next) == null || s.thread != Thread.currentThread());
+    }
+
+
+    // Instrumentation and monitoring methods
+
+    /**
+     * Returns an estimate of the number of threads waiting to
+     * acquire.  The value is only an estimate because the number of
+     * threads may change dynamically while this method traverses
+     * internal data structures.  This method is designed for use in
+     * monitoring system state, not for synchronization
+     * control.
+     *
+     * @return the estimated number of threads waiting to acquire
+     */
+    public final int getQueueLength() {
+        int n = 0;
+        for (Node p = tail; p != null; p = p.prev) {
+            if (p.thread != null)
+                ++n;
+        }
+        return n;
+    }
+
+    /**
+     * Returns a collection containing threads that may be waiting to
+     * acquire.  Because the actual set of threads may change
+     * dynamically while constructing this result, the returned
+     * collection is only a best-effort estimate.  The elements of the
+     * returned collection are in no particular order.  This method is
+     * designed to facilitate construction of subclasses that provide
+     * more extensive monitoring facilities.
+     *
+     * @return the collection of threads
+     */
+    public final Collection<Thread> getQueuedThreads() {
+        ArrayList<Thread> list = new ArrayList<Thread>();
+        for (Node p = tail; p != null; p = p.prev) {
+            Thread t = p.thread;
+            if (t != null)
+                list.add(t);
+        }
+        return list;
+    }
+
+    /**
+     * Returns a collection containing threads that may be waiting to
+     * acquire in exclusive mode. This has the same properties
+     * as {@link #getQueuedThreads} except that it only returns
+     * those threads waiting due to an exclusive acquire.
+     *
+     * @return the collection of threads
+     */
+    public final Collection<Thread> getExclusiveQueuedThreads() {
+        ArrayList<Thread> list = new ArrayList<Thread>();
+        for (Node p = tail; p != null; p = p.prev) {
+            if (!p.isShared()) {
+                Thread t = p.thread;
+                if (t != null)
+                    list.add(t);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns a collection containing threads that may be waiting to
+     * acquire in shared mode. This has the same properties
+     * as {@link #getQueuedThreads} except that it only returns
+     * those threads waiting due to a shared acquire.
+     *
+     * @return the collection of threads
+     */
+    public final Collection<Thread> getSharedQueuedThreads() {
+        ArrayList<Thread> list = new ArrayList<Thread>();
+        for (Node p = tail; p != null; p = p.prev) {
+            if (p.isShared()) {
+                Thread t = p.thread;
+                if (t != null)
+                    list.add(t);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns a string identifying this synchronizer, as well as its state.
+     * The state, in brackets, includes the String {@code "State ="}
+     * followed by the current value of {@link #getState}, and either
+     * {@code "nonempty"} or {@code "empty"} depending on whether the
+     * queue is empty.
+     *
+     * @return a string identifying this synchronizer, as well as its state
+     */
+    public String toString() {
+        long s = getState();
+        String q  = hasQueuedThreads() ? "non" : "";
+        return super.toString() +
+            "[State = " + s + ", " + q + "empty queue]";
+    }
+
+
+    // Internal support methods for Conditions
+
+    /**
+     * Returns true if a node, always one that was initially placed on
+     * a condition queue, is now waiting to reacquire on sync queue.
+     * @param node the node
+     * @return true if is reacquiring
+     */
+    final boolean isOnSyncQueue(Node node) {
+        if (node.waitStatus == Node.CONDITION || node.prev == null)
+            return false;
+        if (node.next != null) // If has successor, it must be on queue
+            return true;
+        /*
+         * node.prev can be non-null, but not yet on queue because
+         * the CAS to place it on queue can fail. So we have to
+         * traverse from tail to make sure it actually made it.  It
+         * will always be near the tail in calls to this method, and
+         * unless the CAS failed (which is unlikely), it will be
+         * there, so we hardly ever traverse much.
+         */
+        return findNodeFromTail(node);
+    }
+
+    /**
+     * Returns true if node is on sync queue by searching backwards from tail.
+     * Called only when needed by isOnSyncQueue.
+     * @return true if present
+     */
+    private boolean findNodeFromTail(Node node) {
+        Node t = tail;
+        for (;;) {
+            if (t == node)
+                return true;
+            if (t == null)
+                return false;
+            t = t.prev;
+        }
+    }
+
+    /**
+     * Transfers a node from a condition queue onto sync queue.
+     * Returns true if successful.
+     * @param node the node
+     * @return true if successfully transferred (else the node was
+     * cancelled before signal).
+     */
+    final boolean transferForSignal(Node node) {
+        /*
+         * If cannot change waitStatus, the node has been cancelled.
+         */
+        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
+            return false;
+
+        /*
+         * Splice onto queue and try to set waitStatus of predecessor to
+         * indicate that thread is (probably) waiting. If cancelled or
+         * attempt to set waitStatus fails, wake up to resync (in which
+         * case the waitStatus can be transiently and harmlessly wrong).
+         */
+        Node p = enq(node);
+        int ws = p.waitStatus;
+        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
+            LockSupport.unpark(node.thread);
+        return true;
+    }
+
+    /**
+     * Transfers node, if necessary, to sync queue after a cancelled
+     * wait. Returns true if thread was cancelled before being
+     * signalled.
+     * @param current the waiting thread
+     * @param node its node
+     * @return true if cancelled before the node was signalled
+     */
+    final boolean transferAfterCancelledWait(Node node) {
+        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
+            enq(node);
+            return true;
+        }
+        /*
+         * If we lost out to a signal(), then we can't proceed
+         * until it finishes its enq().  Cancelling during an
+         * incomplete transfer is both rare and transient, so just
+         * spin.
+         */
+        while (!isOnSyncQueue(node))
+            Thread.yield();
+        return false;
+    }
+
+    /**
+     * Invokes release with current state value; returns saved state.
+     * Cancels node and throws exception on failure.
+     * @param node the condition node for this wait
+     * @return previous sync state
+     */
+    final long fullyRelease(Node node) {
+        boolean failed = true;
+        try {
+            long savedState = getState();
+            if (release(savedState)) {
+                failed = false;
+                return savedState;
+            } else {
+                throw new IllegalMonitorStateException();
+            }
+        } finally {
+            if (failed)
+                node.waitStatus = Node.CANCELLED;
+        }
+    }
+
+    // Instrumentation methods for conditions
+
+    /**
+     * Queries whether the given ConditionObject
+     * uses this synchronizer as its lock.
+     *
+     * @param condition the condition
+     * @return <tt>true</tt> if owned
+     * @throws NullPointerException if the condition is null
+     */
+    public final boolean owns(ConditionObject condition) {
+        if (condition == null)
+            throw new NullPointerException();
+        return condition.isOwnedBy(this);
+    }
+
+    /**
+     * Queries whether any threads are waiting on the given condition
+     * associated with this synchronizer. Note that because timeouts
+     * and interrupts may occur at any time, a <tt>true</tt> return
+     * does not guarantee that a future <tt>signal</tt> will awaken
+     * any threads.  This method is designed primarily for use in
+     * monitoring of the system state.
+     *
+     * @param condition the condition
+     * @return <tt>true</tt> if there are any waiting threads
+     * @throws IllegalMonitorStateException if exclusive synchronization
+     *         is not held
+     * @throws IllegalArgumentException if the given condition is
+     *         not associated with this synchronizer
+     * @throws NullPointerException if the condition is null
+     */
+    public final boolean hasWaiters(ConditionObject condition) {
+        if (!owns(condition))
+            throw new IllegalArgumentException("Not owner");
+        return condition.hasWaiters();
+    }
+
+    /**
+     * Returns an estimate of the number of threads waiting on the
+     * given condition associated with this synchronizer. Note that
+     * because timeouts and interrupts may occur at any time, the
+     * estimate serves only as an upper bound on the actual number of
+     * waiters.  This method is designed for use in monitoring of the
+     * system state, not for synchronization control.
+     *
+     * @param condition the condition
+     * @return the estimated number of waiting threads
+     * @throws IllegalMonitorStateException if exclusive synchronization
+     *         is not held
+     * @throws IllegalArgumentException if the given condition is
+     *         not associated with this synchronizer
+     * @throws NullPointerException if the condition is null
+     */
+    public final int getWaitQueueLength(ConditionObject condition) {
+        if (!owns(condition))
+            throw new IllegalArgumentException("Not owner");
+        return condition.getWaitQueueLength();
+    }
+
+    /**
+     * Returns a collection containing those threads that may be
+     * waiting on the given condition associated with this
+     * synchronizer.  Because the actual set of threads may change
+     * dynamically while constructing this result, the returned
+     * collection is only a best-effort estimate. The elements of the
+     * returned collection are in no particular order.
+     *
+     * @param condition the condition
+     * @return the collection of threads
+     * @throws IllegalMonitorStateException if exclusive synchronization
+     *         is not held
+     * @throws IllegalArgumentException if the given condition is
+     *         not associated with this synchronizer
+     * @throws NullPointerException if the condition is null
+     */
+    public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
+        if (!owns(condition))
+            throw new IllegalArgumentException("Not owner");
+        return condition.getWaitingThreads();
+    }
+
+    /**
+     * Condition implementation for a {@link
+     * AbstractQueuedLongSynchronizer} serving as the basis of a {@link
+     * Lock} implementation.
+     *
+     * <p>Method documentation for this class describes mechanics,
+     * not behavioral specifications from the point of view of Lock
+     * and Condition users. Exported versions of this class will in
+     * general need to be accompanied by documentation describing
+     * condition semantics that rely on those of the associated
+     * <tt>AbstractQueuedLongSynchronizer</tt>.
+     *
+     * <p>This class is Serializable, but all fields are transient,
+     * so deserialized conditions have no waiters.
+     *
+     * @since 1.6
+     */
+    public class ConditionObject implements Condition, java.io.Serializable {
+        private static final long serialVersionUID = 1173984872572414699L;
+        /** First node of condition queue. */
+        private transient Node firstWaiter;
+        /** Last node of condition queue. */
+        private transient Node lastWaiter;
+
+        /**
+         * Creates a new <tt>ConditionObject</tt> instance.
+         */
+        public ConditionObject() { }
+
+        // Internal methods
+
+        /**
+         * Adds a new waiter to wait queue.
+         * @return its new wait node
+         */
+        private Node addConditionWaiter() {
+            Node t = lastWaiter;
+            // If lastWaiter is cancelled, clean out.
+            if (t != null && t.waitStatus != Node.CONDITION) {
+                unlinkCancelledWaiters();
+                t = lastWaiter;
+            }
+            Node node = new Node(Thread.currentThread(), Node.CONDITION);
+            if (t == null)
+                firstWaiter = node;
+            else
+                t.nextWaiter = node;
+            lastWaiter = node;
+            return node;
+        }
+
+        /**
+         * Removes and transfers nodes until hit non-cancelled one or
+         * null. Split out from signal in part to encourage compilers
+         * to inline the case of no waiters.
+         * @param first (non-null) the first node on condition queue
+         */
+        private void doSignal(Node first) {
+            do {
+                if ( (firstWaiter = first.nextWaiter) == null)
+                    lastWaiter = null;
+                first.nextWaiter = null;
+            } while (!transferForSignal(first) &&
+                     (first = firstWaiter) != null);
+        }
+
+        /**
+         * Removes and transfers all nodes.
+         * @param first (non-null) the first node on condition queue
+         */
+        private void doSignalAll(Node first) {
+            lastWaiter = firstWaiter = null;
+            do {
+                Node next = first.nextWaiter;
+                first.nextWaiter = null;
+                transferForSignal(first);
+                first = next;
+            } while (first != null);
+        }
+
+        /**
+         * Unlinks cancelled waiter nodes from condition queue.
+         * Called only while holding lock. This is called when
+         * cancellation occurred during condition wait, and upon
+         * insertion of a new waiter when lastWaiter is seen to have
+         * been cancelled. This method is needed to avoid garbage
+         * retention in the absence of signals. So even though it may
+         * require a full traversal, it comes into play only when
+         * timeouts or cancellations occur in the absence of
+         * signals. It traverses all nodes rather than stopping at a
+         * particular target to unlink all pointers to garbage nodes
+         * without requiring many re-traversals during cancellation
+         * storms.
+         */
+        private void unlinkCancelledWaiters() {
+            Node t = firstWaiter;
+            Node trail = null;
+            while (t != null) {
+                Node next = t.nextWaiter;
+                if (t.waitStatus != Node.CONDITION) {
+                    t.nextWaiter = null;
+                    if (trail == null)
+                        firstWaiter = next;
+                    else
+                        trail.nextWaiter = next;
+                    if (next == null)
+                        lastWaiter = trail;
+                }
+                else
+                    trail = t;
+                t = next;
+            }
+        }
+
+        // public methods
+
+        /**
+         * Moves the longest-waiting thread, if one exists, from the
+         * wait queue for this condition to the wait queue for the
+         * owning lock.
+         *
+         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+         *         returns {@code false}
+         */
+        public final void signal() {
+            if (!isHeldExclusively())
+                throw new IllegalMonitorStateException();
+            Node first = firstWaiter;
+            if (first != null)
+                doSignal(first);
+        }
+
+        /**
+         * Moves all threads from the wait queue for this condition to
+         * the wait queue for the owning lock.
+         *
+         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+         *         returns {@code false}
+         */
+        public final void signalAll() {
+            if (!isHeldExclusively())
+                throw new IllegalMonitorStateException();
+            Node first = firstWaiter;
+            if (first != null)
+                doSignalAll(first);
+        }
+
+        /**
+         * Implements uninterruptible condition wait.
+         * <ol>
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled.
+         * <li> Reacquire by invoking specialized version of
+         *      {@link #acquire} with saved state as argument.
+         * </ol>
+         */
+        public final void awaitUninterruptibly() {
+            Node node = addConditionWaiter();
+            long savedState = fullyRelease(node);
+            boolean interrupted = false;
+            while (!isOnSyncQueue(node)) {
+                LockSupport.park(this);
+                if (Thread.interrupted())
+                    interrupted = true;
+            }
+            if (acquireQueued(node, savedState) || interrupted)
+                selfInterrupt();
+        }
+
+        /*
+         * For interruptible waits, we need to track whether to throw
+         * InterruptedException, if interrupted while blocked on
+         * condition, versus reinterrupt current thread, if
+         * interrupted while blocked waiting to re-acquire.
+         */
+
+        /** Mode meaning to reinterrupt on exit from wait */
+        private static final int REINTERRUPT =  1;
+        /** Mode meaning to throw InterruptedException on exit from wait */
+        private static final int THROW_IE    = -1;
+
+        /**
+         * Checks for interrupt, returning THROW_IE if interrupted
+         * before signalled, REINTERRUPT if after signalled, or
+         * 0 if not interrupted.
+         */
+        private int checkInterruptWhileWaiting(Node node) {
+            return Thread.interrupted() ?
+                (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
+                0;
+        }
+
+        /**
+         * Throws InterruptedException, reinterrupts current thread, or
+         * does nothing, depending on mode.
+         */
+        private void reportInterruptAfterWait(int interruptMode)
+            throws InterruptedException {
+            if (interruptMode == THROW_IE)
+                throw new InterruptedException();
+            else if (interruptMode == REINTERRUPT)
+                selfInterrupt();
+        }
+
+        /**
+         * Implements interruptible condition wait.
+         * <ol>
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled or interrupted.
+         * <li> Reacquire by invoking specialized version of
+         *      {@link #acquire} with saved state as argument.
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * </ol>
+         */
+        public final void await() throws InterruptedException {
+            if (Thread.interrupted())
+                throw new InterruptedException();
+            Node node = addConditionWaiter();
+            long savedState = fullyRelease(node);
+            int interruptMode = 0;
+            while (!isOnSyncQueue(node)) {
+                LockSupport.park(this);
+                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+                    break;
+            }
+            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+                interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null) // clean up if cancelled
+                unlinkCancelledWaiters();
+            if (interruptMode != 0)
+                reportInterruptAfterWait(interruptMode);
+        }
+
+        /**
+         * Implements timed condition wait.
+         * <ol>
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled, interrupted, or timed out.
+         * <li> Reacquire by invoking specialized version of
+         *      {@link #acquire} with saved state as argument.
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * </ol>
+         */
+        public final long awaitNanos(long nanosTimeout) throws InterruptedException {
+            if (Thread.interrupted())
+                throw new InterruptedException();
+            Node node = addConditionWaiter();
+            long savedState = fullyRelease(node);
+            long lastTime = System.nanoTime();
+            int interruptMode = 0;
+            while (!isOnSyncQueue(node)) {
+                if (nanosTimeout <= 0L) {
+                    transferAfterCancelledWait(node);
+                    break;
+                }
+                LockSupport.parkNanos(this, nanosTimeout);
+                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+                    break;
+
+                long now = System.nanoTime();
+                nanosTimeout -= now - lastTime;
+                lastTime = now;
+            }
+            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+                interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null)
+                unlinkCancelledWaiters();
+            if (interruptMode != 0)
+                reportInterruptAfterWait(interruptMode);
+            return nanosTimeout - (System.nanoTime() - lastTime);
+        }
+
+        /**
+         * Implements absolute timed condition wait.
+         * <ol>
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled, interrupted, or timed out.
+         * <li> Reacquire by invoking specialized version of
+         *      {@link #acquire} with saved state as argument.
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li> If timed out while blocked in step 4, return false, else true.
+         * </ol>
+         */
+        public final boolean awaitUntil(Date deadline) throws InterruptedException {
+            if (deadline == null)
+                throw new NullPointerException();
+            long abstime = deadline.getTime();
+            if (Thread.interrupted())
+                throw new InterruptedException();
+            Node node = addConditionWaiter();
+            long savedState = fullyRelease(node);
+            boolean timedout = false;
+            int interruptMode = 0;
+            while (!isOnSyncQueue(node)) {
+                if (System.currentTimeMillis() > abstime) {
+                    timedout = transferAfterCancelledWait(node);
+                    break;
+                }
+                LockSupport.parkUntil(this, abstime);
+                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+                    break;
+            }
+            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+                interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null)
+                unlinkCancelledWaiters();
+            if (interruptMode != 0)
+                reportInterruptAfterWait(interruptMode);
+            return !timedout;
+        }
+
+        /**
+         * Implements timed condition wait.
+         * <ol>
+         * <li> If current thread is interrupted, throw InterruptedException.
+         * <li> Save lock state returned by {@link #getState}.
+         * <li> Invoke {@link #release} with
+         *      saved state as argument, throwing
+         *      IllegalMonitorStateException if it fails.
+         * <li> Block until signalled, interrupted, or timed out.
+         * <li> Reacquire by invoking specialized version of
+         *      {@link #acquire} with saved state as argument.
+         * <li> If interrupted while blocked in step 4, throw InterruptedException.
+         * <li> If timed out while blocked in step 4, return false, else true.
+         * </ol>
+         */
+        public final boolean await(long time, TimeUnit unit) throws InterruptedException {
+            if (unit == null)
+                throw new NullPointerException();
+            long nanosTimeout = unit.toNanos(time);
+            if (Thread.interrupted())
+                throw new InterruptedException();
+            Node node = addConditionWaiter();
+            long savedState = fullyRelease(node);
+            long lastTime = System.nanoTime();
+            boolean timedout = false;
+            int interruptMode = 0;
+            while (!isOnSyncQueue(node)) {
+                if (nanosTimeout <= 0L) {
+                    timedout = transferAfterCancelledWait(node);
+                    break;
+                }
+                if (nanosTimeout >= spinForTimeoutThreshold)
+                    LockSupport.parkNanos(this, nanosTimeout);
+                if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+                    break;
+                long now = System.nanoTime();
+                nanosTimeout -= now - lastTime;
+                lastTime = now;
+            }
+            if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+                interruptMode = REINTERRUPT;
+            if (node.nextWaiter != null)
+                unlinkCancelledWaiters();
+            if (interruptMode != 0)
+                reportInterruptAfterWait(interruptMode);
+            return !timedout;
+        }
+
+        //  support for instrumentation
+
+        /**
+         * Returns true if this condition was created by the given
+         * synchronization object.
+         *
+         * @return {@code true} if owned
+         */
+        final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) {
+            return sync == AbstractQueuedLongSynchronizer.this;
+        }
+
+        /**
+         * Queries whether any threads are waiting on this condition.
+         * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}.
+         *
+         * @return {@code true} if there are any waiting threads
+         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+         *         returns {@code false}
+         */
+        protected final boolean hasWaiters() {
+            if (!isHeldExclusively())
+                throw new IllegalMonitorStateException();
+            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+                if (w.waitStatus == Node.CONDITION)
+                    return true;
+            }
+            return false;
+        }
+
+        /**
+         * Returns an estimate of the number of threads waiting on
+         * this condition.
+         * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}.
+         *
+         * @return the estimated number of waiting threads
+         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+         *         returns {@code false}
+         */
+        protected final int getWaitQueueLength() {
+            if (!isHeldExclusively())
+                throw new IllegalMonitorStateException();
+            int n = 0;
+            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+                if (w.waitStatus == Node.CONDITION)
+                    ++n;
+            }
+            return n;
+        }
+
+        /**
+         * Returns a collection containing those threads that may be
+         * waiting on this Condition.
+         * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}.
+         *
+         * @return the collection of threads
+         * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+         *         returns {@code false}
+         */
+        protected final Collection<Thread> getWaitingThreads() {
+            if (!isHeldExclusively())
+                throw new IllegalMonitorStateException();
+            ArrayList<Thread> list = new ArrayList<Thread>();
+            for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+                if (w.waitStatus == Node.CONDITION) {
+                    Thread t = w.thread;
+                    if (t != null)
+                        list.add(t);
+                }
+            }
+            return list;
+        }
+    }
+
+    /**
+     * Setup to support compareAndSet. We need to natively implement
+     * this here: For the sake of permitting future enhancements, we
+     * cannot explicitly subclass AtomicLong, which would be
+     * efficient and useful otherwise. So, as the lesser of evils, we
+     * natively implement using hotspot intrinsics API. And while we
+     * are at it, we do the same for other CASable fields (which could
+     * otherwise be done with atomic field updaters).
+     */
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final long stateOffset;
+    private static final long headOffset;
+    private static final long tailOffset;
+    private static final long waitStatusOffset;
+    private static final long nextOffset;
+
+    static {
+        try {
+            stateOffset = unsafe.objectFieldOffset
+                (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
+            headOffset = unsafe.objectFieldOffset
+                (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
+            tailOffset = unsafe.objectFieldOffset
+                (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
+            waitStatusOffset = unsafe.objectFieldOffset
+                (Node.class.getDeclaredField("waitStatus"));
+            nextOffset = unsafe.objectFieldOffset
+                (Node.class.getDeclaredField("next"));
+
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+
+    /**
+     * CAS head field. Used only by enq.
+     */
+    private final boolean compareAndSetHead(Node update) {
+        return unsafe.compareAndSwapObject(this, headOffset, null, update);
+    }
+
+    /**
+     * CAS tail field. Used only by enq.
+     */
+    private final boolean compareAndSetTail(Node expect, Node update) {
+        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
+    }
+
+    /**
+     * CAS waitStatus field of a node.
+     */
+    private final static boolean compareAndSetWaitStatus(Node node,
+                                                         int expect,
+                                                         int update) {
+        return unsafe.compareAndSwapInt(node, waitStatusOffset,
+                                        expect, update);
+    }
+
+    /**
+     * CAS next field of a node.
+     */
+    private final static boolean compareAndSetNext(Node node,
+                                                   Node expect,
+                                                   Node update) {
+        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
+    }
+}
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 8b9821e..66498e3 100644
--- a/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/concurrent/src/main/java/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -94,6 +94,12 @@
  * means of using this class. All other methods are declared
  * <tt>final</tt> because they cannot be independently varied.
  *
+ * <p>You may also find the inherited methods from {@link
+ * AbstractOwnableSynchronizer} useful to keep track of the thread
+ * owning an exclusive synchronizer.  You are encouraged to use them
+ * -- this enables monitoring and diagnostic tools to assist users in
+ * determining which threads hold locks.
+ *
  * <p>Even though this class is based on an internal FIFO queue, it
  * does not automatically enforce FIFO acquisition policies.  The core
  * of exclusive synchronization takes the form:
@@ -119,8 +125,9 @@
  * disable barging by internally invoking one or more of the inspection
  * methods, thereby providing a <em>fair</em> FIFO acquisition order.
  * In particular, most fair synchronizers can define <tt>tryAcquire</tt>
- * to return <tt>false</tt> if predecessors are queued.  Other variations
- * are possible.
+ * to return <tt>false</tt> if {@link #hasQueuedPredecessors} (a method
+ * specifically designed to be used by fair synchronizers) returns
+ * <tt>true</tt>.  Other variations are possible.
  *
  * <p>Throughput and scalability are generally highest for the
  * default barging (also known as <em>greedy</em>,
@@ -152,7 +159,10 @@
  *
  * <p>Here is a non-reentrant mutual exclusion lock class that uses
  * the value zero to represent the unlocked state, and one to
- * represent the locked state. It also supports conditions and exposes
+ * represent the locked state. While a non-reentrant lock
+ * does not strictly require recording of the current owner
+ * thread, this class does so anyway to make usage easier to monitor.
+ * It also supports conditions and exposes
  * one of the instrumentation methods:
  *
  * <pre>
@@ -168,13 +178,18 @@
  *     // Acquire the lock if state is zero
  *     public boolean tryAcquire(int acquires) {
  *       assert acquires == 1; // Otherwise unused
- *       return compareAndSetState(0, 1);
+ *       if (compareAndSetState(0, 1)) {
+ *         setExclusiveOwnerThread(Thread.currentThread());
+ *         return true;
+ *       }
+ *       return false;
  *     }
  *
  *     // Release the lock by setting state to zero
  *     protected boolean tryRelease(int releases) {
  *       assert releases == 1; // Otherwise unused
  *       if (getState() == 0) throw new IllegalMonitorStateException();
+ *       setExclusiveOwnerThread(null);
  *       setState(0);
  *       return true;
  *     }
@@ -787,7 +802,7 @@
      * @return {@code true} if interrupted
      */
     private final boolean parkAndCheckInterrupt() {
-        LockSupport.park();
+        LockSupport.park(this);
         return Thread.interrupted();
     }
 
@@ -882,7 +897,7 @@
                     return false;
                 if (shouldParkAfterFailedAcquire(p, node) &&
                     nanosTimeout > spinForTimeoutThreshold)
-                    LockSupport.parkNanos(nanosTimeout);
+                    LockSupport.parkNanos(this, nanosTimeout);
                 long now = System.nanoTime();
                 nanosTimeout -= now - lastTime;
                 lastTime = now;
@@ -986,7 +1001,7 @@
                     return false;
                 if (shouldParkAfterFailedAcquire(p, node) &&
                     nanosTimeout > spinForTimeoutThreshold)
-                    LockSupport.parkNanos(nanosTimeout);
+                    LockSupport.parkNanos(this, nanosTimeout);
                 long now = System.nanoTime();
                 nanosTimeout -= now - lastTime;
                 lastTime = now;
@@ -1458,8 +1473,10 @@
      * @return {@code true} if there is a queued thread preceding the
      *         current thread, and {@code false} if the current thread
      *         is at the head of the queue or the queue is empty
+     * @since 1.7
+     * @hide
      */
-    final boolean hasQueuedPredecessors() {
+    public final boolean hasQueuedPredecessors() {
         // The correctness of this depends on head being initialized
         // before tail and on head.next being accurate if the current
         // thread is first in queue.
@@ -1926,7 +1943,7 @@
             int savedState = fullyRelease(node);
             boolean interrupted = false;
             while (!isOnSyncQueue(node)) {
-                LockSupport.park();
+                LockSupport.park(this);
                 if (Thread.interrupted())
                     interrupted = true;
             }
@@ -1993,7 +2010,7 @@
             int savedState = fullyRelease(node);
             int interruptMode = 0;
             while (!isOnSyncQueue(node)) {
-                LockSupport.park();
+                LockSupport.park(this);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
             }
@@ -2040,7 +2057,7 @@
                     transferAfterCancelledWait(node);
                     break;
                 }
-                LockSupport.parkNanos(nanosTimeout);
+                LockSupport.parkNanos(this, nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
 
@@ -2094,7 +2111,7 @@
                     timedout = transferAfterCancelledWait(node);
                     break;
                 }
-                LockSupport.parkUntil(abstime);
+                LockSupport.parkUntil(this, abstime);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
             }
@@ -2146,7 +2163,7 @@
                     break;
                 }
                 if (nanosTimeout >= spinForTimeoutThreshold)
-                    LockSupport.parkNanos(nanosTimeout);
+                    LockSupport.parkNanos(this, nanosTimeout);
                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                     break;
                 long now = System.nanoTime();
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/Condition.java b/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
index 03be58f..d75de51 100644
--- a/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
+++ b/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
@@ -421,6 +421,15 @@
      * <p>If any threads are waiting on this condition then one
      * is selected for waking up. That thread must then re-acquire the
      * lock before returning from {@code await}.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>The current thread is assumed to hold the lock associated
+     * with this {@code Condition} when this method is called.  It is
+     * up to the implementation to determine if this is the case and
+     * if not, how to respond. Typically, an exception will be thrown
+     * (such as {@link IllegalMonitorStateException}) and the
+     * implementation must document that fact.
      */
     void signal();
 
@@ -430,6 +439,15 @@
      * <p>If any threads are waiting on this condition then they are
      * all woken up. Each thread must re-acquire the lock before it can
      * return from {@code await}.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>The current thread is assumed to hold the lock associated
+     * with this {@code Condition} when this method is called.  It is
+     * up to the implementation to determine if this is the case and
+     * if not, how to respond. Typically, an exception will be thrown
+     * (such as {@link IllegalMonitorStateException}) and the
+     * implementation must document that fact.
      */
     void signalAll();
 }
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java b/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
index b55b874..ac9a94f 100644
--- a/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
+++ b/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
@@ -36,6 +36,15 @@
  * spinning, but must be paired with an {@code unpark} to be
  * effective.
  *
+ * <p>The three forms of {@code park} each also support a
+ * {@code blocker} object parameter. This object is recorded while
+ * the thread is blocked to permit monitoring and diagnostic tools to
+ * identify the reasons that threads are blocked. (Such tools may
+ * access blockers using method {@link #getBlocker}.) The use of these
+ * forms rather than the original forms without this parameter is
+ * strongly encouraged. The normal argument to supply as a
+ * {@code blocker} within a lock implementation is {@code this}.
+ *
  * <p>These methods are designed to be used as tools for creating
  * higher-level synchronization utilities, and are not in themselves
  * useful for most concurrency control applications.  The {@code park}
@@ -78,13 +87,25 @@
  *   }
  * }}</pre>
  */
-@SuppressWarnings("all")
+
 public class LockSupport {
     private LockSupport() {} // Cannot be instantiated.
 
-    // BEGIN android-changed
-    private static final Unsafe unsafe = UnsafeAccess.THE_ONE;
-    // END android-changed
+    // Hotspot implementation via intrinsics API
+    private static final Unsafe unsafe = UnsafeAccess.THE_ONE; // android-changed
+    private static final long parkBlockerOffset;
+
+    static {
+        try {
+            parkBlockerOffset = unsafe.objectFieldOffset
+                (java.lang.Thread.class.getDeclaredField("parkBlocker"));
+        } catch (Exception ex) { throw new Error(ex); }
+    }
+
+    private static void setBlocker(Thread t, Object arg) {
+        // Even though volatile, hotspot doesn't need a write barrier here.
+        unsafe.putObject(t, parkBlockerOffset, arg);
+    }
 
     /**
      * Makes available the permit for the given thread, if it
@@ -106,6 +127,136 @@
      * Disables the current thread for thread scheduling purposes unless the
      * permit is available.
      *
+     * <p>If the permit is available then it is consumed and the call returns
+     * immediately; otherwise
+     * the current thread becomes disabled for thread scheduling
+     * purposes and lies dormant until one of three things happens:
+     *
+     * <ul>
+     * <li>Some other thread invokes {@link #unpark unpark} with the
+     * current thread as the target; or
+     *
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+     * the current thread; or
+     *
+     * <li>The call spuriously (that is, for no reason) returns.
+     * </ul>
+     *
+     * <p>This method does <em>not</em> report which of these caused the
+     * method to return. Callers should re-check the conditions which caused
+     * the thread to park in the first place. Callers may also determine,
+     * for example, the interrupt status of the thread upon return.
+     *
+     * @param blocker the synchronization object responsible for this
+     *        thread parking
+     * @since 1.6
+     */
+    public static void park(Object blocker) {
+        Thread t = Thread.currentThread();
+        setBlocker(t, blocker);
+        unsafe.park(false, 0L);
+        setBlocker(t, null);
+    }
+
+    /**
+     * Disables the current thread for thread scheduling purposes, for up to
+     * the specified waiting time, unless the permit is available.
+     *
+     * <p>If the permit is available then it is consumed and the call
+     * returns immediately; otherwise the current thread becomes disabled
+     * for thread scheduling purposes and lies dormant until one of four
+     * things happens:
+     *
+     * <ul>
+     * <li>Some other thread invokes {@link #unpark unpark} with the
+     * current thread as the target; or
+     *
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current
+     * thread; or
+     *
+     * <li>The specified waiting time elapses; or
+     *
+     * <li>The call spuriously (that is, for no reason) returns.
+     * </ul>
+     *
+     * <p>This method does <em>not</em> report which of these caused the
+     * method to return. Callers should re-check the conditions which caused
+     * the thread to park in the first place. Callers may also determine,
+     * for example, the interrupt status of the thread, or the elapsed time
+     * upon return.
+     *
+     * @param blocker the synchronization object responsible for this
+     *        thread parking
+     * @param nanos the maximum number of nanoseconds to wait
+     * @since 1.6
+     */
+    public static void parkNanos(Object blocker, long nanos) {
+        if (nanos > 0) {
+            Thread t = Thread.currentThread();
+            setBlocker(t, blocker);
+            unsafe.park(false, nanos);
+            setBlocker(t, null);
+        }
+    }
+
+    /**
+     * Disables the current thread for thread scheduling purposes, until
+     * the specified deadline, unless the permit is available.
+     *
+     * <p>If the permit is available then it is consumed and the call
+     * returns immediately; otherwise the current thread becomes disabled
+     * for thread scheduling purposes and lies dormant until one of four
+     * things happens:
+     *
+     * <ul>
+     * <li>Some other thread invokes {@link #unpark unpark} with the
+     * current thread as the target; or
+     *
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread; or
+     *
+     * <li>The specified deadline passes; or
+     *
+     * <li>The call spuriously (that is, for no reason) returns.
+     * </ul>
+     *
+     * <p>This method does <em>not</em> report which of these caused the
+     * method to return. Callers should re-check the conditions which caused
+     * the thread to park in the first place. Callers may also determine,
+     * for example, the interrupt status of the thread, or the current time
+     * upon return.
+     *
+     * @param blocker the synchronization object responsible for this
+     *        thread parking
+     * @param deadline the absolute time, in milliseconds from the Epoch,
+     *        to wait until
+     * @since 1.6
+     */
+    public static void parkUntil(Object blocker, long deadline) {
+        Thread t = Thread.currentThread();
+        setBlocker(t, blocker);
+        unsafe.park(true, deadline);
+        setBlocker(t, null);
+    }
+
+    /**
+     * Returns the blocker object supplied to the most recent
+     * invocation of a park method that has not yet unblocked, or null
+     * if not blocked.  The value returned is just a momentary
+     * snapshot -- the thread may have since unblocked or blocked on a
+     * different blocker object.
+     *
+     * @return the blocker
+     * @since 1.6
+     */
+    public static Object getBlocker(Thread t) {
+        return unsafe.getObjectVolatile(t, parkBlockerOffset);
+    }
+
+    /**
+     * Disables the current thread for thread scheduling purposes unless the
+     * permit is available.
+     *
      * <p>If the permit is available then it is consumed and the call
      * returns immediately; otherwise the current thread becomes disabled
      * for thread scheduling purposes and lies dormant until one of three
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java b/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
index c923944..bfaff06 100644
--- a/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
+++ b/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
@@ -1161,6 +1161,32 @@
                                        "[Locked by thread " + o.getName() + "]");
         }
 
+        /**
+         * Queries if this write lock is held by the current thread.
+         * Identical in effect to {@link
+         * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
+         *
+         * @return {@code true} if the current thread holds this lock and
+         *         {@code false} otherwise
+         * @since 1.6
+         */
+        public boolean isHeldByCurrentThread() {
+            return sync.isHeldExclusively();
+        }
+
+        /**
+         * Queries the number of holds on this write lock by the current
+         * thread.  A thread has a hold on a lock for each lock action
+         * that is not matched by an unlock action.  Identical in effect
+         * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
+         *
+         * @return the number of holds on this lock by the current thread,
+         *         or zero if this lock is not held by the current thread
+         * @since 1.6
+         */
+        public int getHoldCount() {
+            return sync.getWriteHoldCount();
+        }
     }
 
     // Instrumentation and status
@@ -1236,6 +1262,19 @@
     }
 
     /**
+     * Queries the number of reentrant read holds on this lock by the
+     * current thread.  A reader thread has a hold on a lock for
+     * each lock action that is not matched by an unlock action.
+     *
+     * @return the number of holds on the read lock by the current thread,
+     *         or zero if the read lock is not held by the current thread
+     * @since 1.6
+     */
+    public int getReadHoldCount() {
+        return sync.getReadHoldCount();
+    }
+
+    /**
      * Returns a collection containing threads that may be waiting to
      * acquire the write lock.  Because the actual set of threads may
      * change dynamically while constructing this result, the returned
diff --git a/concurrent/src/main/java/java/util/concurrent/locks/package-info.java b/concurrent/src/main/java/java/util/concurrent/locks/package-info.java
index 801ee9b..860acdd 100644
--- a/concurrent/src/main/java/java/util/concurrent/locks/package-info.java
+++ b/concurrent/src/main/java/java/util/concurrent/locks/package-info.java
@@ -34,10 +34,16 @@
  *
  * <p>The {@link java.util.concurrent.locks.AbstractQueuedSynchronizer}
  * class serves as a useful superclass for defining locks and other
- * synchronizers that rely on queuing blocked threads. The
- * {@link java.util.concurrent.locks.LockSupport} class provides
- * lower-level blocking and unblocking support that is useful for those
- * developers implementing their own customized lock classes.
+ * synchronizers that rely on queuing blocked threads.  The {@link
+ * java.util.concurrent.locks.AbstractQueuedLongSynchronizer} class
+ * provides the same functionality but extends support to 64 bits of
+ * synchronization state.  Both extend class {@link
+ * java.util.concurrent.locks.AbstractOwnableSynchronizer}, a simple
+ * class that helps record the thread currently holding exclusive
+ * synchronization.  The {@link java.util.concurrent.locks.LockSupport}
+ * class provides lower-level blocking and unblocking support that is
+ * useful for those developers implementing their own customized lock
+ * classes.
  *
  * @since 1.5
  */
diff --git a/concurrent/src/main/java/java/util/concurrent/package-info.java b/concurrent/src/main/java/java/util/concurrent/package-info.java
index d49ef252..dd3a22d 100644
--- a/concurrent/src/main/java/java/util/concurrent/package-info.java
+++ b/concurrent/src/main/java/java/util/concurrent/package-info.java
@@ -41,6 +41,10 @@
  * a function, allows determination of whether execution has
  * completed, and provides a means to cancel execution.
  *
+ * A {@link java.util.concurrent.RunnableFuture} is a {@code Future}
+ * that possesses a {@code run} method that upon execution,
+ * sets its results.
+ *
  * <p>
  *
  * <b>Implementations.</b>
@@ -59,6 +63,13 @@
  * assists in coordinating the processing of groups of
  * asynchronous tasks.
  *
+ * <p>Class {@link java.util.concurrent.ForkJoinPool} provides an
+ * Executor primarily designed for processing instances of {@link
+ * java.util.concurrent.ForkJoinTask} and its subclasses.  These
+ * classes employ a work-stealing scheduler that attains high
+ * throughput for tasks conforming to restrictions that often hold in
+ * computation-intensive parallel processing.
+ *
  * <h2>Queues</h2>
  *
  * The {@link java.util.concurrent.ConcurrentLinkedQueue} class
@@ -77,6 +88,18 @@
  * for producer-consumer, messaging, parallel tasking, and
  * related concurrent designs.
  *
+ * <p> Extended interface {@link java.util.concurrent.TransferQueue},
+ * and implementation {@link java.util.concurrent.LinkedTransferQueue}
+ * introduce a synchronous {@code transfer} method (along with related
+ * features) in which a producer may optionally block awaiting its
+ * consumer.
+ *
+ * <p>The {@link java.util.concurrent.BlockingDeque} interface
+ * extends {@code BlockingQueue} to support both FIFO and LIFO
+ * (stack-based) operations.
+ * Class {@link java.util.concurrent.LinkedBlockingDeque}
+ * provides an implementation.
+ *
  * <h2>Timing</h2>
  *
  * The {@link java.util.concurrent.TimeUnit} class provides
@@ -97,28 +120,45 @@
  *
  * <h2>Synchronizers</h2>
  *
- * Four classes aid common special-purpose synchronization idioms.
- * {@link java.util.concurrent.Semaphore} is a classic concurrency tool.
- * {@link java.util.concurrent.CountDownLatch} is a very simple yet very
- * common utility for blocking until a given number of signals, events,
- * or conditions hold.  A {@link java.util.concurrent.CyclicBarrier} is a
- * resettable multiway synchronization point useful in some styles of
- * parallel programming.  An {@link java.util.concurrent.Exchanger} allows
- * two threads to exchange objects at a rendezvous point, and is useful
- * in several pipeline designs.
+ * Five classes aid common special-purpose synchronization idioms.
+ * <ul>
+ *
+ * <li>{@link java.util.concurrent.Semaphore} is a classic concurrency tool.
+ *
+ * <li>{@link java.util.concurrent.CountDownLatch} is a very simple yet
+ * very common utility for blocking until a given number of signals,
+ * events, or conditions hold.
+ *
+ * <li>A {@link java.util.concurrent.CyclicBarrier} is a resettable
+ * multiway synchronization point useful in some styles of parallel
+ * programming.
+ *
+ * <li>A {@link java.util.concurrent.Phaser} provides
+ * a more flexible form of barrier that may be used to control phased
+ * computation among multiple threads.
+ *
+ * <li>An {@link java.util.concurrent.Exchanger} allows two threads to
+ * exchange objects at a rendezvous point, and is useful in several
+ * pipeline designs.
+ *
+ * </ul>
  *
  * <h2>Concurrent Collections</h2>
  *
  * Besides Queues, this package supplies Collection implementations
  * designed for use in multithreaded contexts:
  * {@link java.util.concurrent.ConcurrentHashMap},
+ * {@link java.util.concurrent.ConcurrentSkipListMap},
+ * {@link java.util.concurrent.ConcurrentSkipListSet},
  * {@link java.util.concurrent.CopyOnWriteArrayList}, and
  * {@link java.util.concurrent.CopyOnWriteArraySet}.
  * When many threads are expected to access a given collection, a
  * {@code ConcurrentHashMap} is normally preferable to a synchronized
- * {@code HashMap}. A {@code CopyOnWriteArrayList} is preferable to a
- * synchronized {@code ArrayList} when the expected number of reads and
- * traversals greatly outnumber the number of updates to a list.
+ * {@code HashMap}, and a {@code ConcurrentSkipListMap} is normally
+ * preferable to a synchronized {@code TreeMap}.
+ * A {@code CopyOnWriteArrayList} is preferable to a synchronized
+ * {@code ArrayList} when the expected number of reads and traversals
+ * greatly outnumber the number of updates to a list.
 
  * <p>The "Concurrent" prefix used with some classes in this package
  * is a shorthand indicating several differences from similar
@@ -216,7 +256,8 @@
  *   in each thread <i>happen-before</i> those subsequent to the
  *   corresponding {@code exchange()} in another thread.
  *
- *   <li>Actions prior to calling {@code CyclicBarrier.await}
+ *   <li>Actions prior to calling {@code CyclicBarrier.await} and
+ *   {@code Phaser.awaitAdvance} (as well as its variants)
  *   <i>happen-before</i> actions performed by the barrier action, and
  *   actions performed by the barrier action <i>happen-before</i> actions
  *   subsequent to a successful return from the corresponding {@code await}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java
index 99a007a..a8db7ad 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractExecutorServiceTest.java
@@ -2,27 +2,25 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.math.BigInteger;
 import java.security.*;
 
-public class AbstractExecutorServiceTest extends JSR166TestCase{
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class AbstractExecutorServiceTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(AbstractExecutorServiceTest.class);
     }
 
-    /** 
+    /**
      * A no-frills implementation of AbstractExecutorService, designed
      * to test the submit methods only.
      */
@@ -39,188 +37,106 @@
     /**
      * execute(runnable) runs it to completion
      */
-    public void testExecuteRunnable() {
-        try {
-            ExecutorService e = new DirectExecutorService();
-            TrackedShortRunnable task = new TrackedShortRunnable();
-            assertFalse(task.done);
-            Future<?> future = e.submit(task);
-            future.get();
-            assertTrue(task.done);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
+    public void testExecuteRunnable() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        TrackedShortRunnable task = new TrackedShortRunnable();
+        assertFalse(task.done);
+        Future<?> future = e.submit(task);
+        future.get();
+        assertTrue(task.done);
     }
 
 
     /**
      * Completed submit(callable) returns result
      */
-    public void testSubmitCallable() {
-        try {
-            ExecutorService e = new DirectExecutorService();
-            Future<String> future = e.submit(new StringTask());
-            String result = future.get();
-            assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
+    public void testSubmitCallable() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        Future<String> future = e.submit(new StringTask());
+        String result = future.get();
+        assertSame(TEST_STRING, result);
     }
 
     /**
      * Completed submit(runnable) returns successfully
      */
-    public void testSubmitRunnable() {
-        try {
-            ExecutorService e = new DirectExecutorService();
-            Future<?> future = e.submit(new NoOpRunnable());
-            future.get();
-            assertTrue(future.isDone());
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
+    public void testSubmitRunnable() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        Future<?> future = e.submit(new NoOpRunnable());
+        future.get();
+        assertTrue(future.isDone());
     }
 
     /**
      * Completed submit(runnable, result) returns result
      */
-    public void testSubmitRunnable2() {
-        try {
-            ExecutorService e = new DirectExecutorService();
-            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
-            String result = future.get();
-            assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
+    public void testSubmitRunnable2() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+        String result = future.get();
+        assertSame(TEST_STRING, result);
     }
 
 
     /**
-     * A submitted privileged action to completion
+     * A submitted privileged action runs to completion
      */
-    public void testSubmitPrivilegedAction() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            policy.addPermission(new RuntimePermission("getContextClassLoader"));
-            policy.addPermission(new RuntimePermission("setContextClassLoader"));
-            Policy.setPolicy(policy);
-        } catch(AccessControlException ok) {
-            return;
-        }
-        try {
-            ExecutorService e = new DirectExecutorService();
-            Future future = e.submit(Executors.callable(new PrivilegedAction() {
+    public void testSubmitPrivilegedAction() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                ExecutorService e = new DirectExecutorService();
+                Future future = e.submit(Executors.callable(new PrivilegedAction() {
                     public Object run() {
                         return TEST_STRING;
                     }}));
 
-            Object result = future.get();
-            assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
-        finally {
-            try {
-                Policy.setPolicy(savedPolicy);
-            } catch(AccessControlException ok) {
-                return;
-            }
-        }
+                assertSame(TEST_STRING, future.get());
+            }};
+
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"),
+                           new RuntimePermission("modifyThread"));
     }
 
     /**
-     * A submitted a privileged exception action runs to completion
+     * A submitted privileged exception action runs to completion
      */
-    public void testSubmitPrivilegedExceptionAction() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            policy.addPermission(new RuntimePermission("getContextClassLoader"));
-            policy.addPermission(new RuntimePermission("setContextClassLoader"));
-            Policy.setPolicy(policy);
-        } catch(AccessControlException ok) {
-            return;
-        }
-
-        try {
-            ExecutorService e = new DirectExecutorService();
-            Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
+    public void testSubmitPrivilegedExceptionAction() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                ExecutorService e = new DirectExecutorService();
+                Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
                     public Object run() {
                         return TEST_STRING;
                     }}));
 
-            Object result = future.get();
-            assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
-        finally {
-            Policy.setPolicy(savedPolicy);
-        }
+                assertSame(TEST_STRING, future.get());
+            }};
+
+        runWithPermissions(r);
     }
 
     /**
      * A submitted failed privileged exception action reports exception
      */
-    public void testSubmitFailedPrivilegedExceptionAction() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            policy.addPermission(new RuntimePermission("getContextClassLoader"));
-            policy.addPermission(new RuntimePermission("setContextClassLoader"));
-            Policy.setPolicy(policy);
-        } catch(AccessControlException ok) {
-            return;
-        }
-
-
-        try {
-            ExecutorService e = new DirectExecutorService();
-            Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
+    public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                ExecutorService e = new DirectExecutorService();
+                Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
                     public Object run() throws Exception {
                         throw new IndexOutOfBoundsException();
                     }}));
 
-            Object result = future.get();
-            shouldThrow();
-        }
-        catch (ExecutionException success) {
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
-        }
-        finally {
-            Policy.setPolicy(savedPolicy);
-        }
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
+                }}};
+
+        runWithPermissions(r);
     }
 
     /**
@@ -229,15 +145,9 @@
     public void testExecuteNullRunnable() {
         try {
             ExecutorService e = new DirectExecutorService();
-            TrackedShortRunnable task = null;
-            Future<?> future = e.submit(task);
+            e.submit((Runnable) null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -247,15 +157,9 @@
     public void testSubmitNullCallable() {
         try {
             ExecutorService e = new DirectExecutorService();
-            StringTask t = null;
-            Future<String> future = e.submit(t);
+            e.submit((Callable) null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -263,15 +167,22 @@
      * executor is saturated.
      */
     public void testExecute1() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
+        ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   60, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
         try {
-
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 2; ++i)
                 p.submit(new MediumRunnable());
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.submit(new MediumRunnable());
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
             }
-            shouldThrow();
-        } catch(RejectedExecutionException success){}
-        joinPool(p);
+        } finally {
+            joinPool(p);
+        }
     }
 
     /**
@@ -279,14 +190,22 @@
      * if executor is saturated.
      */
     public void testExecute2() {
-         ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
+        ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   60, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
         try {
-            for(int i = 0; i < 5; ++i) {
-                p.submit(new SmallCallable());
+            for (int i = 0; i < 2; ++i)
+                p.submit(new MediumRunnable());
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.submit(new SmallCallable());
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
             }
-            shouldThrow();
-        } catch(RejectedExecutionException e){}
-        joinPool(p);
+        } finally {
+            joinPool(p);
+        }
     }
 
 
@@ -294,75 +213,43 @@
      *  Blocking on submit(callable) throws InterruptedException if
      *  caller interrupted.
      */
-    public void testInterruptedSubmit() {
+    public void testInterruptedSubmit() throws InterruptedException {
         final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        p.submit(new Callable<Object>() {
-                                public Object call() {
-                                    try {
-                                        Thread.sleep(MEDIUM_DELAY_MS);
-                                        shouldThrow();
-                                    } catch(InterruptedException e){
-                                    }
-                                    return null;
-                                }
-                            }).get();
-                    } catch(InterruptedException success){
-                    } catch(Exception e) {
-                        unexpectedException();
-                    }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws Exception {
+                p.submit(new CheckedCallable<Object>() {
+                             public Object realCall()
+                                 throws InterruptedException {
+                                 Thread.sleep(SMALL_DELAY_MS);
+                                 return null;
+                             }}).get();
+            }});
 
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
         joinPool(p);
     }
 
     /**
-     *  get of submitted callable throws Exception if callable
+     *  get of submitted callable throws InterruptedException if callable
      *  interrupted
      */
-    public void testSubmitIE() {
-        final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testSubmitIE() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   60, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
 
-        final Callable c = new Callable() {
-                public Object call() {
-                    try {
-                        p.submit(new SmallCallable()).get();
-                        shouldThrow();
-                    } catch(InterruptedException e){}
-                    catch(RejectedExecutionException e2){}
-                    catch(ExecutionException e3){}
-                    return Boolean.TRUE;
-                }
-            };
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws Exception {
+                p.submit(new SmallCallable()).get();
+            }});
 
-
-
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.call();
-                    } catch(Exception e){}
-                }
-          });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
-
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
         joinPool(p);
     }
 
@@ -370,26 +257,20 @@
      *  get of submit(callable) throws ExecutionException if callable
      *  throws exception
      */
-    public void testSubmitEE() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testSubmitEE() throws InterruptedException {
+        ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   60, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+
+        Callable c = new Callable() {
+            public Object call() { return 5/0; }};
 
         try {
-            Callable c = new Callable() {
-                    public Object call() {
-                        int i = 5/0;
-                        return Boolean.TRUE;
-                    }
-                };
-
-            for(int i =0; i < 5; i++){
-                p.submit(c).get();
-            }
-
+            p.submit(c).get();
             shouldThrow();
-        }
-        catch(ExecutionException success){
-        } catch(Exception e) {
-            unexpectedException();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof ArithmeticException);
         }
         joinPool(p);
     }
@@ -397,13 +278,13 @@
     /**
      * invokeAny(null) throws NPE
      */
-    public void testInvokeAny1() {
+    public void testInvokeAny1()
+        throws InterruptedException, ExecutionException {
         ExecutorService e = new DirectExecutorService();
         try {
             e.invokeAny(null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -412,13 +293,13 @@
     /**
      * invokeAny(empty collection) throws IAE
      */
-    public void testInvokeAny2() {
+    public void testInvokeAny2()
+        throws InterruptedException, ExecutionException {
         ExecutorService e = new DirectExecutorService();
         try {
             e.invokeAny(new ArrayList<Callable<String>>());
+            shouldThrow();
         } catch (IllegalArgumentException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -427,17 +308,16 @@
     /**
      * invokeAny(c) throws NPE if c has null elements
      */
-    public void testInvokeAny3() {
+    public void testInvokeAny3() throws Exception {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<Integer>> l = new ArrayList<Callable<Integer>>();
+        l.add(new Callable<Integer>() {
+                  public Integer call() { return 5/0; }});
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
             e.invokeAny(l);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            ex.printStackTrace();
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -446,15 +326,15 @@
     /**
      * invokeAny(c) throws ExecutionException if no task in c completes
      */
-    public void testInvokeAny4() {
+    public void testInvokeAny4() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
             e.invokeAny(l);
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -463,17 +343,14 @@
     /**
      * invokeAny(c) returns result of some task in c if at least one completes
      */
-    public void testInvokeAny5() {
+    public void testInvokeAny5() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -482,13 +359,12 @@
     /**
      * invokeAll(null) throws NPE
      */
-    public void testInvokeAll1() {
+    public void testInvokeAll1() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
         try {
             e.invokeAll(null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -497,13 +373,11 @@
     /**
      * invokeAll(empty collection) returns empty collection
      */
-    public void testInvokeAll2() {
+    public void testInvokeAll2() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
         try {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -512,16 +386,15 @@
     /**
      * invokeAll(c) throws NPE if c has null elements
      */
-    public void testInvokeAll3() {
+    public void testInvokeAll3() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
             e.invokeAll(l);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -530,18 +403,19 @@
     /**
      * get of returned element of invokeAll(c) throws exception on failed task
      */
-    public void testInvokeAll4() {
+    public void testInvokeAll4() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new NPETask());
-            List<Future<String>> result = e.invokeAll(l);
-            assertEquals(1, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                it.next().get();
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         } finally {
             joinPool(e);
         }
@@ -550,19 +424,16 @@
     /**
      * invokeAll(c) returns results of all completed tasks in c
      */
-    public void testInvokeAll5() {
+    public void testInvokeAll5() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l);
-            assertEquals(2, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                assertSame(TEST_STRING, it.next().get());
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
         } finally {
             joinPool(e);
         }
@@ -572,13 +443,12 @@
     /**
      * timed invokeAny(null) throws NPE
      */
-    public void testTimedInvokeAny1() {
+    public void testTimedInvokeAny1() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -587,15 +457,14 @@
     /**
      * timed invokeAny(null time unit) throws NPE
      */
-    public void testTimedInvokeAnyNullTimeUnit() {
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
             e.invokeAny(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -604,13 +473,12 @@
     /**
      * timed invokeAny(empty collection) throws IAE
      */
-    public void testTimedInvokeAny2() {
+    public void testTimedInvokeAny2() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (IllegalArgumentException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -619,17 +487,16 @@
     /**
      * timed invokeAny(c) throws NPE if c has null elements
      */
-    public void testTimedInvokeAny3() {
+    public void testTimedInvokeAny3() throws Exception {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<Integer>> l = new ArrayList<Callable<Integer>>();
+        l.add(new Callable<Integer>() {
+                  public Integer call() { return 5/0; }});
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
-            e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            ex.printStackTrace();
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -638,15 +505,15 @@
     /**
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
-    public void testTimedInvokeAny4() {
+    public void testTimedInvokeAny4() throws Exception {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
-            e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -655,17 +522,14 @@
     /**
      * timed invokeAny(c) returns result of some task in c
      */
-    public void testTimedInvokeAny5() {
+    public void testTimedInvokeAny5() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -674,13 +538,12 @@
     /**
      * timed invokeAll(null) throws NPE
      */
-    public void testTimedInvokeAll1() {
+    public void testTimedInvokeAll1() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
         try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -689,15 +552,14 @@
     /**
      * timed invokeAll(null time unit) throws NPE
      */
-    public void testTimedInvokeAllNullTimeUnit() {
+    public void testTimedInvokeAllNullTimeUnit() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
             e.invokeAll(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -706,13 +568,11 @@
     /**
      * timed invokeAll(empty collection) returns empty collection
      */
-    public void testTimedInvokeAll2() {
+    public void testTimedInvokeAll2() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
         try {
-            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -721,16 +581,15 @@
     /**
      * timed invokeAll(c) throws NPE if c has null elements
      */
-    public void testTimedInvokeAll3() {
+    public void testTimedInvokeAll3() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
-            e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -739,18 +598,20 @@
     /**
      * get of returned element of invokeAll(c) throws exception on failed task
      */
-    public void testTimedInvokeAll4() {
+    public void testTimedInvokeAll4() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new NPETask());
-            List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(1, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                it.next().get();
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         } finally {
             joinPool(e);
         }
@@ -759,19 +620,17 @@
     /**
      * timed invokeAll(c) returns results of all completed tasks in c
      */
-    public void testTimedInvokeAll5() {
+    public void testTimedInvokeAll5() throws Exception {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(2, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                assertSame(TEST_STRING, it.next().get());
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
         } finally {
             joinPool(e);
         }
@@ -780,16 +639,17 @@
     /**
      * timed invokeAll cancels tasks not completed by timeout
      */
-    public void testTimedInvokeAll6() {
+    public void testTimedInvokeAll6() throws InterruptedException {
         ExecutorService e = new DirectExecutorService();
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l, SMALL_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(3, result.size());
-            Iterator<Future<String>> it = result.iterator(); 
+            List<Future<String>> futures =
+                e.invokeAll(l, SMALL_DELAY_MS, MILLISECONDS);
+            assertEquals(3, futures.size());
+            Iterator<Future<String>> it = futures.iterator();
             Future<String> f1 = it.next();
             Future<String> f2 = it.next();
             Future<String> f3 = it.next();
@@ -798,8 +658,6 @@
             assertTrue(f2.isDone());
             assertTrue(f3.isDone());
             assertTrue(f3.isCancelled());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java
index 0251390..9bb206b 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueueTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
@@ -15,17 +15,14 @@
 import java.io.*;
 
 public class AbstractQueueTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AbstractQueueTest.class);
     }
 
     static class Succeed extends AbstractQueue<Integer> {
-        public boolean offer(Integer x) { 
+        public boolean offer(Integer x) {
             if (x == null) throw new NullPointerException();
-            return true; 
+            return true;
         }
         public Integer peek() { return one; }
         public Integer poll() { return one; }
@@ -34,9 +31,9 @@
     }
 
     static class Fail extends AbstractQueue<Integer> {
-        public boolean offer(Integer x) { 
+        public boolean offer(Integer x) {
             if (x == null) throw new NullPointerException();
-            return false; 
+            return false;
         }
         public Integer peek() { return null; }
         public Integer poll() { return null; }
@@ -60,8 +57,7 @@
         try {
             q.add(one);
             shouldThrow();
-        } catch (IllegalStateException success) {
-        }
+        } catch (IllegalStateException success) {}
     }
 
     /**
@@ -72,8 +68,7 @@
         try {
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -92,8 +87,7 @@
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success) {
-        }
+        } catch (NoSuchElementException success) {}
     }
 
 
@@ -113,8 +107,7 @@
         try {
             q.element();
             shouldThrow();
-        } catch (NoSuchElementException success) {
-        }
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -125,8 +118,7 @@
             Succeed q = new Succeed();
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -137,8 +129,7 @@
             Succeed q = new Succeed();
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
 
@@ -151,8 +142,7 @@
             Integer[] ints = new Integer[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with any null elements throws NPE after
@@ -166,8 +156,7 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll throws ISE if an add fails
@@ -180,8 +169,7 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (IllegalStateException success) {}
+        } catch (IllegalStateException success) {}
     }
 
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java
new file mode 100644
index 0000000..43a4bd1
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java
@@ -0,0 +1,1025 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.*;
+import java.io.*;
+
+public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(AbstractQueuedLongSynchronizerTest.class);
+    }
+
+    /**
+     * A simple mutex class, adapted from the
+     * AbstractQueuedLongSynchronizer javadoc.  Exclusive acquire tests
+     * exercise this as a sample user extension.  Other
+     * methods/features of AbstractQueuedLongSynchronizerTest are tested
+     * via other test classes, including those for ReentrantLock,
+     * ReentrantReadWriteLock, and Semaphore
+     */
+    static class Mutex extends AbstractQueuedLongSynchronizer {
+        // Use value > 32 bits for locked state
+        static final long LOCKED = 1 << 48;
+        public boolean isHeldExclusively() {
+            return getState() == LOCKED;
+        }
+
+        public boolean tryAcquire(long acquires) {
+            return compareAndSetState(0, LOCKED);
+        }
+
+        public boolean tryRelease(long releases) {
+            if (getState() == 0) throw new IllegalMonitorStateException();
+            setState(0);
+            return true;
+        }
+
+        public AbstractQueuedLongSynchronizer.ConditionObject newCondition() { return new AbstractQueuedLongSynchronizer.ConditionObject(); }
+
+    }
+
+
+    /**
+     * A simple latch class, to test shared mode.
+     */
+    static class BooleanLatch extends AbstractQueuedLongSynchronizer {
+        public boolean isSignalled() { return getState() != 0; }
+
+        public long tryAcquireShared(long ignore) {
+            return isSignalled()? 1 : -1;
+        }
+
+        public boolean tryReleaseShared(long ignore) {
+            setState(1 << 62);
+            return true;
+        }
+    }
+
+    /**
+     * A runnable calling acquireInterruptibly that does not expect to
+     * be interrupted.
+     */
+    class InterruptibleSyncRunnable extends CheckedRunnable {
+        final Mutex sync;
+        InterruptibleSyncRunnable(Mutex l) { sync = l; }
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly(1);
+        }
+    }
+
+
+    /**
+     * A runnable calling acquireInterruptibly that expects to be
+     * interrupted.
+     */
+    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
+        final Mutex sync;
+        InterruptedSyncRunnable(Mutex l) { sync = l; }
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly(1);
+        }
+    }
+
+    /**
+     * isHeldExclusively is false upon construction
+     */
+    public void testIsHeldExclusively() {
+        Mutex rl = new Mutex();
+        assertFalse(rl.isHeldExclusively());
+    }
+
+    /**
+     * acquiring released sync succeeds
+     */
+    public void testAcquire() {
+        Mutex rl = new Mutex();
+        rl.acquire(1);
+        assertTrue(rl.isHeldExclusively());
+        rl.release(1);
+        assertFalse(rl.isHeldExclusively());
+    }
+
+    /**
+     * tryAcquire on an released sync succeeds
+     */
+    public void testTryAcquire() {
+        Mutex rl = new Mutex();
+        assertTrue(rl.tryAcquire(1));
+        assertTrue(rl.isHeldExclusively());
+        rl.release(1);
+    }
+
+    /**
+     * hasQueuedThreads reports whether there are waiting threads
+     */
+    public void testhasQueuedThreads() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertFalse(sync.hasQueuedThreads());
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThreads());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThreads());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThreads());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThreads());
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * isQueued(null) throws NPE
+     */
+    public void testIsQueuedNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.isQueued(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * isQueued reports whether a thread is queued.
+     */
+    public void testIsQueued() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertFalse(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.isQueued(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.isQueued(t1));
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.isQueued(t2));
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * getFirstQueuedThread returns first waiting thread or null if none
+     */
+    public void testGetFirstQueuedThread() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertNull(sync.getFirstQueuedThread());
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(t2, sync.getFirstQueuedThread());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertNull(sync.getFirstQueuedThread());
+        t1.join();
+        t2.join();
+    }
+
+
+    /**
+     * hasContended reports false if no thread has ever blocked, else true
+     */
+    public void testHasContended() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertFalse(sync.hasContended());
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * getQueuedThreads includes waiting threads
+     */
+    public void testGetQueuedThreads() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertTrue(sync.getQueuedThreads().isEmpty());
+        sync.acquire(1);
+        assertTrue(sync.getQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        assertTrue(sync.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.getQueuedThreads().contains(t1));
+        assertTrue(sync.getQueuedThreads().contains(t2));
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * getExclusiveQueuedThreads includes waiting threads
+     */
+    public void testGetExclusiveQueuedThreads() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+        sync.acquire(1);
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * getSharedQueuedThreads does not include exclusively waiting threads
+     */
+    public void testGetSharedQueuedThreads() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.acquire(1);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * tryAcquireNanos is interruptible.
+     */
+    public void testInterruptedException2() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquire(1);
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.tryAcquireNanos(1, MILLISECONDS.toNanos(MEDIUM_DELAY_MS));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+
+    /**
+     * TryAcquire on exclusively held sync fails
+     */
+    public void testTryAcquireWhenSynced() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquire(1);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(sync.tryAcquire(1));
+            }});
+
+        t.start();
+        t.join();
+        sync.release(1);
+    }
+
+    /**
+     * tryAcquireNanos on an exclusively held sync times out
+     */
+    public void testAcquireNanos_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquire(1);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long nanos = MILLISECONDS.toNanos(SHORT_DELAY_MS);
+                assertFalse(sync.tryAcquireNanos(1, nanos));
+            }});
+
+        t.start();
+        t.join();
+        sync.release(1);
+    }
+
+
+    /**
+     * getState is true when acquired and false when not
+     */
+    public void testGetState() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquire(1);
+        assertTrue(sync.isHeldExclusively());
+        sync.release(1);
+        assertFalse(sync.isHeldExclusively());
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                Thread.sleep(SMALL_DELAY_MS);
+                sync.release(1);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.isHeldExclusively());
+        t.join();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+
+    /**
+     * acquireInterruptibly is interruptible.
+     */
+    public void testAcquireInterruptibly1() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquire(1);
+        Thread t = new Thread(new InterruptedSyncRunnable(sync));
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.release(1);
+        t.join();
+    }
+
+    /**
+     * acquireInterruptibly succeeds when released, else is interruptible
+     */
+    public void testAcquireInterruptibly2() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquireInterruptibly(1);
+        Thread t = new Thread(new InterruptedSyncRunnable(sync));
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        assertTrue(sync.isHeldExclusively());
+        t.join();
+    }
+
+    /**
+     * owns is true for a condition created by sync else false
+     */
+    public void testOwns() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        assertTrue(sync.owns(c));
+        assertFalse(sync2.owns(c));
+    }
+
+    /**
+     * Calling await without holding sync throws IllegalMonitorStateException
+     */
+    public void testAwait_IllegalMonitor() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        try {
+            c.await();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * Calling signal without holding sync throws IllegalMonitorStateException
+     */
+    public void testSignal_IllegalMonitor() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        try {
+            c.signal();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * awaitNanos without a signal times out
+     */
+    public void testAwaitNanos_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        sync.acquire(1);
+        long t = c.awaitNanos(100);
+        assertTrue(t <= 0);
+        sync.release(1);
+    }
+
+    /**
+     *  Timed await without a signal times out
+     */
+    public void testAwait_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        sync.acquire(1);
+        assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS));
+        sync.release(1);
+    }
+
+    /**
+     * awaitUntil without a signal times out
+     */
+    public void testAwaitUntil_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        sync.acquire(1);
+        java.util.Date d = new java.util.Date();
+        assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
+        sync.release(1);
+    }
+
+    /**
+     * await returns when signalled
+     */
+    public void testAwait() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+                sync.release(1);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        c.signal();
+        sync.release(1);
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+
+
+    /**
+     * hasWaiters throws NPE if null
+     */
+    public void testHasWaitersNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.hasWaiters(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws NPE if null
+     */
+    public void testGetWaitQueueLengthNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.getWaitQueueLength(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * getWaitingThreads throws NPE if null
+     */
+    public void testGetWaitingThreadsNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.getWaitingThreads(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * hasWaiters throws IAE if not owned
+     */
+    public void testHasWaitersIAE() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * hasWaiters throws IMSE if not synced
+     */
+    public void testHasWaitersIMSE() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        try {
+            sync.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+
+    /**
+     * getWaitQueueLength throws IAE if not owned
+     */
+    public void testGetWaitQueueLengthIAE() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws IMSE if not synced
+     */
+    public void testGetWaitQueueLengthIMSE() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        try {
+            sync.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+
+    /**
+     * getWaitingThreads throws IAE if not owned
+     */
+    public void testGetWaitingThreadsIAE() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws IMSE if not synced
+     */
+    public void testGetWaitingThreadsIMSE() {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        try {
+            sync.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+
+
+    /**
+     * hasWaiters returns true when a thread is waiting, else false
+     */
+    public void testHasWaiters() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertFalse(sync.hasWaiters(c));
+                threadAssertEquals(0, sync.getWaitQueueLength(c));
+                c.await();
+                sync.release(1);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertTrue(sync.hasWaiters(c));
+        assertEquals(1, sync.getWaitQueueLength(c));
+        c.signal();
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertFalse(sync.hasWaiters(c));
+        assertEquals(0, sync.getWaitQueueLength(c));
+        sync.release(1);
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+    /**
+     * getWaitQueueLength returns number of waiting threads
+     */
+    public void testGetWaitQueueLength() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertFalse(sync.hasWaiters(c));
+                threadAssertEquals(0, sync.getWaitQueueLength(c));
+                c.await();
+                sync.release(1);
+            }});
+
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertTrue(sync.hasWaiters(c));
+                threadAssertEquals(1, sync.getWaitQueueLength(c));
+                c.await();
+                sync.release(1);
+            }});
+
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertTrue(sync.hasWaiters(c));
+        assertEquals(2, sync.getWaitQueueLength(c));
+        c.signalAll();
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertFalse(sync.hasWaiters(c));
+        assertEquals(0, sync.getWaitQueueLength(c));
+        sync.release(1);
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
+    }
+
+    /**
+     * getWaitingThreads returns only and all waiting threads
+     */
+    public void testGetWaitingThreads() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
+                c.await();
+                sync.release(1);
+            }});
+
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
+                c.await();
+                sync.release(1);
+            }});
+
+            sync.acquire(1);
+            assertTrue(sync.getWaitingThreads(c).isEmpty());
+            sync.release(1);
+            t1.start();
+            Thread.sleep(SHORT_DELAY_MS);
+            t2.start();
+            Thread.sleep(SHORT_DELAY_MS);
+            sync.acquire(1);
+            assertTrue(sync.hasWaiters(c));
+            assertTrue(sync.getWaitingThreads(c).contains(t1));
+            assertTrue(sync.getWaitingThreads(c).contains(t2));
+            c.signalAll();
+            sync.release(1);
+            Thread.sleep(SHORT_DELAY_MS);
+            sync.acquire(1);
+            assertFalse(sync.hasWaiters(c));
+            assertTrue(sync.getWaitingThreads(c).isEmpty());
+            sync.release(1);
+            t1.join(SHORT_DELAY_MS);
+            t2.join(SHORT_DELAY_MS);
+            assertFalse(t1.isAlive());
+            assertFalse(t2.isAlive());
+    }
+
+
+
+    /**
+     * awaitUninterruptibly doesn't abort on interrupt
+     */
+    public void testAwaitUninterruptibly() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                sync.acquire(1);
+                c.awaitUninterruptibly();
+                sync.release(1);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        sync.acquire(1);
+        c.signal();
+        sync.release(1);
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+    /**
+     * await is interruptible
+     */
+    public void testAwait_Interrupt() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+    /**
+     * awaitNanos is interruptible
+     */
+    public void testAwaitNanos_Interrupt() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+    /**
+     * awaitUntil is interruptible
+     */
+    public void testAwaitUntil_Interrupt() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                java.util.Date d = new java.util.Date();
+                c.awaitUntil(new java.util.Date(d.getTime() + 10000));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+    /**
+     * signalAll wakes up all threads
+     */
+    public void testSignalAll() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+                sync.release(1);
+            }});
+
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+                sync.release(1);
+            }});
+
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        c.signalAll();
+        sync.release(1);
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
+    }
+
+
+    /**
+     * toString indicates current state
+     */
+    public void testToString() {
+        Mutex sync = new Mutex();
+        String us = sync.toString();
+        assertTrue(us.indexOf("State = 0") >= 0);
+        sync.acquire(1);
+        String ls = sync.toString();
+        assertTrue(ls.indexOf("State = " + Mutex.LOCKED) >= 0);
+    }
+
+    /**
+     * A serialized AQS deserializes with current state
+     */
+    public void testSerialization() throws Exception {
+        Mutex l = new Mutex();
+        l.acquire(1);
+        assertTrue(l.isHeldExclusively());
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        Mutex r = (Mutex) in.readObject();
+        assertTrue(r.isHeldExclusively());
+    }
+
+
+    /**
+     * tryReleaseShared setting state changes getState
+     */
+    public void testGetStateWithReleaseShared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertFalse(l.isSignalled());
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+    }
+
+    /**
+     * releaseShared has no effect when already signalled
+     */
+    public void testReleaseShared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertFalse(l.isSignalled());
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+    }
+
+    /**
+     * acquireSharedInterruptibly returns after release, but not before
+     */
+    public void testAcquireSharedInterruptibly() throws InterruptedException {
+        final BooleanLatch l = new BooleanLatch();
+
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+                threadAssertTrue(l.isSignalled());
+            }});
+
+        t.start();
+        assertFalse(l.isSignalled());
+        Thread.sleep(SHORT_DELAY_MS);
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+        t.join();
+    }
+
+
+    /**
+     * acquireSharedTimed returns after release
+     */
+    public void testAsquireSharedTimed() throws InterruptedException {
+        final BooleanLatch l = new BooleanLatch();
+
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(MEDIUM_DELAY_MS);
+                assertTrue(l.tryAcquireSharedNanos(0, nanos));
+                assertTrue(l.isSignalled());
+            }});
+
+        t.start();
+        assertFalse(l.isSignalled());
+        Thread.sleep(SHORT_DELAY_MS);
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+        t.join();
+    }
+
+    /**
+     * acquireSharedInterruptibly throws IE if interrupted before released
+     */
+    public void testAcquireSharedInterruptibly_InterruptedException() throws InterruptedException {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+            }});
+
+        t.start();
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * acquireSharedTimed throws IE if interrupted before released
+     */
+    public void testAcquireSharedNanos_InterruptedException() throws InterruptedException {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(SMALL_DELAY_MS);
+                l.tryAcquireSharedNanos(0, nanos);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * acquireSharedTimed times out if not released before timeout
+     */
+    public void testAcquireSharedNanos_Timeout() throws InterruptedException {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(SMALL_DELAY_MS);
+                assertFalse(l.tryAcquireSharedNanos(0, nanos));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(l.isSignalled());
+        t.join();
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java
index db89645..a5b6554 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AbstractQueuedSynchronizerTest.java
@@ -2,8 +2,8 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
 package tests.api.java.util.concurrent;
@@ -11,13 +11,11 @@
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.concurrent.locks.*;
 import java.io.*;
 
 public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AbstractQueuedSynchronizerTest.class);
     }
@@ -32,33 +30,33 @@
      */
     static class Mutex extends AbstractQueuedSynchronizer {
         public boolean isHeldExclusively() { return getState() == 1; }
-        
+
         public boolean tryAcquire(int acquires) {
-            assertTrue(acquires == 1); 
+            assertTrue(acquires == 1);
             return compareAndSetState(0, 1);
         }
-        
+
         public boolean tryRelease(int releases) {
             if (getState() == 0) throw new IllegalMonitorStateException();
             setState(0);
             return true;
         }
-        
+
         public AbstractQueuedSynchronizer.ConditionObject newCondition() { return new AbstractQueuedSynchronizer.ConditionObject(); }
 
     }
 
-    
+
     /**
      * A simple latch class, to test shared mode.
      */
-    static class BooleanLatch extends AbstractQueuedSynchronizer { 
+    static class BooleanLatch extends AbstractQueuedSynchronizer {
         public boolean isSignalled() { return getState() != 0; }
 
         public int tryAcquireShared(int ignore) {
             return isSignalled()? 1 : -1;
         }
-        
+
         public boolean tryReleaseShared(int ignore) {
             setState(1);
             return true;
@@ -66,46 +64,42 @@
     }
 
     /**
-     * A runnable calling acquireInterruptibly
+     * A runnable calling acquireInterruptibly that does not expect to
+     * be interrupted.
      */
-    class InterruptibleSyncRunnable implements Runnable {
+    class InterruptibleSyncRunnable extends CheckedRunnable {
         final Mutex sync;
         InterruptibleSyncRunnable(Mutex l) { sync = l; }
-        public void run() {
-            try {
-                sync.acquireInterruptibly(1);
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly(1);
         }
     }
 
 
     /**
      * A runnable calling acquireInterruptibly that expects to be
-     * interrupted
+     * interrupted.
      */
-    class InterruptedSyncRunnable implements Runnable {
+    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
         final Mutex sync;
         InterruptedSyncRunnable(Mutex l) { sync = l; }
-        public void run() {
-            try {
-                sync.acquireInterruptibly(1);
-                threadShouldThrow();
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly(1);
         }
     }
 
     /**
      * isHeldExclusively is false upon construction
      */
-    public void testIsHeldExclusively() { 
+    public void testIsHeldExclusively() {
         Mutex rl = new Mutex();
         assertFalse(rl.isHeldExclusively());
     }
-    
+
     /**
      * acquiring released sync succeeds
      */
-    public void testAcquire() { 
+    public void testAcquire() {
         Mutex rl = new Mutex();
         rl.acquire(1);
         assertTrue(rl.isHeldExclusively());
@@ -116,7 +110,7 @@
     /**
      * tryAcquire on an released sync succeeds
      */
-    public void testTryAcquire() { 
+    public void testTryAcquire() {
         Mutex rl = new Mutex();
         assertTrue(rl.tryAcquire(1));
         assertTrue(rl.isHeldExclusively());
@@ -126,378 +120,314 @@
     /**
      * hasQueuedThreads reports whether there are waiting threads
      */
-    public void testhasQueuedThreads() { 
+    public void testhasQueuedThreads() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertFalse(sync.hasQueuedThreads());
-            sync.acquire(1);
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThreads());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThreads());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThreads());
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThreads());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertFalse(sync.hasQueuedThreads());
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThreads());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThreads());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThreads());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThreads());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * isQueued(null) throws NPE
      */
-    public void testIsQueuedNPE() { 
+    public void testIsQueuedNPE() {
         final Mutex sync = new Mutex();
         try {
             sync.isQueued(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * isQueued reports whether a thread is queued.
      */
-    public void testIsQueued() { 
+    public void testIsQueued() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertFalse(sync.isQueued(t1));
-            assertFalse(sync.isQueued(t2));
-            sync.acquire(1);
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.isQueued(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.isQueued(t1));
-            assertTrue(sync.isQueued(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.isQueued(t1));
-            assertTrue(sync.isQueued(t2));
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.isQueued(t1));
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.isQueued(t2));
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertFalse(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.isQueued(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.isQueued(t1));
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.isQueued(t2));
+        t1.join();
+        t2.join();
+    }
 
     /**
      * getFirstQueuedThread returns first waiting thread or null if none
      */
-    public void testGetFirstQueuedThread() { 
+    public void testGetFirstQueuedThread() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertNull(sync.getFirstQueuedThread());
-            sync.acquire(1);
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(t1, sync.getFirstQueuedThread());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(t1, sync.getFirstQueuedThread());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(t2, sync.getFirstQueuedThread());
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertNull(sync.getFirstQueuedThread());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertNull(sync.getFirstQueuedThread());
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(t2, sync.getFirstQueuedThread());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertNull(sync.getFirstQueuedThread());
+        t1.join();
+        t2.join();
+    }
 
 
     /**
      * hasContended reports false if no thread has ever blocked, else true
      */
-    public void testHasContended() { 
+    public void testHasContended() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertFalse(sync.hasContended());
-            sync.acquire(1);
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasContended());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasContended());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasContended());
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasContended());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertFalse(sync.hasContended());
+        sync.acquire(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasContended());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * getQueuedThreads includes waiting threads
      */
-    public void testGetQueuedThreads() { 
+    public void testGetQueuedThreads() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertTrue(sync.getQueuedThreads().isEmpty());
-            sync.acquire(1);
-            assertTrue(sync.getQueuedThreads().isEmpty());
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getQueuedThreads().contains(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getQueuedThreads().contains(t1));
-            assertTrue(sync.getQueuedThreads().contains(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.getQueuedThreads().contains(t1));
-            assertTrue(sync.getQueuedThreads().contains(t2));
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getQueuedThreads().isEmpty());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertTrue(sync.getQueuedThreads().isEmpty());
+        sync.acquire(1);
+        assertTrue(sync.getQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        assertTrue(sync.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.getQueuedThreads().contains(t1));
+        assertTrue(sync.getQueuedThreads().contains(t2));
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * getExclusiveQueuedThreads includes waiting threads
      */
-    public void testGetExclusiveQueuedThreads() { 
+    public void testGetExclusiveQueuedThreads() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
-            sync.acquire(1);
-            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
-            assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
-            assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+        sync.acquire(1);
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * getSharedQueuedThreads does not include exclusively waiting threads
      */
-    public void testGetSharedQueuedThreads() { 
+    public void testGetSharedQueuedThreads() throws InterruptedException {
         final Mutex sync = new Mutex();
         Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
         Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
-        try {
-            assertTrue(sync.getSharedQueuedThreads().isEmpty());
-            sync.acquire(1);
-            assertTrue(sync.getSharedQueuedThreads().isEmpty());
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getSharedQueuedThreads().isEmpty());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getSharedQueuedThreads().isEmpty());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getSharedQueuedThreads().isEmpty());
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.getSharedQueuedThreads().isEmpty());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.acquire(1);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * tryAcquireNanos is interruptible.
      */
-    public void testInterruptedException2() { 
+    public void testInterruptedException2() throws InterruptedException {
         final Mutex sync = new Mutex();
         sync.acquire(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
-        try {
-            t.start();
-            t.interrupt();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.tryAcquireNanos(1, MILLISECONDS.toNanos(MEDIUM_DELAY_MS));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
     /**
      * TryAcquire on exclusively held sync fails
      */
-    public void testTryAcquireWhenSynced() { 
+    public void testTryAcquireWhenSynced() throws InterruptedException {
         final Mutex sync = new Mutex();
         sync.acquire(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertFalse(sync.tryAcquire(1));
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            sync.release(1);
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(sync.tryAcquire(1));
+            }});
+
+        t.start();
+        t.join();
+        sync.release(1);
+    }
 
     /**
      * tryAcquireNanos on an exclusively held sync times out
      */
-    public void testAcquireNanos_Timeout() { 
+    public void testAcquireNanos_Timeout() throws InterruptedException {
         final Mutex sync = new Mutex();
         sync.acquire(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000));
-                    } catch (Exception ex) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            sync.release(1);
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
-    
-   
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long nanos = MILLISECONDS.toNanos(SHORT_DELAY_MS);
+                assertFalse(sync.tryAcquireNanos(1, nanos));
+            }});
+
+        t.start();
+        t.join();
+        sync.release(1);
+    }
+
+
     /**
      * getState is true when acquired and false when not
      */
-    public void testGetState() {
+    public void testGetState() throws InterruptedException {
         final Mutex sync = new Mutex();
         sync.acquire(1);
         assertTrue(sync.isHeldExclusively());
         sync.release(1);
         assertFalse(sync.isHeldExclusively());
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    sync.acquire(1);
-                    try {
-                        Thread.sleep(SMALL_DELAY_MS);
-                    }
-                    catch(Exception e) {
-                        threadUnexpectedException();
-                    }
-                    sync.release(1);
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.isHeldExclusively());
-            t.join();
-            assertFalse(sync.isHeldExclusively());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                Thread.sleep(SMALL_DELAY_MS);
+                sync.release(1);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.isHeldExclusively());
+        t.join();
+        assertFalse(sync.isHeldExclusively());
     }
 
 
     /**
      * acquireInterruptibly is interruptible.
      */
-    public void testAcquireInterruptibly1() { 
+    public void testAcquireInterruptibly1() throws InterruptedException {
         final Mutex sync = new Mutex();
         sync.acquire(1);
         Thread t = new Thread(new InterruptedSyncRunnable(sync));
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.release(1);
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.release(1);
+        t.join();
+    }
 
     /**
      * acquireInterruptibly succeeds when released, else is interruptible
      */
-    public void testAcquireInterruptibly2() {
-        final Mutex sync = new Mutex();        
-        try {
-            sync.acquireInterruptibly(1);
-        } catch(Exception e) {
-            unexpectedException();
-        }
+    public void testAcquireInterruptibly2() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        sync.acquireInterruptibly(1);
         Thread t = new Thread(new InterruptedSyncRunnable(sync));
-        try {
-            t.start();
-            t.interrupt();
-            assertTrue(sync.isHeldExclusively());
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        assertTrue(sync.isHeldExclusively());
+        t.join();
     }
 
     /**
      * owns is true for a condition created by sync else false
      */
     public void testOwns() {
-        final Mutex sync = new Mutex();        
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         final Mutex sync2 = new Mutex();
         assertTrue(sync.owns(c));
@@ -507,118 +437,82 @@
     /**
      * Calling await without holding sync throws IllegalMonitorStateException
      */
-    public void testAwait_IllegalMonitor() {
-        final Mutex sync = new Mutex();        
+    public void testAwait_IllegalMonitor() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         try {
             c.await();
             shouldThrow();
-        }
-        catch (IllegalMonitorStateException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
      * Calling signal without holding sync throws IllegalMonitorStateException
      */
     public void testSignal_IllegalMonitor() {
-        final Mutex sync = new Mutex();        
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         try {
             c.signal();
             shouldThrow();
-        }
-        catch (IllegalMonitorStateException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
      * awaitNanos without a signal times out
      */
-    public void testAwaitNanos_Timeout() {
-        final Mutex sync = new Mutex();        
+    public void testAwaitNanos_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        try {
-            sync.acquire(1);
-            long t = c.awaitNanos(100);
-            assertTrue(t <= 0);
-            sync.release(1);
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        sync.acquire(1);
+        long t = c.awaitNanos(100);
+        assertTrue(t <= 0);
+        sync.release(1);
     }
 
     /**
      *  Timed await without a signal times out
      */
-    public void testAwait_Timeout() {
-        final Mutex sync = new Mutex();        
+    public void testAwait_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        try {
-            sync.acquire(1);
-            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            sync.release(1);
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        sync.acquire(1);
+        assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS));
+        sync.release(1);
     }
 
     /**
      * awaitUntil without a signal times out
      */
-    public void testAwaitUntil_Timeout() {
-        final Mutex sync = new Mutex();        
+    public void testAwaitUntil_Timeout() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        try {
-            sync.acquire(1);
-            java.util.Date d = new java.util.Date();
-            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
-            sync.release(1);
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        sync.acquire(1);
+        java.util.Date d = new java.util.Date();
+        assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
+        sync.release(1);
     }
 
     /**
      * await returns when signalled
      */
-    public void testAwait() {
-        final Mutex sync = new Mutex();        
+    public void testAwait() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+                sync.release(1);
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            c.signal();
-            sync.release(1);
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        c.signal();
+        sync.release(1);
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
 
@@ -631,10 +525,7 @@
         try {
             sync.hasWaiters(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -645,10 +536,7 @@
         try {
             sync.getWaitQueueLength(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -660,10 +548,7 @@
         try {
             sync.getWaitingThreads(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -672,15 +557,12 @@
      */
     public void testHasWaitersIAE() {
         final Mutex sync = new Mutex();
-        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
+        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         final Mutex sync2 = new Mutex();
         try {
             sync2.hasWaiters(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -688,14 +570,11 @@
      */
     public void testHasWaitersIMSE() {
         final Mutex sync = new Mutex();
-        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
+        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         try {
             sync.hasWaiters(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -704,15 +583,12 @@
      */
     public void testGetWaitQueueLengthIAE() {
         final Mutex sync = new Mutex();
-        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
+        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         final Mutex sync2 = new Mutex();
         try {
             sync2.getWaitQueueLength(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -720,14 +596,11 @@
      */
     public void testGetWaitQueueLengthIMSE() {
         final Mutex sync = new Mutex();
-        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
+        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         try {
             sync.getWaitQueueLength(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -735,31 +608,25 @@
      * getWaitingThreads throws IAE if not owned
      */
     public void testGetWaitingThreadsIAE() {
-        final Mutex sync = new Mutex();        
-        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
-        final Mutex sync2 = new Mutex();        
+        final Mutex sync = new Mutex();
+        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
         try {
             sync2.getWaitingThreads(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * getWaitingThreads throws IMSE if not synced
      */
     public void testGetWaitingThreadsIMSE() {
-        final Mutex sync = new Mutex();        
-        final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
+        final Mutex sync = new Mutex();
+        final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
         try {
             sync.getWaitingThreads(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -767,167 +634,122 @@
     /**
      * hasWaiters returns true when a thread is waiting, else false
      */
-    public void testHasWaiters() {
-        final Mutex sync = new Mutex();        
+    public void testHasWaiters() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        threadAssertFalse(sync.hasWaiters(c));
-                        threadAssertEquals(0, sync.getWaitQueueLength(c));
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertFalse(sync.hasWaiters(c));
+                threadAssertEquals(0, sync.getWaitQueueLength(c));
+                c.await();
+                sync.release(1);
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            assertTrue(sync.hasWaiters(c));
-            assertEquals(1, sync.getWaitQueueLength(c));
-            c.signal();
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            assertFalse(sync.hasWaiters(c));
-            assertEquals(0, sync.getWaitQueueLength(c));
-            sync.release(1);
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertTrue(sync.hasWaiters(c));
+        assertEquals(1, sync.getWaitQueueLength(c));
+        c.signal();
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertFalse(sync.hasWaiters(c));
+        assertEquals(0, sync.getWaitQueueLength(c));
+        sync.release(1);
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * getWaitQueueLength returns number of waiting threads
      */
-    public void testGetWaitQueueLength() {
-        final Mutex sync = new Mutex();        
+    public void testGetWaitQueueLength() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t1 = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        threadAssertFalse(sync.hasWaiters(c));
-                        threadAssertEquals(0, sync.getWaitQueueLength(c));
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertFalse(sync.hasWaiters(c));
+                threadAssertEquals(0, sync.getWaitQueueLength(c));
+                c.await();
+                sync.release(1);
+            }});
 
-        Thread t2 = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        threadAssertTrue(sync.hasWaiters(c));
-                        threadAssertEquals(1, sync.getWaitQueueLength(c));
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertTrue(sync.hasWaiters(c));
+                threadAssertEquals(1, sync.getWaitQueueLength(c));
+                c.await();
+                sync.release(1);
+            }});
 
-        try {
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            assertTrue(sync.hasWaiters(c));
-            assertEquals(2, sync.getWaitQueueLength(c));
-            c.signalAll();
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            assertFalse(sync.hasWaiters(c));
-            assertEquals(0, sync.getWaitQueueLength(c));
-            sync.release(1);
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertTrue(sync.hasWaiters(c));
+        assertEquals(2, sync.getWaitQueueLength(c));
+        c.signalAll();
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertFalse(sync.hasWaiters(c));
+        assertEquals(0, sync.getWaitQueueLength(c));
+        sync.release(1);
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /**
      * getWaitingThreads returns only and all waiting threads
      */
-    public void testGetWaitingThreads() {
-        final Mutex sync = new Mutex();        
+    public void testGetWaitingThreads() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t1 = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
+                c.await();
+                sync.release(1);
+            }});
 
-        Thread t2 = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
+                c.await();
+                sync.release(1);
+            }});
 
-        try {
-            sync.acquire(1);
-            assertTrue(sync.getWaitingThreads(c).isEmpty());
-            sync.release(1);
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            assertTrue(sync.hasWaiters(c));
-            assertTrue(sync.getWaitingThreads(c).contains(t1));
-            assertTrue(sync.getWaitingThreads(c).contains(t2));
-            c.signalAll();
-            sync.release(1);
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            assertFalse(sync.hasWaiters(c));
-            assertTrue(sync.getWaitingThreads(c).isEmpty());
-            sync.release(1);
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        sync.acquire(1);
+        assertTrue(sync.getWaitingThreads(c).isEmpty());
+        sync.release(1);
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertTrue(sync.hasWaiters(c));
+        assertTrue(sync.getWaitingThreads(c).contains(t1));
+        assertTrue(sync.getWaitingThreads(c).contains(t2));
+        c.signalAll();
+        sync.release(1);
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        assertFalse(sync.hasWaiters(c));
+        assertTrue(sync.getWaitingThreads(c).isEmpty());
+        sync.release(1);
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
 
@@ -935,175 +757,114 @@
     /**
      * awaitUninterruptibly doesn't abort on interrupt
      */
-    public void testAwaitUninterruptibly() {
-        final Mutex sync = new Mutex();        
+    public void testAwaitUninterruptibly() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    sync.acquire(1);
-                    c.awaitUninterruptibly();
-                    sync.release(1);
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                sync.acquire(1);
+                c.awaitUninterruptibly();
+                sync.release(1);
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            sync.acquire(1);
-            c.signal();
-            sync.release(1);
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        sync.acquire(1);
+        c.signal();
+        sync.release(1);
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * await is interruptible
      */
-    public void testAwait_Interrupt() {
-        final Mutex sync = new Mutex();        
+    public void testAwait_Interrupt() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        c.await();
-                        sync.release(1);
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * awaitNanos is interruptible
      */
-    public void testAwaitNanos_Interrupt() {
-        final Mutex sync = new Mutex();        
+    public void testAwaitNanos_Interrupt() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
-                        sync.release(1);
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS));
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * awaitUntil is interruptible
      */
-    public void testAwaitUntil_Interrupt() {
-        final Mutex sync = new Mutex();        
+    public void testAwaitUntil_Interrupt() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        java.util.Date d = new java.util.Date();
-                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
-                        sync.release(1);
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                java.util.Date d = new java.util.Date();
+                c.awaitUntil(new java.util.Date(d.getTime() + 10000));
+            }});
 
-        try {
-            t.start();
-            // BEGIN android-changed
-            Thread.sleep(SMALL_DELAY_MS); // SHORT_DELAY_MS was flaky on Android
-            t.interrupt();
-            t.join(SMALL_DELAY_MS);       // SHORT_DELAY_MS was flaky on Android
-            // END android-changed
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * signalAll wakes up all threads
      */
-    public void testSignalAll() {
-        final Mutex sync = new Mutex();        
+    public void testSignalAll() throws InterruptedException {
+        final Mutex sync = new Mutex();
         final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
-        Thread t1 = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+                sync.release(1);
+            }});
 
-        Thread t2 = new Thread(new Runnable() { 
-                public void run() {
-                    try {
-                        sync.acquire(1);
-                        c.await();
-                        sync.release(1);
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire(1);
+                c.await();
+                sync.release(1);
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            sync.acquire(1);
-            c.signalAll();
-            sync.release(1);
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        sync.acquire(1);
+        c.signalAll();
+        sync.release(1);
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
 
@@ -1122,25 +883,20 @@
     /**
      * A serialized AQS deserializes with current state
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         Mutex l = new Mutex();
         l.acquire(1);
         assertTrue(l.isHeldExclusively());
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            Mutex r = (Mutex) in.readObject();
-            assertTrue(r.isHeldExclusively());
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        Mutex r = (Mutex) in.readObject();
+        assertTrue(r.isHeldExclusively());
     }
 
 
@@ -1169,136 +925,99 @@
     /**
      * acquireSharedInterruptibly returns after release, but not before
      */
-    public void testAcquireSharedInterruptibly() {
+    public void testAcquireSharedInterruptibly() throws InterruptedException {
         final BooleanLatch l = new BooleanLatch();
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(l.isSignalled());
-                        l.acquireSharedInterruptibly(0);
-                        threadAssertTrue(l.isSignalled());
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            assertFalse(l.isSignalled());
-            Thread.sleep(SHORT_DELAY_MS);
-            l.releaseShared(0);
-            assertTrue(l.isSignalled());
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+                threadAssertTrue(l.isSignalled());
+            }});
+
+        t.start();
+        assertFalse(l.isSignalled());
+        Thread.sleep(SHORT_DELAY_MS);
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+        t.join();
     }
-    
+
 
     /**
      * acquireSharedTimed returns after release
      */
-    public void testAsquireSharedTimed() {
+    public void testAsquireSharedTimed() throws InterruptedException {
         final BooleanLatch l = new BooleanLatch();
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(l.isSignalled());
-                        threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
-                        threadAssertTrue(l.isSignalled());
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(MEDIUM_DELAY_MS);
+                assertTrue(l.tryAcquireSharedNanos(0, nanos));
+                assertTrue(l.isSignalled());
+            }});
 
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            assertFalse(l.isSignalled());
-            Thread.sleep(SHORT_DELAY_MS);
-            l.releaseShared(0);
-            assertTrue(l.isSignalled());
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        t.start();
+        assertFalse(l.isSignalled());
+        Thread.sleep(SHORT_DELAY_MS);
+        l.releaseShared(0);
+        assertTrue(l.isSignalled());
+        t.join();
     }
-    
+
     /**
      * acquireSharedInterruptibly throws IE if interrupted before released
      */
-    public void testAcquireSharedInterruptibly_InterruptedException() {
+    public void testAcquireSharedInterruptibly_InterruptedException() throws InterruptedException {
         final BooleanLatch l = new BooleanLatch();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(l.isSignalled());
-                        l.acquireSharedInterruptibly(0);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+            }});
+
         t.start();
-        try {
-            assertFalse(l.isSignalled());
-            t.interrupt();
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        t.join();
     }
 
     /**
      * acquireSharedTimed throws IE if interrupted before released
      */
-    public void testAcquireSharedNanos_InterruptedException() {
+    public void testAcquireSharedNanos_InterruptedException() throws InterruptedException {
         final BooleanLatch l = new BooleanLatch();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(l.isSignalled());
-                        l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
-                        threadShouldThrow();                        
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(SMALL_DELAY_MS);
+                l.tryAcquireSharedNanos(0, nanos);
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(l.isSignalled());
-            t.interrupt();
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        t.join();
     }
 
     /**
      * acquireSharedTimed times out if not released before timeout
      */
-    public void testAcquireSharedNanos_Timeout() {
+    public void testAcquireSharedNanos_Timeout() throws InterruptedException {
         final BooleanLatch l = new BooleanLatch();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(l.isSignalled());
-                        threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(SMALL_DELAY_MS);
+                assertFalse(l.tryAcquireSharedNanos(0, nanos));
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(l.isSignalled());
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(l.isSignalled());
+        t.join();
     }
 
-    
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java
index b650ede..8fc5cb6 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayBlockingQueueTest.java
@@ -2,21 +2,19 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 
 public class ArrayBlockingQueueTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(ArrayBlockingQueueTest.class);
     }
@@ -28,14 +26,14 @@
     private ArrayBlockingQueue populatedQueue(int n) {
         ArrayBlockingQueue q = new ArrayBlockingQueue(n);
         assertTrue(q.isEmpty());
-        for(int i = 0; i < n; i++)
+        for (int i = 0; i < n; i++)
             assertTrue(q.offer(new Integer(i)));
         assertFalse(q.isEmpty());
         assertEquals(0, q.remainingCapacity());
         assertEquals(n, q.size());
         return q;
     }
- 
+
     /**
      * A new queue has the indicated capacity
      */
@@ -44,14 +42,13 @@
     }
 
     /**
-     * Constructor throws IAE if  capacity argument nonpositive
+     * Constructor throws IAE if capacity argument nonpositive
      */
     public void testConstructor2() {
         try {
             ArrayBlockingQueue q = new ArrayBlockingQueue(0);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -61,8 +58,7 @@
         try {
             ArrayBlockingQueue q = new ArrayBlockingQueue(1, true, null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -73,8 +69,7 @@
             Integer[] ints = new Integer[SIZE];
             ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -87,8 +82,7 @@
                 ints[i] = new Integer(i);
             ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -101,23 +95,19 @@
                 ints[i] = new Integer(i);
             ArrayBlockingQueue q = new ArrayBlockingQueue(1, false, Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * Queue contains all elements of collection used to initialize
      */
     public void testConstructor7() {
-        try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, Arrays.asList(ints));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -160,7 +150,7 @@
             ArrayBlockingQueue q = new ArrayBlockingQueue(1);
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -171,7 +161,7 @@
             ArrayBlockingQueue q = new ArrayBlockingQueue(1);
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -194,8 +184,8 @@
             }
             assertEquals(0, q.remainingCapacity());
             q.add(new Integer(SIZE));
-        } catch (IllegalStateException success){
-        }   
+            shouldThrow();
+        } catch (IllegalStateException success) {}
     }
 
     /**
@@ -206,8 +196,7 @@
             ArrayBlockingQueue q = new ArrayBlockingQueue(1);
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -218,8 +207,7 @@
             ArrayBlockingQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
 
@@ -232,8 +220,7 @@
             Integer[] ints = new Integer[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with any null elements throws NPE after
@@ -247,8 +234,7 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll throws ISE if not enough room
@@ -261,214 +247,166 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (IllegalStateException success) {}
+        } catch (IllegalStateException success) {}
     }
     /**
      * Queue contains all elements, in traversal order, of successful addAll
      */
     public void testAddAll5() {
-        try {
-            Integer[] empty = new Integer[0];
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
-            assertFalse(q.addAll(Arrays.asList(empty)));
-            assertTrue(q.addAll(Arrays.asList(ints)));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
      *  put(null) throws NPE
      */
-     public void testPutNull() {
+    public void testPutNull() throws InterruptedException {
         try {
             ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
             q.put(null);
             shouldThrow();
-        } 
-        catch (NullPointerException success){
-        }   
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
      }
 
     /**
      * all elements successfully put are contained
      */
-     public void testPut() {
-         try {
-             ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
-             for (int i = 0; i < SIZE; ++i) {
-                 Integer I = new Integer(i);
-                 q.put(I);
-                 assertTrue(q.contains(I));
-             }
-             assertEquals(0, q.remainingCapacity());
-         }
-        catch (InterruptedException ie) {
-            unexpectedException();
+    public void testPut() throws InterruptedException {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer I = new Integer(i);
+            q.put(I);
+            assertTrue(q.contains(I));
         }
+        assertEquals(0, q.remainingCapacity());
     }
 
     /**
      * put blocks interruptibly if full
      */
-    public void testBlockingPut() {
+    public void testBlockingPut() throws InterruptedException {
         final ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        for (int i = 0; i < SIZE; ++i) {
-                            q.put(new Integer(i));
-                            ++added;
-                        }
-                        q.put(new Integer(SIZE));
-                        threadShouldThrow();
-                    } catch (InterruptedException ie){
-                        threadAssertEquals(added, SIZE);
-                    }   
-                }});
-        try { 
-            t.start();
-           Thread.sleep(MEDIUM_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.put(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
     }
 
     /**
      * put blocks waiting for take when full
      */
-    public void testPutWithTake() {
-        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        threadShouldThrow();
-                    } catch (InterruptedException e){
-                        threadAssertTrue(added >= 2);
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.take();
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+    public void testPutWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(capacity);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity + 1; i++)
+                    q.put(i);
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(q.remainingCapacity(), 0);
+        assertEquals(0, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(q.remainingCapacity(), 0);
     }
 
     /**
      * timed offer times out if full and elements not taken
      */
-    public void testTimedOffer() {
+    public void testTimedOffer() throws InterruptedException {
         final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new Object());
-                        q.put(new Object());
-                        threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS/2, TimeUnit.MILLISECONDS));
-                        q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success){}
-                }
-            });
-        
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Object());
+                q.put(new Object());
+                assertFalse(q.offer(new Object(), SHORT_DELAY_MS/2, MILLISECONDS));
+                try {
+                    q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * take retrieves elements in FIFO order
      */
-    public void testTake() {
-        try {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.take()).intValue());
-            }
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTake() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
     }
 
     /**
      * take blocks interruptibly when empty
      */
-    public void testTakeFromEmpty() {
+    public void testTakeFromEmpty() throws InterruptedException {
         final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){ }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }};
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * Take removes existing elements until empty, then blocks interruptibly
      */
-    public void testBlockingTake() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        ArrayBlockingQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(i, ((Integer)q.take()).intValue());
-                        }
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){
-                    }   
-                }});
-        try { 
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS); 
-            t.interrupt();
-            t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+    public void testBlockingTake() throws InterruptedException {
+        final ArrayBlockingQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
@@ -478,7 +416,7 @@
     public void testPoll() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.poll()).intValue());
+            assertEquals(i, q.poll());
         }
         assertNull(q.poll());
     }
@@ -486,86 +424,70 @@
     /**
      * timed pool with zero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll0() {
-        try {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue());
-            }
-            assertNull(q.poll(0, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTimedPoll0() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
     }
 
     /**
      * timed pool with nonzero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll() {
-        try {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
-            }
-            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTimedPoll() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
+        }
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
     }
 
     /**
      * Interrupted timed poll throws InterruptedException instead of
      * returning timeout status
      */
-    public void testInterruptedTimedPoll() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        ArrayBlockingQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
-                        }
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch (InterruptedException success){
-                    }   
-                }});
-        try { 
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS); 
-            t.interrupt();
-            t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                ArrayBlockingQueue q = populatedQueue(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));;
+                }
+                try {
+                    q.poll(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  timed poll before a delayed offer fails; after offer succeeds;
      *  on interruption throws
      */
-    public void testTimedPollWithOffer() {
+    public void testTimedPollWithOffer() throws InterruptedException {
         final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success) { }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
-    }  
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
 
 
     /**
@@ -574,10 +496,10 @@
     public void testPeek() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.peek()).intValue());
-            q.poll();
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
             assertTrue(q.peek() == null ||
-                       i != ((Integer)q.peek()).intValue());
+                       !q.peek().equals(i));
         }
         assertNull(q.peek());
     }
@@ -588,14 +510,13 @@
     public void testElement() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.element()).intValue());
-            q.poll();
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
         }
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -604,13 +525,12 @@
     public void testRemove() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.remove()).intValue());
+            assertEquals(i, q.remove());
         }
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-        }   
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -627,7 +547,7 @@
         }
         assertTrue(q.isEmpty());
     }
-        
+
     /**
      * contains(x) reports true when elements added but not yet removed
      */
@@ -635,7 +555,7 @@
         ArrayBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(q.contains(new Integer(i)));
-            q.poll();
+            assertEquals(i, q.poll());
             assertFalse(q.contains(new Integer(i)));
         }
     }
@@ -708,68 +628,56 @@
     /**
      *  toArray contains all elements
      */
-    public void testToArray() {
+    public void testToArray() throws InterruptedException {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         Object[] o = q.toArray();
-        try {
-        for(int i = 0; i < o.length; i++)
+        for (int i = 0; i < o.length; i++)
             assertEquals(o[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
     }
 
     /**
      * toArray(a) contains all elements
      */
-    public void testToArray2() {
+    public void testToArray2() throws InterruptedException {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         Integer[] ints = new Integer[SIZE];
         ints = (Integer[])q.toArray(ints);
-        try {
-            for(int i = 0; i < ints.length; i++)
-                assertEquals(ints[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.take());
     }
 
     /**
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
         try {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
             Object o[] = q.toArray(null);
             shouldThrow();
-        } catch(NullPointerException success){}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * toArray with incompatible array type throws CCE
      */
     public void testToArray1_BadArg() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
         try {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
-            Object o[] = q.toArray(new String[10] );
+            Object o[] = q.toArray(new String[10]);
             shouldThrow();
-        } catch(ArrayStoreException  success){}
+        } catch (ArrayStoreException success) {}
     }
 
-    
+
     /**
      * iterator iterates through all elements
      */
-    public void testIterator() {
+    public void testIterator() throws InterruptedException {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         Iterator it = q.iterator();
-        try {
-            while(it.hasNext()){
-                assertEquals(it.next(), q.take());
-            }
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
+        while (it.hasNext()) {
+            assertEquals(it.next(), q.take());
+        }
     }
 
     /**
@@ -784,10 +692,10 @@
         Iterator it = q.iterator();
         it.next();
         it.remove();
-        
+
         it = q.iterator();
-        assertEquals(it.next(), one);
-        assertEquals(it.next(), three);
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
         assertFalse(it.hasNext());
     }
 
@@ -804,8 +712,7 @@
 
         int k = 0;
         for (Iterator it = q.iterator(); it.hasNext();) {
-            int i = ((Integer)(it.next())).intValue();
-            assertEquals(++k, i);
+            assertEquals(++k, it.next());
         }
         assertEquals(3, k);
     }
@@ -818,14 +725,9 @@
         q.add(one);
         q.add(two);
         q.add(three);
-        try {
-            for (Iterator it = q.iterator(); it.hasNext();) {
-                q.remove();
-                it.next();
-            }
-        }
-        catch (ConcurrentModificationException e) {
-            unexpectedException();
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
         }
         assertEquals(0, q.size());
     }
@@ -840,7 +742,7 @@
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
 
     /**
@@ -851,33 +753,20 @@
         q.add(one);
         q.add(two);
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertFalse(q.offer(three));
-                try {
-                    threadAssertTrue(q.offer(three, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertEquals(0, q.remainingCapacity());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(q.offer(three));
+                assertTrue(q.offer(three, MEDIUM_DELAY_MS, MILLISECONDS));
+                assertEquals(0, q.remainingCapacity());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    threadAssertEquals(one, q.take());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
-        
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                assertSame(one, q.take());
+            }});
+
         joinPool(executor);
-
     }
 
     /**
@@ -886,91 +775,73 @@
     public void testPollInExecutor() {
         final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertNull(q.poll());
-                try {
-                    threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertTrue(q.isEmpty());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll());
+                assertSame(one, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(q.isEmpty());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    q.put(one);
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
-        
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                q.put(one);
+            }});
+
         joinPool(executor);
     }
 
     /**
      * A deserialized serialized queue has same elements in same order
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         ArrayBlockingQueue q = populatedQueue(SIZE);
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            ArrayBlockingQueue r = (ArrayBlockingQueue)in.readObject();
-            assertEquals(q.size(), r.size());
-            while (!q.isEmpty()) 
-                assertEquals(q.remove(), r.remove());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ArrayBlockingQueue r = (ArrayBlockingQueue)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
     }
 
     /**
      * drainTo(null) throws NPE
-     */ 
+     */
     public void testDrainToNull() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(null);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this) throws IAE
-     */ 
+     */
     public void testDrainToSelf() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(q);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c) empties queue into another collection c
-     */ 
+     */
     public void testDrainTo() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         ArrayList l = new ArrayList();
         q.drainTo(l);
         assertEquals(q.size(), 0);
         assertEquals(l.size(), SIZE);
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertEquals(l.get(i), new Integer(i));
         q.add(zero);
         q.add(one);
@@ -981,80 +852,69 @@
         q.drainTo(l);
         assertEquals(q.size(), 0);
         assertEquals(l.size(), 2);
-        for (int i = 0; i < 2; ++i) 
+        for (int i = 0; i < 2; ++i)
             assertEquals(l.get(i), new Integer(i));
     }
 
     /**
      * drainTo empties full queue, unblocking a waiting put.
-     */ 
-    public void testDrainToWithActivePut() {
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
         final ArrayBlockingQueue q = populatedQueue(SIZE);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new Integer(SIZE+1));
-                    } catch (InterruptedException ie){ 
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            ArrayList l = new ArrayList();
-            q.drainTo(l);
-            assertTrue(l.size() >= SIZE);
-            for (int i = 0; i < SIZE; ++i) 
-                assertEquals(l.get(i), new Integer(i));
-            t.join();
-            assertTrue(q.size() + l.size() >= SIZE);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(SIZE+1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
     }
 
     /**
      * drainTo(null, n) throws NPE
-     */ 
+     */
     public void testDrainToNullN() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(null, 0);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this, n) throws IAE
-     */ 
+     */
     public void testDrainToSelfN() {
         ArrayBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(q, 0);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c, n) empties first max {n, size} elements of queue into c
-     */ 
+     */
     public void testDrainToN() {
         ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE*2);
         for (int i = 0; i < SIZE + 2; ++i) {
-            for(int j = 0; j < SIZE; j++)
+            for (int j = 0; j < SIZE; j++)
                 assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE)? i : SIZE;
             assertEquals(l.size(), k);
             assertEquals(q.size(), SIZE-k);
-            for (int j = 0; j < k; ++j) 
+            for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
             while (q.poll() != null) ;
         }
     }
 
-
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayDequeTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayDequeTest.java
new file mode 100644
index 0000000..cec1d58
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ArrayDequeTest.java
@@ -0,0 +1,630 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+public class ArrayDequeTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ArrayDequeTest.class);
+    }
+
+    /**
+     * Create a queue of given size containing consecutive
+     * Integers 0 ... n.
+     */
+    private ArrayDeque populatedDeque(int n) {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; ++i)
+            assertTrue(q.offerLast(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        return q;
+    }
+
+    /**
+     * new queue is empty
+     */
+    public void testConstructor1() {
+        assertEquals(0, new ArrayDeque().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            ArrayDeque q = new ArrayDeque((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayDeque q = new ArrayDeque(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.removeFirst();
+        q.removeFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i, q.size());
+            q.removeFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * push(null) throws NPE
+     */
+    public void testPushNull() {
+        try {
+            ArrayDeque q = new ArrayDeque(1);
+            q.push(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * peekFirst returns element inserted with push
+     */
+    public void testPush() {
+        ArrayDeque q = populatedDeque(3);
+        q.pollLast();
+        q.push(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     *  pop removes next element, or throws NSEE if empty
+     */
+    public void testPop() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pop());
+        }
+        try {
+            q.pop();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferFirstNull() {
+        try {
+            ArrayDeque q = new ArrayDeque();
+            q.offerFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * OfferFirst succeeds
+     */
+    public void testOfferFirst() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.offerFirst(new Integer(0)));
+        assertTrue(q.offerFirst(new Integer(1)));
+    }
+
+    /**
+     * OfferLast succeeds
+     */
+    public void testOfferLast() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.offerLast(new Integer(0)));
+        assertTrue(q.offerLast(new Integer(1)));
+    }
+
+    /**
+     * add succeeds
+     */
+    public void testAdd() {
+        ArrayDeque q = new ArrayDeque();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            assertTrue(q.add(new Integer(i)));
+        }
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        try {
+            ArrayDeque q = new ArrayDeque();
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayDeque q = new ArrayDeque();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     *  pollFirst succeeds unless empty
+     */
+    public void testPollFirst() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     *  pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollLast());
+    }
+
+    /**
+     *  poll succeeds unless empty
+     */
+    public void testPoll() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     *  remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     *  peekFirst returns next element, or null if empty
+     */
+    public void testPeekFirst() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peekFirst());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peekFirst() == null ||
+                       !q.peekFirst().equals(i));
+        }
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     *  peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     *  peekLast returns next element, or null if empty
+     */
+    public void testPeekLast() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.peekLast());
+            assertEquals(i, q.pollLast());
+            assertTrue(q.peekLast() == null ||
+                       !q.peekLast().equals(i));
+        }
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * getFirst returns next getFirst, or throws NSEE if empty
+     */
+    public void testFirstElement() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.getFirst());
+            assertEquals(i, q.pollFirst());
+        }
+        try {
+            q.getFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     *  getLast returns next element, or throws NSEE if empty
+     */
+    public void testLastElement() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.getLast());
+            assertEquals(i, q.pollLast());
+        }
+        try {
+            q.getLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+
+    /**
+     *  removeFirst removes next element, or throws NSEE if empty
+     */
+    public void testRemoveFirst() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.removeFirst());
+        }
+        try {
+            q.removeFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * removeFirstOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveFirstOccurrence() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * removeLastOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveLastOccurrence() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+            assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            assertEquals(i, q.pollFirst());
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        ArrayDeque q = populatedDeque(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertTrue(q.add(new Integer(1)));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ArrayDeque q = populatedDeque(SIZE);
+        ArrayDeque p = new ArrayDeque();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            assertTrue(p.add(new Integer(i)));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        ArrayDeque q = populatedDeque(SIZE);
+        ArrayDeque p = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            assertEquals(changed, (i > 0));
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE-i, q.size());
+            p.removeFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ArrayDeque q = populatedDeque(SIZE);
+            ArrayDeque p = populatedDeque(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE-i, q.size());
+            for (int j = 0; j < i; ++j) {
+                assertFalse(q.contains(p.removeFirst()));
+            }
+        }
+    }
+
+    /**
+     *  toArray contains all elements
+     */
+    public void testToArray() {
+        ArrayDeque q = populatedDeque(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.pollFirst());
+    }
+
+    /**
+     *  toArray(a) contains all elements
+     */
+    public void testToArray2() {
+        ArrayDeque q = populatedDeque(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        ints = (Integer[])q.toArray(ints);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(null) throws NPE
+     */
+    public void testToArray_BadArg() {
+        ArrayDeque l = new ArrayDeque();
+        l.add(new Object());
+        try {
+            Object o[] = l.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray with incompatible array type throws CCE
+     */
+    public void testToArray1_BadArg() {
+        ArrayDeque l = new ArrayDeque();
+        l.add(new Integer(5));
+        try {
+            Object o[] = l.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     *  iterator iterates through all elements
+     */
+    public void testIterator() {
+        ArrayDeque q = populatedDeque(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+    }
+
+    /**
+     *  iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final ArrayDeque q = new ArrayDeque();
+        q.add(new Integer(1));
+        q.add(new Integer(2));
+        q.add(new Integer(3));
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+
+        assertEquals(3, k);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove () {
+        final ArrayDeque q = new ArrayDeque();
+        final Random rng = new Random();
+        for (int iters = 0; iters < 100; ++iters) {
+            int max = rng.nextInt(5) + 2;
+            int split = rng.nextInt(max-1) + 1;
+            for (int j = 1; j <= max; ++j)
+                q.add(new Integer(j));
+            Iterator it = q.iterator();
+            for (int j = 1; j <= split; ++j)
+                assertEquals(it.next(), new Integer(j));
+            it.remove();
+            assertEquals(it.next(), new Integer(split+1));
+            for (int j = 1; j <= split; ++j)
+                q.remove(new Integer(j));
+            it = q.iterator();
+            for (int j = split+1; j <= max; ++j) {
+                assertEquals(it.next(), new Integer(j));
+                it.remove();
+            }
+            assertFalse(it.hasNext());
+            assertTrue(q.isEmpty());
+        }
+    }
+
+    /**
+     *  Descending iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        ArrayDeque q = populatedDeque(SIZE);
+        int i = 0;
+        Iterator it = q.descendingIterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     *  Descending iterator ordering is reverse FIFO
+     */
+    public void testDescendingIteratorOrdering() {
+        final ArrayDeque q = new ArrayDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            int k = 0;
+            for (Iterator it = q.descendingIterator(); it.hasNext();) {
+                assertEquals(++k, it.next());
+            }
+
+            assertEquals(3, k);
+            q.remove();
+            q.remove();
+            q.remove();
+        }
+    }
+
+    /**
+     * descendingIterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove () {
+        final ArrayDeque q = new ArrayDeque();
+        final Random rng = new Random();
+        for (int iters = 0; iters < 100; ++iters) {
+            int max = rng.nextInt(5) + 2;
+            int split = rng.nextInt(max-1) + 1;
+            for (int j = max; j >= 1; --j)
+                q.add(new Integer(j));
+            Iterator it = q.descendingIterator();
+            for (int j = 1; j <= split; ++j)
+                assertEquals(it.next(), new Integer(j));
+            it.remove();
+            assertEquals(it.next(), new Integer(split+1));
+            for (int j = 1; j <= split; ++j)
+                q.remove(new Integer(j));
+            it = q.descendingIterator();
+            for (int j = split+1; j <= max; ++j) {
+                assertEquals(it.next(), new Integer(j));
+                it.remove();
+            }
+            assertFalse(it.hasNext());
+            assertTrue(q.isEmpty());
+        }
+    }
+
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        ArrayDeque q = populatedDeque(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    /**
+     * peekFirst returns element inserted with addFirst
+     */
+    public void testAddFirst() {
+        ArrayDeque q = populatedDeque(3);
+        q.addFirst(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * peekLast returns element inserted with addLast
+     */
+    public void testAddLast() {
+        ArrayDeque q = populatedDeque(3);
+        q.addLast(four);
+        assertSame(four, q.peekLast());
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java
index 230357a..b2d91b8 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicBooleanTest.java
@@ -2,20 +2,17 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 import java.io.*;
 
 public class AtomicBooleanTest extends JSR166TestCase {
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicBooleanTest.class);
     }
@@ -24,8 +21,8 @@
      * constructor initializes to given value
      */
     public void testConstructor() {
-        AtomicBoolean ai = new AtomicBoolean(true);
-        assertEquals(true,ai.get());
+        assertTrue(new AtomicBoolean(true).get());
+        assertFalse(new AtomicBoolean(false).get());
     }
 
     /**
@@ -33,7 +30,7 @@
      */
     public void testConstructor2() {
         AtomicBoolean ai = new AtomicBoolean();
-        assertEquals(false,ai.get());
+        assertFalse(ai.get());
     }
 
     /**
@@ -41,12 +38,23 @@
      */
     public void testGetSet() {
         AtomicBoolean ai = new AtomicBoolean(true);
-        assertEquals(true,ai.get());
+        assertTrue(ai.get());
         ai.set(false);
-        assertEquals(false,ai.get());
+        assertFalse(ai.get());
         ai.set(true);
-        assertEquals(true,ai.get());
-        
+        assertTrue(ai.get());
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicBoolean ai = new AtomicBoolean(true);
+        assertTrue(ai.get());
+        ai.lazySet(false);
+        assertFalse(ai.get());
+        ai.lazySet(true);
+        assertTrue(ai.get());
     }
 
     /**
@@ -55,48 +63,44 @@
     public void testCompareAndSet() {
         AtomicBoolean ai = new AtomicBoolean(true);
         assertTrue(ai.compareAndSet(true,false));
-        assertEquals(false,ai.get());
+        assertFalse(ai.get());
         assertTrue(ai.compareAndSet(false,false));
-        assertEquals(false,ai.get());
+        assertFalse(ai.get());
         assertFalse(ai.compareAndSet(true,false));
-        assertFalse((ai.get()));
+        assertFalse(ai.get());
         assertTrue(ai.compareAndSet(false,true));
-        assertEquals(true,ai.get());
+        assertTrue(ai.get());
     }
 
     /**
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicBoolean ai = new AtomicBoolean(true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(false, true)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(true, false));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(false, true)) Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(true, false));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
     public void testWeakCompareAndSet() {
         AtomicBoolean ai = new AtomicBoolean(true);
-        while(!ai.weakCompareAndSet(true,false));
-        assertEquals(false,ai.get());
-        while(!ai.weakCompareAndSet(false,false));
-        assertEquals(false,ai.get());
-        while(!ai.weakCompareAndSet(false,true));
-        assertEquals(true,ai.get());
+        while (!ai.weakCompareAndSet(true,false));
+        assertFalse(ai.get());
+        while (!ai.weakCompareAndSet(false,false));
+        assertFalse(ai.get());
+        while (!ai.weakCompareAndSet(false,true));
+        assertTrue(ai.get());
     }
 
     /**
@@ -107,37 +111,32 @@
         assertEquals(true,ai.getAndSet(false));
         assertEquals(false,ai.getAndSet(false));
         assertEquals(false,ai.getAndSet(true));
-        assertEquals(true,ai.get());
+        assertTrue(ai.get());
     }
 
     /**
      * a deserialized serialized atomic holds same value
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         AtomicBoolean l = new AtomicBoolean();
 
-        try {
-            l.set(true);
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        l.set(true);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicBoolean r = (AtomicBoolean) in.readObject();
-            assertEquals(l.get(), r.get());
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicBoolean r = (AtomicBoolean) in.readObject();
+        assertEquals(l.get(), r.get());
     }
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
-        AtomicBoolean ai = new AtomicBoolean(); 
+        AtomicBoolean ai = new AtomicBoolean();
         assertEquals(ai.toString(), Boolean.toString(false));
         ai.set(true);
         assertEquals(ai.toString(), Boolean.toString(true));
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java
index cd13fcf..838296d 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerArrayTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
@@ -14,10 +14,6 @@
 import java.util.*;
 
 public class AtomicIntegerArrayTest extends JSR166TestCase {
-
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicIntegerArrayTest.class);
     }
@@ -28,7 +24,7 @@
      */
     public void testConstructor() {
         AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertEquals(0,ai.get(i));
     }
 
@@ -39,10 +35,8 @@
         try {
             int[] a = null;
             AtomicIntegerArray ai = new AtomicIntegerArray(a);
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -52,30 +46,34 @@
         int[] a = { 17, 3, -42, 99, -7};
         AtomicIntegerArray ai = new AtomicIntegerArray(a);
         assertEquals(a.length, ai.length());
-        for (int i = 0; i < a.length; ++i) 
+        for (int i = 0; i < a.length; ++i)
             assertEquals(a[i], ai.get(i));
     }
 
     /**
      * get and set for out of bound indices throw IndexOutOfBoundsException
      */
-    public void testIndexing(){
+    public void testIndexing() {
         AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         try {
             ai.get(SIZE);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.get(-1);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.set(SIZE, 0);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.set(-1, 0);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
     }
 
@@ -83,7 +81,7 @@
      * get returns the last value set at index
      */
     public void testGetSet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.get(i));
@@ -95,17 +93,32 @@
     }
 
     /**
+     * get returns the last value lazySet at index by same thread
+     */
+    public void testGetLazySet() {
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            ai.lazySet(i, 1);
+            assertEquals(1,ai.get(i));
+            ai.lazySet(i, 2);
+            assertEquals(2,ai.get(i));
+            ai.lazySet(i, -3);
+            assertEquals(-3,ai.get(i));
+        }
+    }
+
+    /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
     public void testCompareAndSet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertTrue(ai.compareAndSet(i, 1,2));
             assertTrue(ai.compareAndSet(i, 2,-4));
             assertEquals(-4,ai.get(i));
             assertFalse(ai.compareAndSet(i, -5,7));
-            assertFalse((7 == ai.get(i)));
+            assertEquals(-4,ai.get(i));
             assertTrue(ai.compareAndSet(i, -4,7));
             assertEquals(7,ai.get(i));
         }
@@ -115,37 +128,34 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicIntegerArray a = new AtomicIntegerArray(1);
         a.set(0, 1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!a.compareAndSet(0, 2, 3)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(a.compareAndSet(0, 1, 2));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(a.get(0), 3);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(0, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(0, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(a.get(0), 3);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
     public void testWeakCompareAndSet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
-            while(!ai.weakCompareAndSet(i, 1,2));
-            while(!ai.weakCompareAndSet(i, 2,-4));
+            while (!ai.weakCompareAndSet(i, 1,2));
+            while (!ai.weakCompareAndSet(i, 2,-4));
             assertEquals(-4,ai.get(i));
-            while(!ai.weakCompareAndSet(i, -4,7));
+            while (!ai.weakCompareAndSet(i, -4,7));
             assertEquals(7,ai.get(i));
         }
     }
@@ -154,7 +164,7 @@
      *  getAndSet returns previous value and sets to given value at given index
      */
     public void testGetAndSet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndSet(i,0));
@@ -167,7 +177,7 @@
      *  getAndAdd returns previous value and adds given value
      */
     public void testGetAndAdd() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndAdd(i,2));
@@ -181,7 +191,7 @@
      * getAndDecrement returns previous value and decrements
      */
     public void testGetAndDecrement() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndDecrement(i));
@@ -194,7 +204,7 @@
      * getAndIncrement returns previous value and increments
      */
     public void testGetAndIncrement() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndIncrement(i));
@@ -211,7 +221,7 @@
      *  addAndGet adds given value to current, and returns current value
      */
     public void testAddAndGet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(3,ai.addAndGet(i,2));
@@ -225,7 +235,7 @@
      * decrementAndGet decrements and returns current value
      */
     public void testDecrementAndGet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(0,ai.decrementAndGet(i));
@@ -239,7 +249,7 @@
      *  incrementAndGet increments and returns current value
      */
     public void testIncrementAndGet() {
-        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
+        AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(2,ai.incrementAndGet(i));
@@ -253,7 +263,7 @@
     }
 
     static final int COUNTDOWN = 100000;
-    
+
     class Counter implements Runnable {
         final AtomicIntegerArray ai;
         volatile int counts;
@@ -280,57 +290,47 @@
      * Multiple threads using same array of counters successfully
      * update a number of times equal to total count
      */
-    public void testCountingInMultipleThreads() {
-        try {
-            final AtomicIntegerArray ai = new AtomicIntegerArray(SIZE); 
-            for (int i = 0; i < SIZE; ++i) 
-                ai.set(i, COUNTDOWN);
-            Counter c1 = new Counter(ai);
-            Counter c2 = new Counter(ai);
-            Thread t1 = new Thread(c1);
-            Thread t2 = new Thread(c2);
-            t1.start();
-            t2.start();
-            t1.join();
-            t2.join();
-            assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN);
-        }
-        catch(InterruptedException ie) {
-            unexpectedException();
-        }
+    public void testCountingInMultipleThreads() throws InterruptedException {
+        final AtomicIntegerArray ai = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            ai.set(i, COUNTDOWN);
+        Counter c1 = new Counter(ai);
+        Counter c2 = new Counter(ai);
+        Thread t1 = new Thread(c1);
+        Thread t2 = new Thread(c2);
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+        assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN);
     }
 
 
     /**
      * a deserialized serialized array holds same values
      */
-    public void testSerialization() {
-        AtomicIntegerArray l = new AtomicIntegerArray(SIZE); 
-        for (int i = 0; i < SIZE; ++i) 
+    public void testSerialization() throws Exception {
+        AtomicIntegerArray l = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; ++i)
             l.set(i, -i);
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicIntegerArray r = (AtomicIntegerArray) in.readObject();
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(l.get(i), r.get(i));
-            }
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicIntegerArray r = (AtomicIntegerArray) in.readObject();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(l.get(i), r.get(i));
         }
     }
 
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
         int[] a = { 17, 3, -42, 99, -7};
         AtomicIntegerArray ai = new AtomicIntegerArray(a);
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java
index 4c3ecb4..383e30b 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerFieldUpdaterTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import java.util.concurrent.atomic.*;
 import junit.framework.*;
@@ -16,9 +16,6 @@
     volatile int x = 0;
     int w;
     long z;
-    public static void main(String[] args){
-        junit.textui.TestRunner.run(suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicIntegerFieldUpdaterTest.class);
     }
@@ -27,60 +24,36 @@
      * Construction with non-existent field throws RuntimeException
      */
     public void testConstructor() {
-        try{
-            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> 
+        try {
+            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest>
                 a = AtomicIntegerFieldUpdater.newUpdater
                 (AtomicIntegerFieldUpdaterTest.class, "y");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      * construction with field not of given type throws RuntimeException
      */
     public void testConstructor2() {
-        try{
-            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> 
+        try {
+            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest>
                 a = AtomicIntegerFieldUpdater.newUpdater
                 (AtomicIntegerFieldUpdaterTest.class, "z");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      * construction with non-volatile field throws RuntimeException
      */
     public void testConstructor3() {
-        try{
-            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> 
+        try {
+            AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest>
                 a = AtomicIntegerFieldUpdater.newUpdater
                 (AtomicIntegerFieldUpdaterTest.class, "w");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
-    }
-
-    static class Base {
-        protected volatile int f = 0;
-    }
-    static class Sub1 extends Base {
-        AtomicIntegerFieldUpdater<Base> fUpdater
-                = AtomicIntegerFieldUpdater.newUpdater(Base.class, "f");
-    }
-    static class Sub2 extends Base {}
-
-    public void testProtectedFieldOnAnotherSubtype() {
-        Sub1 sub1 = new Sub1();
-        Sub2 sub2 = new Sub2();
-
-        sub1.fUpdater.set(sub1, 1);
-        try {
-            sub1.fUpdater.set(sub2, 2);
-            shouldThrow();
-        } 
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
@@ -99,7 +72,24 @@
         assertEquals(2,a.get(this));
         a.set(this,-3);
         assertEquals(-3,a.get(this));
-        
+    }
+
+    /**
+     *  get returns the last value lazySet by same thread
+     */
+    public void testGetLazySet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        try {
+            a = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class, "x");
+        } catch (RuntimeException ok) {
+            return;
+        }
+        x = 1;
+        assertEquals(1,a.get(this));
+        a.lazySet(this,2);
+        assertEquals(2,a.get(this));
+        a.lazySet(this,-3);
+        assertEquals(-3,a.get(this));
     }
 
     /**
@@ -117,7 +107,7 @@
         assertTrue(a.compareAndSet(this,2,-4));
         assertEquals(-4,a.get(this));
         assertFalse(a.compareAndSet(this,-5,7));
-        assertFalse((7 == a.get(this)));
+        assertEquals(-4,a.get(this));
         assertTrue(a.compareAndSet(this,-4,7));
         assertEquals(7,a.get(this));
     }
@@ -127,7 +117,7 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         x = 1;
         final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest>a;
         try {
@@ -136,25 +126,22 @@
             return;
         }
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(a.compareAndSet(this, 1, 2));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(a.get(this), 3);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(this, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(a.get(this), 3);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
     public void testWeakCompareAndSet() {
         AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
@@ -164,10 +151,10 @@
             return;
         }
         x = 1;
-        while(!a.weakCompareAndSet(this,1,2));
-        while(!a.weakCompareAndSet(this,2,-4));
+        while (!a.weakCompareAndSet(this,1,2));
+        while (!a.weakCompareAndSet(this,2,-4));
         assertEquals(-4,a.get(this));
-        while(!a.weakCompareAndSet(this,-4,7));
+        while (!a.weakCompareAndSet(this,-4,7));
         assertEquals(7,a.get(this));
     }
 
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java
index d484785..a2f3b4b 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicIntegerTest.java
@@ -2,28 +2,29 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 import java.io.*;
 
 public class AtomicIntegerTest extends JSR166TestCase {
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicIntegerTest.class);
     }
 
+    final int[] VALUES = {
+        Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
+    };
+
     /**
      * constructor initializes to given value
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(1,ai.get());
     }
@@ -31,7 +32,7 @@
     /**
      * default constructed initializes to zero
      */
-    public void testConstructor2(){
+    public void testConstructor2() {
         AtomicInteger ai = new AtomicInteger();
         assertEquals(0,ai.get());
     }
@@ -39,26 +40,37 @@
     /**
      * get returns the last value set
      */
-    public void testGetSet(){
+    public void testGetSet() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(1,ai.get());
         ai.set(2);
         assertEquals(2,ai.get());
         ai.set(-3);
         assertEquals(-3,ai.get());
-        
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1,ai.get());
+        ai.lazySet(2);
+        assertEquals(2,ai.get());
+        ai.lazySet(-3);
+        assertEquals(-3,ai.get());
     }
 
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         AtomicInteger ai = new AtomicInteger(1);
         assertTrue(ai.compareAndSet(1,2));
         assertTrue(ai.compareAndSet(2,-4));
         assertEquals(-4,ai.get());
         assertFalse(ai.compareAndSet(-5,7));
-        assertFalse((7 == ai.get()));
+        assertEquals(-4,ai.get());
         assertTrue(ai.compareAndSet(-4,7));
         assertEquals(7,ai.get());
     }
@@ -67,41 +79,38 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicInteger ai = new AtomicInteger(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(2, 3)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(1, 2));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.get(), 3);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(ai.get(), 3);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         AtomicInteger ai = new AtomicInteger(1);
-        while(!ai.weakCompareAndSet(1,2));
-        while(!ai.weakCompareAndSet(2,-4));
+        while (!ai.weakCompareAndSet(1,2));
+        while (!ai.weakCompareAndSet(2,-4));
         assertEquals(-4,ai.get());
-        while(!ai.weakCompareAndSet(-4,7));
+        while (!ai.weakCompareAndSet(-4,7));
         assertEquals(7,ai.get());
     }
 
     /**
      * getAndSet returns previous value and sets to given value
      */
-    public void testGetAndSet(){
+    public void testGetAndSet() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(1,ai.getAndSet(0));
         assertEquals(0,ai.getAndSet(-10));
@@ -111,7 +120,7 @@
     /**
      * getAndAdd returns previous value and adds given value
      */
-    public void testGetAndAdd(){
+    public void testGetAndAdd() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(1,ai.getAndAdd(2));
         assertEquals(3,ai.get());
@@ -122,7 +131,7 @@
     /**
      * getAndDecrement returns previous value and decrements
      */
-    public void testGetAndDecrement(){
+    public void testGetAndDecrement() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(1,ai.getAndDecrement());
         assertEquals(0,ai.getAndDecrement());
@@ -132,7 +141,7 @@
     /**
      * getAndIncrement returns previous value and increments
      */
-    public void testGetAndIncrement(){
+    public void testGetAndIncrement() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(1,ai.getAndIncrement());
         assertEquals(2,ai.get());
@@ -146,7 +155,7 @@
     /**
      * addAndGet adds given value to current, and returns current value
      */
-    public void testAddAndGet(){
+    public void testAddAndGet() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(3,ai.addAndGet(2));
         assertEquals(3,ai.get());
@@ -157,7 +166,7 @@
     /**
      * decrementAndGet decrements and returns current value
      */
-    public void testDecrementAndGet(){
+    public void testDecrementAndGet() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(0,ai.decrementAndGet());
         assertEquals(-1,ai.decrementAndGet());
@@ -168,7 +177,7 @@
     /**
      * incrementAndGet increments and returns current value
      */
-    public void testIncrementAndGet(){
+    public void testIncrementAndGet() {
         AtomicInteger ai = new AtomicInteger(1);
         assertEquals(2,ai.incrementAndGet());
         assertEquals(2,ai.get());
@@ -182,81 +191,79 @@
     /**
      * a deserialized serialized atomic holds same value
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         AtomicInteger l = new AtomicInteger();
 
-        try {
-            l.set(22);
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        l.set(22);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicInteger r = (AtomicInteger) in.readObject();
-            assertEquals(l.get(), r.get());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicInteger r = (AtomicInteger) in.readObject();
+        assertEquals(l.get(), r.get());
     }
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
         AtomicInteger ai = new AtomicInteger();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals(ai.toString(), Integer.toString(i));
+        assertEquals("0", ai.toString());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals(ai.toString(), Integer.toString(x));
         }
     }
 
     /**
      * intValue returns current value.
-     */ 
+     */
     public void testIntValue() {
         AtomicInteger ai = new AtomicInteger();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals(i, ai.intValue());
+        assertEquals(0, ai.intValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals(x, ai.intValue());
         }
     }
 
-
     /**
      * longValue returns current value.
-     */ 
+     */
     public void testLongValue() {
         AtomicInteger ai = new AtomicInteger();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals((long)i, ai.longValue());
+        assertEquals(0L, ai.longValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals((long)x, ai.longValue());
         }
     }
 
     /**
      * floatValue returns current value.
-     */ 
+     */
     public void testFloatValue() {
         AtomicInteger ai = new AtomicInteger();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals((float)i, ai.floatValue());
+        assertEquals(0.0f, ai.floatValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals((float)x, ai.floatValue());
         }
     }
 
     /**
      * doubleValue returns current value.
-     */ 
+     */
     public void testDoubleValue() {
         AtomicInteger ai = new AtomicInteger();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals((double)i, ai.doubleValue());
+        assertEquals(0.0d, ai.doubleValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals((double)x, ai.doubleValue());
         }
     }
 
-
-
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java
index 99ce204..88e0984 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongArrayTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
@@ -14,9 +14,6 @@
 import java.util.*;
 
 public class AtomicLongArrayTest extends JSR166TestCase {
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicLongArrayTest.class);
     }
@@ -24,9 +21,9 @@
     /**
      * constructor creates array of given size with all elements zero
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicLongArray ai = new AtomicLongArray(SIZE);
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertEquals(0,ai.get(i));
     }
 
@@ -37,10 +34,8 @@
         try {
             long[] a = null;
             AtomicLongArray ai = new AtomicLongArray(a);
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -50,38 +45,42 @@
         long[] a = { 17L, 3L, -42L, 99L, -7L};
         AtomicLongArray ai = new AtomicLongArray(a);
         assertEquals(a.length, ai.length());
-        for (int i = 0; i < a.length; ++i) 
+        for (int i = 0; i < a.length; ++i)
             assertEquals(a[i], ai.get(i));
     }
 
     /**
      * get and set for out of bound indices throw IndexOutOfBoundsException
      */
-    public void testIndexing(){
+    public void testIndexing() {
         AtomicLongArray ai = new AtomicLongArray(SIZE);
         try {
             ai.get(SIZE);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.get(-1);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.set(SIZE, 0);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.set(-1, 0);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
     }
 
     /**
      * get returns the last value set at index
      */
-    public void testGetSet(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testGetSet() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.get(i));
@@ -93,17 +92,32 @@
     }
 
     /**
+     * get returns the last value lazySet at index by same thread
+     */
+    public void testGetLazySet() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            ai.lazySet(i, 1);
+            assertEquals(1,ai.get(i));
+            ai.lazySet(i, 2);
+            assertEquals(2,ai.get(i));
+            ai.lazySet(i, -3);
+            assertEquals(-3,ai.get(i));
+        }
+    }
+
+    /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testCompareAndSet() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertTrue(ai.compareAndSet(i, 1,2));
             assertTrue(ai.compareAndSet(i, 2,-4));
             assertEquals(-4,ai.get(i));
             assertFalse(ai.compareAndSet(i, -5,7));
-            assertFalse((7 == ai.get(i)));
+            assertEquals(-4,ai.get(i));
             assertTrue(ai.compareAndSet(i, -4,7));
             assertEquals(7,ai.get(i));
         }
@@ -113,37 +127,34 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws InterruptedException {
         final AtomicLongArray a = new AtomicLongArray(1);
         a.set(0, 1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!a.compareAndSet(0, 2, 3)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(a.compareAndSet(0, 1, 2));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(a.get(0), 3);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(0, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(0, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(a.get(0), 3);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
-    public void testWeakCompareAndSet(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testWeakCompareAndSet() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
-            while(!ai.weakCompareAndSet(i, 1,2));
-            while(!ai.weakCompareAndSet(i, 2,-4));
+            while (!ai.weakCompareAndSet(i, 1,2));
+            while (!ai.weakCompareAndSet(i, 2,-4));
             assertEquals(-4,ai.get(i));
-            while(!ai.weakCompareAndSet(i, -4,7));
+            while (!ai.weakCompareAndSet(i, -4,7));
             assertEquals(7,ai.get(i));
         }
     }
@@ -151,8 +162,8 @@
     /**
      *  getAndSet returns previous value and sets to given value at given index
      */
-    public void testGetAndSet(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testGetAndSet() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndSet(i,0));
@@ -164,8 +175,8 @@
     /**
      *  getAndAdd returns previous value and adds given value
      */
-    public void testGetAndAdd(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testGetAndAdd() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndAdd(i,2));
@@ -178,8 +189,8 @@
     /**
      * getAndDecrement returns previous value and decrements
      */
-    public void testGetAndDecrement(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testGetAndDecrement() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndDecrement(i));
@@ -191,8 +202,8 @@
     /**
      * getAndIncrement returns previous value and increments
      */
-    public void testGetAndIncrement(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testGetAndIncrement() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(1,ai.getAndIncrement(i));
@@ -209,7 +220,7 @@
      *  addAndGet adds given value to current, and returns current value
      */
     public void testAddAndGet() {
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(3,ai.addAndGet(i,2));
@@ -222,8 +233,8 @@
     /**
      * decrementAndGet decrements and returns current value
      */
-    public void testDecrementAndGet(){
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+    public void testDecrementAndGet() {
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(0,ai.decrementAndGet(i));
@@ -237,7 +248,7 @@
      * incrementAndGet increments and returns current value
      */
     public void testIncrementAndGet() {
-        AtomicLongArray ai = new AtomicLongArray(SIZE); 
+        AtomicLongArray ai = new AtomicLongArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, 1);
             assertEquals(2,ai.incrementAndGet(i));
@@ -251,7 +262,7 @@
     }
 
     static final long COUNTDOWN = 100000;
-    
+
     class Counter implements Runnable {
         final AtomicLongArray ai;
         volatile long counts;
@@ -278,54 +289,45 @@
      * Multiple threads using same array of counters successfully
      * update a number of times equal to total count
      */
-    public void testCountingInMultipleThreads() {
-        try {
-            final AtomicLongArray ai = new AtomicLongArray(SIZE); 
-            for (int i = 0; i < SIZE; ++i) 
-                ai.set(i, COUNTDOWN);
-            Counter c1 = new Counter(ai);
-            Counter c2 = new Counter(ai);
-            Thread t1 = new Thread(c1);
-            Thread t2 = new Thread(c2);
-            t1.start();
-            t2.start();
-            t1.join();
-            t2.join();
-            assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN);
-        }
-        catch(InterruptedException ie) {
-            unexpectedException();
-        }
+    public void testCountingInMultipleThreads() throws InterruptedException {
+        final AtomicLongArray ai = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            ai.set(i, COUNTDOWN);
+        Counter c1 = new Counter(ai);
+        Counter c2 = new Counter(ai);
+        Thread t1 = new Thread(c1);
+        Thread t2 = new Thread(c2);
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+        assertEquals(c1.counts+c2.counts, SIZE * COUNTDOWN);
     }
 
     /**
      * a deserialized serialized array holds same values
      */
-    public void testSerialization() {
-        AtomicLongArray l = new AtomicLongArray(SIZE); 
-        for (int i = 0; i < SIZE; ++i) 
+    public void testSerialization() throws Exception {
+        AtomicLongArray l = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; ++i)
             l.set(i, -i);
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicLongArray r = (AtomicLongArray) in.readObject();
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(l.get(i), r.get(i));
-            }
-        } catch(Exception e){
-            unexpectedException();
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicLongArray r = (AtomicLongArray) in.readObject();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(l.get(i), r.get(i));
         }
     }
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
         long[] a = { 17, 3, -42, 99, -7};
         AtomicLongArray ai = new AtomicLongArray(a);
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
index 9310795..491baf4 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongFieldUpdaterTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import java.util.concurrent.atomic.*;
 import junit.framework.*;
@@ -17,9 +17,6 @@
     int z;
     long w;
 
-    public static void main(String[] args){
-        junit.textui.TestRunner.run(suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicLongFieldUpdaterTest.class);
     }
@@ -27,68 +24,43 @@
     /**
      * Construction with non-existent field throws RuntimeException
      */
-    public void testConstructor(){
-        try{
+    public void testConstructor() {
+        try {
             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>
                 a = AtomicLongFieldUpdater.newUpdater
                 (AtomicLongFieldUpdaterTest.class, "y");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      * construction with field not of given type throws RuntimeException
      */
-    public void testConstructor2(){
-        try{
+    public void testConstructor2() {
+        try {
             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>
                 a = AtomicLongFieldUpdater.newUpdater
                 (AtomicLongFieldUpdaterTest.class, "z");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      * construction with non-volatile field throws RuntimeException
      */
-    public void testConstructor3(){
-        try{
+    public void testConstructor3() {
+        try {
             AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>
                 a = AtomicLongFieldUpdater.newUpdater
                 (AtomicLongFieldUpdaterTest.class, "w");
             shouldThrow();
-        }
-
-        catch (RuntimeException rt) {}
-    }
-
-    static class Base {
-        protected volatile long f = 0;
-    }
-    static class Sub1 extends Base {
-        AtomicLongFieldUpdater<Base> fUpdater
-                = AtomicLongFieldUpdater.newUpdater(Base.class, "f");
-    }
-    static class Sub2 extends Base {}
-
-    public void testProtectedFieldOnAnotherSubtype() {
-        Sub1 sub1 = new Sub1();
-        Sub2 sub2 = new Sub2();
-
-        sub1.fUpdater.set(sub1, 1);
-        try {
-            sub1.fUpdater.set(sub2, 2);
-            shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      *  get returns the last value set or assigned
      */
-    public void testGetSet(){
+    public void testGetSet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -96,17 +68,36 @@
             return;
         }
         x = 1;
-	assertEquals(1,a.get(this));
-	a.set(this,2);
-	assertEquals(2,a.get(this));
-	a.set(this,-3);
-	assertEquals(-3,a.get(this));
-
+        assertEquals(1,a.get(this));
+        a.set(this,2);
+        assertEquals(2,a.get(this));
+        a.set(this,-3);
+        assertEquals(-3,a.get(this));
     }
+
+    /**
+     *  get returns the last value lazySet by same thread
+     */
+    public void testGetLazySet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        try {
+            a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
+        } catch (RuntimeException ok) {
+            return;
+        }
+        x = 1;
+        assertEquals(1,a.get(this));
+        a.lazySet(this,2);
+        assertEquals(2,a.get(this));
+        a.lazySet(this,-3);
+        assertEquals(-3,a.get(this));
+    }
+
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -118,7 +109,7 @@
         assertTrue(a.compareAndSet(this,2,-4));
         assertEquals(-4,a.get(this));
         assertFalse(a.compareAndSet(this,-5,7));
-        assertFalse((7 == a.get(this)));
+        assertEquals(-4,a.get(this));
         assertTrue(a.compareAndSet(this,-4,7));
         assertEquals(7,a.get(this));
     }
@@ -128,7 +119,7 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         x = 1;
         final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest>a;
         try {
@@ -137,27 +128,24 @@
             return;
         }
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(a.compareAndSet(this, 1, 2));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(a.get(this), 3);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(this, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(a.get(this), 3);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
      * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -165,17 +153,17 @@
             return;
         }
         x = 1;
-        while(!a.weakCompareAndSet(this,1,2));
-        while(!a.weakCompareAndSet(this,2,-4));
+        while (!a.weakCompareAndSet(this,1,2));
+        while (!a.weakCompareAndSet(this,2,-4));
         assertEquals(-4,a.get(this));
-        while(!a.weakCompareAndSet(this,-4,7));
+        while (!a.weakCompareAndSet(this,-4,7));
         assertEquals(7,a.get(this));
     }
 
     /**
      *  getAndSet returns previous value and sets to given value
      */
-    public void testGetAndSet(){
+    public void testGetAndSet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -191,7 +179,7 @@
     /**
      * getAndAdd returns previous value and adds given value
      */
-    public void testGetAndAdd(){
+    public void testGetAndAdd() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -208,7 +196,7 @@
     /**
      * getAndDecrement returns previous value and decrements
      */
-    public void testGetAndDecrement(){
+    public void testGetAndDecrement() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -224,7 +212,7 @@
     /**
      * getAndIncrement returns previous value and increments
      */
-    public void testGetAndIncrement(){
+    public void testGetAndIncrement() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -244,7 +232,7 @@
     /**
      * addAndGet adds given value to current, and returns current value
      */
-    public void testAddAndGet(){
+    public void testAddAndGet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -261,7 +249,7 @@
     /**
      *  decrementAndGet decrements and returns current value
      */
-    public void testDecrementAndGet(){
+    public void testDecrementAndGet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
@@ -278,7 +266,7 @@
     /**
      * incrementAndGet increments and returns current value
      */
-    public void testIncrementAndGet(){
+    public void testIncrementAndGet() {
         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
         try {
             a = AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdaterTest.class, "x");
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java
index 143c84a..e73e86e 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicLongTest.java
@@ -2,28 +2,31 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 import java.io.*;
 
 public class AtomicLongTest extends JSR166TestCase {
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicLongTest.class);
     }
 
+    final long[] VALUES = {
+        Long.MIN_VALUE,
+        Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
+        Long.MAX_VALUE,
+    };
+
     /**
      * constructor initializes to given value
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(1,ai.get());
     }
@@ -31,7 +34,7 @@
     /**
      * default constructed initializes to zero
      */
-    public void testConstructor2(){
+    public void testConstructor2() {
         AtomicLong ai = new AtomicLong();
         assertEquals(0,ai.get());
     }
@@ -39,26 +42,37 @@
     /**
      * get returns the last value set
      */
-    public void testGetSet(){
+    public void testGetSet() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(1,ai.get());
         ai.set(2);
         assertEquals(2,ai.get());
         ai.set(-3);
         assertEquals(-3,ai.get());
-        
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1,ai.get());
+        ai.lazySet(2);
+        assertEquals(2,ai.get());
+        ai.lazySet(-3);
+        assertEquals(-3,ai.get());
     }
 
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         AtomicLong ai = new AtomicLong(1);
         assertTrue(ai.compareAndSet(1,2));
         assertTrue(ai.compareAndSet(2,-4));
         assertEquals(-4,ai.get());
         assertFalse(ai.compareAndSet(-5,7));
-        assertFalse((7 == ai.get()));
+        assertEquals(-4,ai.get());
         assertTrue(ai.compareAndSet(-4,7));
         assertEquals(7,ai.get());
     }
@@ -67,41 +81,38 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicLong ai = new AtomicLong(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(2, 3)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(1, 2));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.get(), 3);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(ai.get(), 3);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         AtomicLong ai = new AtomicLong(1);
-        while(!ai.weakCompareAndSet(1,2));
-        while(!ai.weakCompareAndSet(2,-4));
+        while (!ai.weakCompareAndSet(1,2));
+        while (!ai.weakCompareAndSet(2,-4));
         assertEquals(-4,ai.get());
-        while(!ai.weakCompareAndSet(-4,7));
+        while (!ai.weakCompareAndSet(-4,7));
         assertEquals(7,ai.get());
     }
 
     /**
      * getAndSet returns previous value and sets to given value
      */
-    public void testGetAndSet(){
+    public void testGetAndSet() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(1,ai.getAndSet(0));
         assertEquals(0,ai.getAndSet(-10));
@@ -111,7 +122,7 @@
     /**
      * getAndAdd returns previous value and adds given value
      */
-    public void testGetAndAdd(){
+    public void testGetAndAdd() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(1,ai.getAndAdd(2));
         assertEquals(3,ai.get());
@@ -122,7 +133,7 @@
     /**
      * getAndDecrement returns previous value and decrements
      */
-    public void testGetAndDecrement(){
+    public void testGetAndDecrement() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(1,ai.getAndDecrement());
         assertEquals(0,ai.getAndDecrement());
@@ -132,7 +143,7 @@
     /**
      * getAndIncrement returns previous value and increments
      */
-    public void testGetAndIncrement(){
+    public void testGetAndIncrement() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(1,ai.getAndIncrement());
         assertEquals(2,ai.get());
@@ -146,7 +157,7 @@
     /**
      * addAndGet adds given value to current, and returns current value
      */
-    public void testAddAndGet(){
+    public void testAddAndGet() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(3,ai.addAndGet(2));
         assertEquals(3,ai.get());
@@ -157,7 +168,7 @@
     /**
      * decrementAndGet decrements and returns current value
      */
-    public void testDecrementAndGet(){
+    public void testDecrementAndGet() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(0,ai.decrementAndGet());
         assertEquals(-1,ai.decrementAndGet());
@@ -168,7 +179,7 @@
     /**
      * incrementAndGet increments and returns current value
      */
-    public void testIncrementAndGet(){
+    public void testIncrementAndGet() {
         AtomicLong ai = new AtomicLong(1);
         assertEquals(2,ai.incrementAndGet());
         assertEquals(2,ai.get());
@@ -182,68 +193,79 @@
     /**
      * a deserialized serialized atomic holds same value
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         AtomicLong l = new AtomicLong();
 
-        try {
-            l.set(-22);
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        l.set(-22);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicLong r = (AtomicLong) in.readObject();
-            assertEquals(l.get(), r.get());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicLong r = (AtomicLong) in.readObject();
+        assertEquals(l.get(), r.get());
     }
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
         AtomicLong ai = new AtomicLong();
-        for (long i = -12; i < 6; ++i) {
+        assertEquals("0", ai.toString());
+        for (long i : VALUES) {
             ai.set(i);
             assertEquals(ai.toString(), Long.toString(i));
         }
     }
 
     /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals(0, ai.intValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((int)x, ai.intValue());
+        }
+    }
+
+    /**
      * longValue returns current value.
-     */ 
+     */
     public void testLongValue() {
         AtomicLong ai = new AtomicLong();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals((long)i, ai.longValue());
+        assertEquals(0L, ai.longValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((long)x, ai.longValue());
         }
     }
 
     /**
      * floatValue returns current value.
-     */ 
+     */
     public void testFloatValue() {
         AtomicLong ai = new AtomicLong();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals((float)i, ai.floatValue());
+        assertEquals(0.0f, ai.floatValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((float)x, ai.floatValue());
         }
     }
 
     /**
      * doubleValue returns current value.
-     */ 
+     */
     public void testDoubleValue() {
         AtomicLong ai = new AtomicLong();
-        for (int i = -12; i < 6; ++i) {
-            ai.set(i);
-            assertEquals((double)i, ai.doubleValue());
+        assertEquals(0.0d, ai.doubleValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((double)x, ai.doubleValue());
         }
     }
 
-
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java
index 7b3dcb1..72a2337 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicMarkableReferenceTest.java
@@ -2,68 +2,64 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 
-public class AtomicMarkableReferenceTest extends JSR166TestCase{
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class AtomicMarkableReferenceTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(AtomicMarkableReferenceTest.class);
     }
-    
+
     /**
      *  constructor initializes to given reference and mark
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
-        assertEquals(one,ai.getReference());
+        assertSame(one,ai.getReference());
         assertFalse(ai.isMarked());
         AtomicMarkableReference a2 = new AtomicMarkableReference(null, true);
         assertNull(a2.getReference());
         assertTrue(a2.isMarked());
-
     }
 
     /**
      *  get returns the last values of reference and mark set
      */
-    public void testGetSet(){
+    public void testGetSet() {
         boolean[] mark = new boolean[1];
         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
-        assertEquals(one,ai.getReference());
+        assertSame(one,ai.getReference());
         assertFalse(ai.isMarked());
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertFalse(mark[0]);
         ai.set(two, false);
-        assertEquals(two,ai.getReference());
+        assertSame(two,ai.getReference());
         assertFalse(ai.isMarked());
-        assertEquals(two, ai.get(mark));
+        assertSame(two, ai.get(mark));
         assertFalse(mark[0]);
         ai.set(one, true);
-        assertEquals(one,ai.getReference());
+        assertSame(one,ai.getReference());
         assertTrue(ai.isMarked());
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertTrue(mark[0]);
     }
 
     /**
      * attemptMark succeeds in single thread
      */
-    public void testAttemptMark(){
+    public void testAttemptMark() {
         boolean[] mark = new boolean[1];
         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
         assertFalse(ai.isMarked());
         assertTrue(ai.attemptMark(one, true));
         assertTrue(ai.isMarked());
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertTrue(mark[0]);
     }
 
@@ -71,23 +67,23 @@
      * compareAndSet succeeds in changing values if equal to expected reference
      * and mark else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         boolean[] mark = new boolean[1];
         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertFalse(ai.isMarked());
         assertFalse(mark[0]);
 
         assertTrue(ai.compareAndSet(one, two, false, false));
-        assertEquals(two, ai.get(mark));
+        assertSame(two, ai.get(mark));
         assertFalse(mark[0]);
 
         assertTrue(ai.compareAndSet(two, m3, false, true));
-        assertEquals(m3, ai.get(mark));
+        assertSame(m3, ai.get(mark));
         assertTrue(mark[0]);
 
         assertFalse(ai.compareAndSet(two, m3, true, true));
-        assertEquals(m3, ai.get(mark));
+        assertSame(m3, ai.get(mark));
         assertTrue(mark[0]);
     }
 
@@ -95,65 +91,59 @@
      * compareAndSet in one thread enables another waiting for reference value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(two, three, false, false)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(one, two, false, false));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.getReference(), three);
-            assertFalse(ai.isMarked());
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(two, three, false, false))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, two, false, false));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(ai.getReference(), three);
+        assertFalse(ai.isMarked());
     }
 
     /**
      * compareAndSet in one thread enables another waiting for mark value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads2() {
+    public void testCompareAndSetInMultipleThreads2() throws Exception {
         final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(one, one, true, false)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(one, one, false, true));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.getReference(), one);
-            assertFalse(ai.isMarked());
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(one, one, true, false))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, one, false, true));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(ai.getReference(), one);
+        assertFalse(ai.isMarked());
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing values when equal
-     * to expected 
+     * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         boolean[] mark = new boolean[1];
         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertFalse(ai.isMarked());
         assertFalse(mark[0]);
 
-        while(!ai.weakCompareAndSet(one, two, false, false));
-        assertEquals(two, ai.get(mark));
+        while (!ai.weakCompareAndSet(one, two, false, false));
+        assertSame(two, ai.get(mark));
         assertFalse(mark[0]);
 
-        while(!ai.weakCompareAndSet(two, m3, false, true));
-        assertEquals(m3, ai.get(mark));
+        while (!ai.weakCompareAndSet(two, m3, false, true));
+        assertSame(m3, ai.get(mark));
         assertTrue(mark[0]);
     }
 
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java
index 9330d39..25f8474 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceArrayTest.java
@@ -2,22 +2,18 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 import java.io.*;
 import java.util.*;
 
-public class AtomicReferenceArrayTest extends JSR166TestCase 
-{
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class AtomicReferenceArrayTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(AtomicReferenceArrayTest.class);
     }
@@ -25,7 +21,7 @@
     /**
      * constructor creates array of given size with all elements null
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             assertNull(ai.get(i));
@@ -39,10 +35,8 @@
         try {
             Integer[] a = null;
             AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(a);
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -52,7 +46,7 @@
         Integer[] a = { two, one, three, four, seven};
         AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(a);
         assertEquals(a.length, ai.length());
-        for (int i = 0; i < a.length; ++i) 
+        for (int i = 0; i < a.length; ++i)
             assertEquals(a[i], ai.get(i));
     }
 
@@ -60,55 +54,74 @@
     /**
      * get and set for out of bound indices throw IndexOutOfBoundsException
      */
-    public void testIndexing(){
+    public void testIndexing() {
         AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(SIZE);
         try {
             ai.get(SIZE);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.get(-1);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.set(SIZE, null);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
         try {
             ai.set(-1, null);
-        } catch(IndexOutOfBoundsException success){
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {
         }
     }
 
     /**
      * get returns the last value set at index
      */
-    public void testGetSet(){
-        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); 
+    public void testGetSet() {
+        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, one);
-            assertEquals(one,ai.get(i));
+            assertSame(one,ai.get(i));
             ai.set(i, two);
-            assertEquals(two,ai.get(i));
+            assertSame(two,ai.get(i));
             ai.set(i, m3);
-            assertEquals(m3,ai.get(i));
+            assertSame(m3,ai.get(i));
+        }
+    }
+
+    /**
+     * get returns the last value lazySet at index by same thread
+     */
+    public void testGetLazySet() {
+        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            ai.lazySet(i, one);
+            assertSame(one,ai.get(i));
+            ai.lazySet(i, two);
+            assertSame(two,ai.get(i));
+            ai.lazySet(i, m3);
+            assertSame(m3,ai.get(i));
         }
     }
 
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
-        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); 
+    public void testCompareAndSet() {
+        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, one);
             assertTrue(ai.compareAndSet(i, one,two));
             assertTrue(ai.compareAndSet(i, two,m4));
-            assertEquals(m4,ai.get(i));
+            assertSame(m4,ai.get(i));
             assertFalse(ai.compareAndSet(i, m5,seven));
-            assertFalse((seven.equals(ai.get(i))));
+            assertSame(m4,ai.get(i));
             assertTrue(ai.compareAndSet(i, m4,seven));
-            assertEquals(seven,ai.get(i));
+            assertSame(seven,ai.get(i));
         }
     }
 
@@ -116,85 +129,78 @@
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws InterruptedException {
         final AtomicReferenceArray a = new AtomicReferenceArray(1);
         a.set(0, one);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!a.compareAndSet(0, two, three)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(a.compareAndSet(0, one, two));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(a.get(0), three);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(0, two, three))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(0, one, two));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(a.get(0), three);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
-     * to expected 
+     * to expected
      */
-    public void testWeakCompareAndSet(){
-        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); 
+    public void testWeakCompareAndSet() {
+        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, one);
-            while(!ai.weakCompareAndSet(i, one,two));
-            while(!ai.weakCompareAndSet(i, two,m4));
-            assertEquals(m4,ai.get(i));
-            while(!ai.weakCompareAndSet(i, m4,seven));
-            assertEquals(seven,ai.get(i));
+            while (!ai.weakCompareAndSet(i, one,two));
+            while (!ai.weakCompareAndSet(i, two,m4));
+            assertSame(m4,ai.get(i));
+            while (!ai.weakCompareAndSet(i, m4,seven));
+            assertSame(seven,ai.get(i));
         }
     }
 
     /**
      * getAndSet returns previous value and sets to given value at given index
      */
-    public void testGetAndSet(){
-        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE); 
+    public void testGetAndSet() {
+        AtomicReferenceArray ai = new AtomicReferenceArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             ai.set(i, one);
-            assertEquals(one,ai.getAndSet(i,zero));
-            assertEquals(0,ai.getAndSet(i,m10));
-            assertEquals(m10,ai.getAndSet(i,one));
+            assertSame(one,ai.getAndSet(i,zero));
+            assertSame(zero,ai.getAndSet(i,m10));
+            assertSame(m10,ai.getAndSet(i,one));
         }
     }
 
     /**
      * a deserialized serialized array holds same values
      */
-    public void testSerialization() {
-        AtomicReferenceArray l = new AtomicReferenceArray(SIZE); 
+    public void testSerialization() throws Exception {
+        AtomicReferenceArray l = new AtomicReferenceArray(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             l.set(i, new Integer(-i));
         }
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicReferenceArray r = (AtomicReferenceArray) in.readObject();
-            assertEquals(l.length(), r.length());
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(r.get(i), l.get(i));
-            }
-        } catch(Exception e){
-            unexpectedException();
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicReferenceArray r = (AtomicReferenceArray) in.readObject();
+        assertEquals(l.length(), r.length());
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(r.get(i), l.get(i));
         }
     }
 
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
         Integer[] a = { two, one, three, four, seven};
         AtomicReferenceArray<Integer> ai = new AtomicReferenceArray<Integer>(a);
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
index feddce7..78c321e 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceFieldUpdaterTest.java
@@ -2,24 +2,21 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import java.util.concurrent.atomic.*;
 import junit.framework.*;
 import java.util.*;
 
-public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase{
+public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase {
     volatile Integer x = null;
     Object z;
     Integer w;
 
-    public static void main(String[] args){
-        junit.textui.TestRunner.run(suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicReferenceFieldUpdaterTest.class);
     }
@@ -27,68 +24,44 @@
     /**
      * Construction with non-existent field throws RuntimeException
      */
-    public void testConstructor(){
-        try{
+    public void testConstructor() {
+        try {
             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>
                 a = AtomicReferenceFieldUpdater.newUpdater
                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "y");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
 
     /**
      * construction with field not of given type throws RuntimeException
      */
-    public void testConstructor2(){
-        try{
+    public void testConstructor2() {
+        try {
             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>
                 a = AtomicReferenceFieldUpdater.newUpdater
                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "z");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      * Constructor with non-volatile field throws exception
      */
-    public void testConstructor3(){
-        try{
+    public void testConstructor3() {
+        try {
             AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>
                 a = AtomicReferenceFieldUpdater.newUpdater
                 (AtomicReferenceFieldUpdaterTest.class, Integer.class, "w");
             shouldThrow();
-        }
-        catch (RuntimeException rt) {}
-    }
-
-    static class Base {
-        protected volatile Object f = null;
-    }
-    static class Sub1 extends Base {
-        AtomicReferenceFieldUpdater<Base, Object> fUpdater
-                = AtomicReferenceFieldUpdater.newUpdater(Base.class, Object.class, "f");
-    }
-    static class Sub2 extends Base {}
-
-    public void testProtectedFieldOnAnotherSubtype() {
-        Sub1 sub1 = new Sub1();
-        Sub2 sub2 = new Sub2();
-
-        sub1.fUpdater.set(sub1, "f");
-        try {
-            sub1.fUpdater.set(sub2, "g");
-            shouldThrow();
-        }
-        catch (RuntimeException rt) {}
+        } catch (RuntimeException success) {}
     }
 
     /**
      *  get returns the last value set or assigned
      */
-    public void testGetSet(){
+    public void testGetSet() {
         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
         try {
             a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
@@ -96,16 +69,35 @@
             return;
         }
         x = one;
-	assertEquals(one,a.get(this));
-	a.set(this,two);
-	assertEquals(two,a.get(this));
-	a.set(this,m3);
-	assertEquals(m3,a.get(this));
+        assertSame(one,a.get(this));
+        a.set(this,two);
+        assertSame(two,a.get(this));
+        a.set(this,m3);
+        assertSame(m3,a.get(this));
     }
+
+    /**
+     *  get returns the last value lazySet by same thread
+     */
+    public void testGetLazySet() {
+        AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
+        try {
+            a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
+        } catch (RuntimeException ok) {
+            return;
+        }
+        x = one;
+        assertSame(one,a.get(this));
+        a.lazySet(this,two);
+        assertSame(two,a.get(this));
+        a.lazySet(this,m3);
+        assertSame(m3,a.get(this));
+    }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
         try {
             a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
@@ -115,18 +107,18 @@
         x = one;
         assertTrue(a.compareAndSet(this,one,two));
         assertTrue(a.compareAndSet(this,two,m4));
-        assertEquals(m4,a.get(this));
+        assertSame(m4,a.get(this));
         assertFalse(a.compareAndSet(this,m5,seven));
-        assertFalse((seven == a.get(this)));
+        assertFalse(seven == a.get(this));
         assertTrue(a.compareAndSet(this,m4,seven));
-        assertEquals(seven,a.get(this));
+        assertSame(seven,a.get(this));
     }
 
     /**
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         x = one;
         final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
         try {
@@ -135,27 +127,24 @@
             return;
         }
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(a.compareAndSet(this, one, two));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(a.get(this), three);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(this, one, two));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(a.get(this), three);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
      * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
         try {
             a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
@@ -163,17 +152,17 @@
             return;
         }
         x = one;
-        while(!a.weakCompareAndSet(this,one,two));
-        while(!a.weakCompareAndSet(this,two,m4));
-        assertEquals(m4,a.get(this));
-        while(!a.weakCompareAndSet(this,m4,seven));
-        assertEquals(seven,a.get(this));
+        while (!a.weakCompareAndSet(this,one,two));
+        while (!a.weakCompareAndSet(this,two,m4));
+        assertSame(m4,a.get(this));
+        while (!a.weakCompareAndSet(this,m4,seven));
+        assertSame(seven,a.get(this));
     }
 
     /**
      * getAndSet returns previous value and sets to given value
      */
-    public void testGetAndSet(){
+    public void testGetAndSet() {
         AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer>a;
         try {
             a = AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdaterTest.class, Integer.class, "x");
@@ -181,9 +170,9 @@
             return;
         }
         x = one;
-        assertEquals(one,a.getAndSet(this, zero));
-        assertEquals(zero,a.getAndSet(this,m10));
-        assertEquals(m10,a.getAndSet(this,1));
+        assertSame(one,a.getAndSet(this, zero));
+        assertSame(zero,a.getAndSet(this,m10));
+        assertSame(m10,a.getAndSet(this,1));
     }
 
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
index 33da30d..5046ee8 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicReferenceTest.java
@@ -2,20 +2,17 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 import java.io.*;
 
 public class AtomicReferenceTest extends JSR166TestCase {
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(AtomicReferenceTest.class);
     }
@@ -23,15 +20,15 @@
     /**
      * constructor initializes to given value
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicReference ai = new AtomicReference(one);
-        assertEquals(one,ai.get());
+        assertSame(one,ai.get());
     }
 
     /**
      * default constructed initializes to null
      */
-    public void testConstructor2(){
+    public void testConstructor2() {
         AtomicReference ai = new AtomicReference();
         assertNull(ai.get());
     }
@@ -39,105 +36,109 @@
     /**
      * get returns the last value set
      */
-    public void testGetSet(){
+    public void testGetSet() {
         AtomicReference ai = new AtomicReference(one);
-        assertEquals(one,ai.get());
+        assertSame(one,ai.get());
         ai.set(two);
-        assertEquals(two,ai.get());
+        assertSame(two,ai.get());
         ai.set(m3);
-        assertEquals(m3,ai.get());
-
+        assertSame(m3,ai.get());
     }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicReference ai = new AtomicReference(one);
+        assertSame(one,ai.get());
+        ai.lazySet(two);
+        assertSame(two,ai.get());
+        ai.lazySet(m3);
+        assertSame(m3,ai.get());
+    }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         AtomicReference ai = new AtomicReference(one);
         assertTrue(ai.compareAndSet(one,two));
         assertTrue(ai.compareAndSet(two,m4));
-        assertEquals(m4,ai.get());
+        assertSame(m4,ai.get());
         assertFalse(ai.compareAndSet(m5,seven));
-        assertFalse((seven.equals(ai.get())));
+        assertSame(m4,ai.get());
         assertTrue(ai.compareAndSet(m4,seven));
-        assertEquals(seven,ai.get());
+        assertSame(seven,ai.get());
     }
 
     /**
      * compareAndSet in one thread enables another waiting for value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicReference ai = new AtomicReference(one);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(two, three)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(one, two));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.get(), three);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(two, three))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, two));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(ai.get(), three);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing value when equal
      * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         AtomicReference ai = new AtomicReference(one);
-        while(!ai.weakCompareAndSet(one,two));
-        while(!ai.weakCompareAndSet(two,m4));
-        assertEquals(m4,ai.get());
-        while(!ai.weakCompareAndSet(m4,seven));
-        assertEquals(seven,ai.get());
+        while (!ai.weakCompareAndSet(one,two));
+        while (!ai.weakCompareAndSet(two,m4));
+        assertSame(m4,ai.get());
+        while (!ai.weakCompareAndSet(m4,seven));
+        assertSame(seven,ai.get());
     }
 
     /**
      * getAndSet returns previous value and sets to given value
      */
-    public void testGetAndSet(){
+    public void testGetAndSet() {
         AtomicReference ai = new AtomicReference(one);
-        assertEquals(one,ai.getAndSet(zero));
-        assertEquals(zero,ai.getAndSet(m10));
-        assertEquals(m10,ai.getAndSet(one));
+        assertSame(one,ai.getAndSet(zero));
+        assertSame(zero,ai.getAndSet(m10));
+        assertSame(m10,ai.getAndSet(one));
     }
 
     /**
      * a deserialized serialized atomic holds same value
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         AtomicReference l = new AtomicReference();
 
-        try {
-            l.set(one);
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        l.set(one);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            AtomicReference r = (AtomicReference) in.readObject();
-            assertEquals(l.get(), r.get());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        AtomicReference r = (AtomicReference) in.readObject();
+        assertEquals(l.get(), r.get());
     }
 
     /**
      * toString returns current value.
-     */ 
+     */
     public void testToString() {
-        AtomicReference<Integer> ai = new AtomicReference<Integer>(one); 
+        AtomicReference<Integer> ai = new AtomicReference<Integer>(one);
         assertEquals(ai.toString(), one.toString());
         ai.set(two);
         assertEquals(ai.toString(), two.toString());
     }
 
 }
-
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java
index 3ffc0a7..ca9b724 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/AtomicStampedReferenceTest.java
@@ -2,68 +2,64 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.atomic.*;
 
-public class AtomicStampedReferenceTest extends JSR166TestCase{
-    public static void main (String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class AtomicStampedReferenceTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(AtomicStampedReferenceTest.class);
     }
-    
+
     /**
      * constructor initializes to given reference and stamp
      */
-    public void testConstructor(){
+    public void testConstructor() {
         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
-        assertEquals(one,ai.getReference());
+        assertSame(one,ai.getReference());
         assertEquals(0, ai.getStamp());
         AtomicStampedReference a2 = new AtomicStampedReference(null, 1);
         assertNull(a2.getReference());
         assertEquals(1, a2.getStamp());
-
     }
 
     /**
      *  get returns the last values of reference and stamp set
      */
-    public void testGetSet(){
+    public void testGetSet() {
         int[] mark = new int[1];
         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
-        assertEquals(one,ai.getReference());
+        assertSame(one,ai.getReference());
         assertEquals(0, ai.getStamp());
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertEquals(0, mark[0]);
         ai.set(two, 0);
-        assertEquals(two,ai.getReference());
+        assertSame(two,ai.getReference());
         assertEquals(0, ai.getStamp());
-        assertEquals(two, ai.get(mark));
+        assertSame(two, ai.get(mark));
         assertEquals(0, mark[0]);
         ai.set(one, 1);
-        assertEquals(one,ai.getReference());
+        assertSame(one,ai.getReference());
         assertEquals(1, ai.getStamp());
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertEquals(1,mark[0]);
     }
 
     /**
      *  attemptStamp succeeds in single thread
      */
-    public void testAttemptStamp(){
+    public void testAttemptStamp() {
         int[] mark = new int[1];
         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
         assertEquals(0, ai.getStamp());
         assertTrue(ai.attemptStamp(one, 1));
         assertEquals(1, ai.getStamp());
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertEquals(1, mark[0]);
     }
 
@@ -71,23 +67,23 @@
      * compareAndSet succeeds in changing values if equal to expected reference
      * and stamp else fails
      */
-    public void testCompareAndSet(){
+    public void testCompareAndSet() {
         int[] mark = new int[1];
         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertEquals(0, ai.getStamp());
         assertEquals(0, mark[0]);
 
         assertTrue(ai.compareAndSet(one, two, 0, 0));
-        assertEquals(two, ai.get(mark));
+        assertSame(two, ai.get(mark));
         assertEquals(0, mark[0]);
 
         assertTrue(ai.compareAndSet(two, m3, 0, 1));
-        assertEquals(m3, ai.get(mark));
+        assertSame(m3, ai.get(mark));
         assertEquals(1, mark[0]);
 
         assertFalse(ai.compareAndSet(two, m3, 1, 1));
-        assertEquals(m3, ai.get(mark));
+        assertSame(m3, ai.get(mark));
         assertEquals(1, mark[0]);
     }
 
@@ -95,65 +91,59 @@
      * compareAndSet in one thread enables another waiting for reference value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads() {
+    public void testCompareAndSetInMultipleThreads() throws Exception {
         final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(two, three, 0, 0)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(one, two, 0, 0));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.getReference(), three);
-            assertEquals(ai.getStamp(), 0);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(two, three, 0, 0))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, two, 0, 0));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(ai.getReference(), three);
+        assertEquals(ai.getStamp(), 0);
     }
 
     /**
      * compareAndSet in one thread enables another waiting for stamp value
      * to succeed
      */
-    public void testCompareAndSetInMultipleThreads2() {
+    public void testCompareAndSetInMultipleThreads2() throws Exception {
         final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    while(!ai.compareAndSet(one, one, 1, 2)) Thread.yield();
-                }});
-        try {
-            t.start();
-            assertTrue(ai.compareAndSet(one, one, 0, 1));
-            t.join(LONG_DELAY_MS);
-            assertFalse(t.isAlive());
-            assertEquals(ai.getReference(), one);
-            assertEquals(ai.getStamp(), 2);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(one, one, 1, 2))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, one, 0, 1));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(ai.getReference(), one);
+        assertEquals(ai.getStamp(), 2);
     }
 
     /**
      * repeated weakCompareAndSet succeeds in changing values when equal
-     * to expected 
+     * to expected
      */
-    public void testWeakCompareAndSet(){
+    public void testWeakCompareAndSet() {
         int[] mark = new int[1];
         AtomicStampedReference ai = new AtomicStampedReference(one, 0);
-        assertEquals(one, ai.get(mark));
+        assertSame(one, ai.get(mark));
         assertEquals(0, ai.getStamp ());
         assertEquals(0, mark[0]);
 
-        while(!ai.weakCompareAndSet(one, two, 0, 0));
-        assertEquals(two, ai.get(mark));
+        while (!ai.weakCompareAndSet(one, two, 0, 0));
+        assertSame(two, ai.get(mark));
         assertEquals(0, mark[0]);
 
-        while(!ai.weakCompareAndSet(two, m3, 0, 1));
-        assertEquals(m3, ai.get(mark));
+        while (!ai.weakCompareAndSet(two, m3, 0, 1));
+        assertSame(m3, ai.get(mark));
         assertEquals(1, mark[0]);
     }
 
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
index d7f2210..9b355f5 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentHashMapTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
@@ -14,10 +14,7 @@
 import java.util.Enumeration;
 import java.io.*;
 
-public class ConcurrentHashMapTest extends JSR166TestCase{
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class ConcurrentHashMapTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(ConcurrentHashMapTest.class);
     }
@@ -83,7 +80,7 @@
      */
     public void testContainsValue() {
         ConcurrentHashMap map = map5();
-	assertTrue(map.containsValue("A"));
+        assertTrue(map.containsValue("A"));
         assertFalse(map.containsValue("Z"));
     }
 
@@ -95,7 +92,7 @@
         ConcurrentHashMap map = map5();
         Enumeration e = map.elements();
         int count = 0;
-        while(e.hasMoreElements()){
+        while (e.hasMoreElements()) {
             count++;
             e.nextElement();
         }
@@ -130,7 +127,7 @@
         ConcurrentHashMap map = map5();
         Enumeration e = map.keys();
         int count = 0;
-        while(e.hasMoreElements()){
+        while (e.hasMoreElements()) {
             count++;
             e.nextElement();
         }
@@ -156,10 +153,10 @@
      */
     public void testKeySetToArray() {
         ConcurrentHashMap map = map5();
-	Set s = map.keySet();
+        Set s = map.keySet();
         Object[] ar = s.toArray();
         assertTrue(s.containsAll(Arrays.asList(ar)));
-	assertEquals(5, ar.length);
+        assertEquals(5, ar.length);
         ar[0] = m10;
         assertFalse(s.containsAll(Arrays.asList(ar)));
     }
@@ -169,15 +166,15 @@
      */
     public void testValuesToArray() {
         ConcurrentHashMap map = map5();
-	Collection v = map.values();
+        Collection v = map.values();
         Object[] ar = v.toArray();
         ArrayList s = new ArrayList(Arrays.asList(ar));
-	assertEquals(5, ar.length);
-	assertTrue(s.contains("A"));
-	assertTrue(s.contains("B"));
-	assertTrue(s.contains("C"));
-	assertTrue(s.contains("D"));
-	assertTrue(s.contains("E"));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
     }
 
     /**
@@ -185,7 +182,7 @@
      */
     public void testEntrySetToArray() {
         ConcurrentHashMap map = map5();
-	Set s = map.entrySet();
+        Set s = map.entrySet();
         Object[] ar = s.toArray();
         assertEquals(5, ar.length);
         for (int i = 0; i < 5; ++i) {
@@ -320,7 +317,6 @@
         map.remove(four, "A");
         assertEquals(4, map.size());
         assertTrue(map.containsKey(four));
-
     }
 
     /**
@@ -353,7 +349,7 @@
         try {
             new ConcurrentHashMap(-1,0,1);
             shouldThrow();
-        } catch(IllegalArgumentException e){}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -363,7 +359,7 @@
         try {
             new ConcurrentHashMap(1,0,-1);
             shouldThrow();
-        } catch(IllegalArgumentException e){}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -373,7 +369,7 @@
         try {
             new ConcurrentHashMap(-1);
             shouldThrow();
-        } catch(IllegalArgumentException e){}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -384,7 +380,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.get(null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -395,7 +391,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.containsKey(null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -406,7 +402,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.containsValue(null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -417,7 +413,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.contains(null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -428,7 +424,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.put(null, "whatever");
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -439,7 +435,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.put("whatever", null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -450,7 +446,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.putIfAbsent(null, "whatever");
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -461,7 +457,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.replace(null, "whatever");
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -472,7 +468,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.replace(null, one, "whatever");
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -483,7 +479,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.putIfAbsent("whatever", null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
 
@@ -495,7 +491,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.replace("whatever", null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -506,7 +502,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.replace("whatever", null, "A");
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -517,7 +513,7 @@
             ConcurrentHashMap c = new ConcurrentHashMap(5);
             c.replace("whatever", one, null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
 
@@ -530,7 +526,7 @@
             c.put("sadsdf", "asdads");
             c.remove(null);
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -542,44 +538,35 @@
             c.put("sadsdf", "asdads");
             c.remove(null, "whatever");
             shouldThrow();
-        } catch(NullPointerException e){}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * remove(x, null) returns false
      */
     public void testRemove3() {
-        try {
-            ConcurrentHashMap c = new ConcurrentHashMap(5);
-            c.put("sadsdf", "asdads");
-            assertFalse(c.remove("sadsdf", null));
-        } catch(NullPointerException e){
-            fail();
-        }
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        c.put("sadsdf", "asdads");
+        assertFalse(c.remove("sadsdf", null));
     }
 
     /**
      * A deserialized map equals original
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         ConcurrentHashMap q = map5();
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            ConcurrentHashMap r = (ConcurrentHashMap)in.readObject();
-            assertEquals(q.size(), r.size());
-            assertTrue(q.equals(r));
-            assertTrue(r.equals(q));
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ConcurrentHashMap r = (ConcurrentHashMap)in.readObject();
+        assertEquals(q.size(), r.size());
+        assertTrue(q.equals(r));
+        assertTrue(r.equals(q));
     }
 
 
@@ -587,23 +574,23 @@
      * SetValue of an EntrySet entry sets value in the map.
      */
     public void testSetValueWriteThrough() {
-        // Adapted from a bug report by Eric Zoerner 
+        // Adapted from a bug report by Eric Zoerner
         ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
         assertTrue(map.isEmpty());
         for (int i = 0; i < 20; i++)
             map.put(new Integer(i), new Integer(i));
         assertFalse(map.isEmpty());
         Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
-        
+
         // assert that entry1 is not 16
         assertTrue("entry is 16, test not valid",
                    !entry1.getKey().equals(new Integer(16)));
-        
-        // remove 16 (a different key) from map 
+
+        // remove 16 (a different key) from map
         // which just happens to cause entry1 to be cloned in map
         map.remove(new Integer(16));
         entry1.setValue("XYZ");
         assertTrue(map.containsValue("XYZ")); // fails
     }
-    
+
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java
index 8d8e13b..1fbc729 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentLinkedQueueTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
@@ -14,11 +14,6 @@
 import java.io.*;
 
 public class ConcurrentLinkedQueueTest extends JSR166TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
-
     public static Test suite() {
         return new TestSuite(ConcurrentLinkedQueueTest.class);
     }
@@ -30,13 +25,13 @@
     private ConcurrentLinkedQueue populatedQueue(int n) {
         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
         assertTrue(q.isEmpty());
-        for(int i = 0; i < n; ++i)
+        for (int i = 0; i < n; ++i)
             assertTrue(q.offer(new Integer(i)));
         assertFalse(q.isEmpty());
         assertEquals(n, q.size());
         return q;
     }
- 
+
     /**
      * new queue is empty
      */
@@ -51,8 +46,7 @@
         try {
             ConcurrentLinkedQueue q = new ConcurrentLinkedQueue((Collection)null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -63,8 +57,7 @@
             Integer[] ints = new Integer[SIZE];
             ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -77,23 +70,19 @@
                 ints[i] = new Integer(i);
             ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of collection used to initialize
      */
     public void testConstructor6() {
-        try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -133,7 +122,7 @@
             ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -144,7 +133,7 @@
             ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
 
@@ -176,8 +165,7 @@
             ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -188,8 +176,7 @@
             ConcurrentLinkedQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -201,8 +188,7 @@
             Integer[] ints = new Integer[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      *  addAll of a collection with any null elements throws NPE after
@@ -216,26 +202,22 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements, in traversal order, of successful addAll
      */
     public void testAddAll5() {
-        try {
-            Integer[] empty = new Integer[0];
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
-            assertFalse(q.addAll(Arrays.asList(empty)));
-            assertTrue(q.addAll(Arrays.asList(ints)));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -244,7 +226,7 @@
     public void testPoll() {
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.poll()).intValue());
+            assertEquals(i, q.poll());
         }
         assertNull(q.poll());
     }
@@ -255,10 +237,10 @@
     public void testPeek() {
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.peek()).intValue());
-            q.poll();
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
             assertTrue(q.peek() == null ||
-                       i != ((Integer)q.peek()).intValue());
+                       !q.peek().equals(i));
         }
         assertNull(q.peek());
     }
@@ -269,14 +251,13 @@
     public void testElement() {
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.element()).intValue());
-            q.poll();
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
         }
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -285,13 +266,12 @@
     public void testRemove() {
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.remove()).intValue());
+            assertEquals(i, q.remove());
         }
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-        }   
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -308,7 +288,7 @@
         }
         assertTrue(q.isEmpty());
     }
-        
+
     /**
      * contains(x) reports true when elements added but not yet removed
      */
@@ -391,7 +371,7 @@
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         Object[] o = q.toArray();
         Arrays.sort(o);
-        for(int i = 0; i < o.length; i++)
+        for (int i = 0; i < o.length; i++)
             assertEquals(o[i], q.poll());
     }
 
@@ -403,7 +383,7 @@
         Integer[] ints = new Integer[SIZE];
         ints = (Integer[])q.toArray(ints);
         Arrays.sort(ints);
-        for(int i = 0; i < ints.length; i++)
+        for (int i = 0; i < ints.length; i++)
             assertEquals(ints[i], q.poll());
     }
 
@@ -411,24 +391,24 @@
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
         try {
-            ConcurrentLinkedQueue q = populatedQueue(SIZE);
             Object o[] = q.toArray(null);
             shouldThrow();
-        } catch(NullPointerException success){}
+        } catch (NullPointerException success) {}
     }
 
     /**
-     * toArray with incompatible array type throws CCE
+     * toArray with incompatible array type throws ArrayStoreException
      */
     public void testToArray1_BadArg() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
         try {
-            ConcurrentLinkedQueue q = populatedQueue(SIZE);
-            Object o[] = q.toArray(new String[10] );
+            Object o[] = q.toArray(new String[10]);
             shouldThrow();
-        } catch(ArrayStoreException  success){}
+        } catch (ArrayStoreException success) {}
     }
-    
+
     /**
      *  iterator iterates through all elements
      */
@@ -436,7 +416,7 @@
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
         int i = 0;
         Iterator it = q.iterator();
-        while(it.hasNext()) {
+        while (it.hasNext()) {
             assertTrue(q.contains(it.next()));
             ++i;
         }
@@ -454,8 +434,7 @@
 
         int k = 0;
         for (Iterator it = q.iterator(); it.hasNext();) {
-            int i = ((Integer)(it.next())).intValue();
-            assertEquals(++k, i);
+            assertEquals(++k, it.next());
         }
 
         assertEquals(3, k);
@@ -470,14 +449,9 @@
         q.add(two);
         q.add(three);
 
-        try {
-            for (Iterator it = q.iterator(); it.hasNext();) {
-                q.remove();
-                it.next();
-            }
-        }
-        catch (ConcurrentModificationException e) {
-            shouldThrow();
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
         }
 
         assertEquals("queue should be empty again", 0, q.size());
@@ -495,8 +469,8 @@
         it.next();
         it.remove();
         it = q.iterator();
-        assertEquals(it.next(), two);
-        assertEquals(it.next(), three);
+        assertSame(it.next(), two);
+        assertSame(it.next(), three);
         assertFalse(it.hasNext());
     }
 
@@ -510,28 +484,24 @@
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
     /**
      * A deserialized serialized queue has same elements in same order
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         ConcurrentLinkedQueue q = populatedQueue(SIZE);
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            ConcurrentLinkedQueue r = (ConcurrentLinkedQueue)in.readObject();
-            assertEquals(q.size(), r.size());
-            while (!q.isEmpty()) 
-                assertEquals(q.remove(), r.remove());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ConcurrentLinkedQueue r = (ConcurrentLinkedQueue)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
     }
 
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListMapTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListMapTest.java
new file mode 100644
index 0000000..3cf5b75
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListMapTest.java
@@ -0,0 +1,1280 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+public class ConcurrentSkipListMapTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListMapTest.class);
+    }
+
+    /**
+     * Create a map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentSkipListMap map5() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        map.put(one, "A");
+        map.put(five, "E");
+        map.put(three, "C");
+        map.put(two, "B");
+        map.put(four, "D");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map;
+    }
+
+    /**
+     *  clear removes all pairs
+     */
+    public void testClear() {
+        ConcurrentSkipListMap map = map5();
+        map.clear();
+        assertEquals(map.size(), 0);
+    }
+
+    /**
+     *
+     */
+    public void testConstructFromSorted() {
+        ConcurrentSkipListMap map = map5();
+        ConcurrentSkipListMap map2 = new ConcurrentSkipListMap(map);
+        assertEquals(map, map2);
+    }
+
+    /**
+     *  Maps with same contents are equal
+     */
+    public void testEquals() {
+        ConcurrentSkipListMap map1 = map5();
+        ConcurrentSkipListMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     *  containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        ConcurrentSkipListMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     *  containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        ConcurrentSkipListMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     *  get returns the correct element at the given key,
+     *  or null if not present
+     */
+    public void testGet() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        assertNull(empty.get(one));
+    }
+
+    /**
+     *  isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        ConcurrentSkipListMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     *   firstKey returns first key
+     */
+    public void testFirstKey() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals(one, map.firstKey());
+    }
+
+    /**
+     *   lastKey returns last key
+     */
+    public void testLastKey() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals(five, map.lastKey());
+    }
+
+
+    /**
+     *  keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingKeySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *   keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     *   keySet is ordered
+     */
+    public void testKeySetOrder() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(count ,5);
+    }
+
+    /**
+     * descending iterator of key set is inverse ordered
+     */
+    public void testKeySetDescendingIteratorOrder() {
+        ConcurrentSkipListMap map = map5();
+        NavigableSet s = map.navigableKeySet();
+        Iterator i = s.descendingIterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, five);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(count ,5);
+    }
+
+    /**
+     *   descendingKeySet is ordered
+     */
+    public void testDescendingKeySetOrder() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingKeySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, five);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(count, 5);
+    }
+
+    /**
+     *  descending iterator of descendingKeySet is ordered
+     */
+    public void testDescendingKeySetDescendingIteratorOrder() {
+        ConcurrentSkipListMap map = map5();
+        NavigableSet s = map.descendingKeySet();
+        Iterator i = s.descendingIterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(count, 5);
+    }
+
+    /**
+     *  Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentSkipListMap map = map5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        ConcurrentSkipListMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * descendingEntrySet contains all pairs
+     */
+    public void testDescendingEntrySet() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingMap().entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     *  entrySet.toArray contains all entries
+     */
+    public void testEntrySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     *  descendingEntrySet.toArray contains all entries
+     */
+    public void testDescendingEntrySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingMap().entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     *   putAll  adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        ConcurrentSkipListMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     *   putIfAbsent works when the given key is not present
+     */
+    public void testPutIfAbsent() {
+        ConcurrentSkipListMap map = map5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     *   putIfAbsent does not add the pair if the key is already present
+     */
+    public void testPutIfAbsent2() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", map.putIfAbsent(one, "Z"));
+    }
+
+    /**
+     *   replace fails when the given key is not present
+     */
+    public void testReplace() {
+        ConcurrentSkipListMap map = map5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     *   replace succeeds if the key is already present
+     */
+    public void testReplace2() {
+        ConcurrentSkipListMap map = map5();
+        assertNotNull(map.replace(one, "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testReplaceValue() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", map.get(one));
+        assertFalse(map.replace(one, "Z", "Z"));
+        assertEquals("A", map.get(one));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testReplaceValue2() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", map.get(one));
+        assertTrue(map.replace(one, "A", "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+
+    /**
+     *   remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        ConcurrentSkipListMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testRemove2() {
+        ConcurrentSkipListMap map = map5();
+        assertTrue(map.containsKey(five));
+        assertEquals("E", map.get(five));
+        map.remove(five, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+        map.remove(four, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(four));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testLowerEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.lowerEntry(three);
+        assertEquals(two, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(one);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testHigherEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.higherEntry(three);
+        assertEquals(four, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(five);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testFloorEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.floorEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(one);
+        assertEquals(one, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testCeilingEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.ceilingEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(five);
+        assertEquals(five, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * lowerEntry, higherEntry, ceilingEntry, and floorEntry return
+     * immutable entries
+     */
+    public void testEntryImmutablity() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e = map.lowerEntry(three);
+        assertEquals(two, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.higherEntry(zero);
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.floorEntry(one);
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.ceilingEntry(five);
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+
+
+    /**
+     * lowerKey returns preceding element
+     */
+    public void testLowerKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.lowerKey(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lowerKey(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lowerKey(one);
+        assertNull(e3);
+
+        Object e4 = q.lowerKey(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherKey returns next element
+     */
+    public void testHigherKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.higherKey(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higherKey(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higherKey(five);
+        assertNull(e3);
+
+        Object e4 = q.higherKey(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorKey returns preceding element
+     */
+    public void testFloorKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.floorKey(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floorKey(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floorKey(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floorKey(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingKey returns next element
+     */
+    public void testCeilingKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.ceilingKey(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceilingKey(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceilingKey(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceilingKey(six);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testPollFirstEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(two, e.getKey());
+        map.put(one, "A");
+        e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(three, e.getKey());
+        map.remove(four);
+        e = map.pollFirstEntry();
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testPollLastEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(four, e.getKey());
+        map.put(five, "E");
+        e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(three, e.getKey());
+        map.remove(two);
+        e = map.pollLastEntry();
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     *   size returns the correct values
+     */
+    public void testSize() {
+        ConcurrentSkipListMap map = map5();
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        ConcurrentSkipListMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testGet_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = map5();
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of nonempty map throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = map5();
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testContainsValue_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testPut1_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = map5();
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testPutIfAbsent1_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = map5();
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testReplace_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = map5();
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testReplaceValue_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = map5();
+            c.replace(null, one, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testRemove1_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+            c.put("sadsdf", "asdads");
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testRemove2_NullPointerException() {
+        try {
+            ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+            c.put("sadsdf", "asdads");
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(x, null) returns false
+     */
+    public void testRemove3() {
+        ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+        c.put("sadsdf", "asdads");
+        assertFalse(c.remove("sadsdf", null));
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        ConcurrentSkipListMap q = map5();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ConcurrentSkipListMap r = (ConcurrentSkipListMap)in.readObject();
+        assertEquals(q.size(), r.size());
+        assertTrue(q.equals(r));
+        assertTrue(r.equals(q));
+    }
+
+
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testSubMapContents() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.subMap(two, true, four, false);
+        assertEquals(two, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(three, k);
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals("C", sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testSubMapContents2() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.subMap(two, true, three, false);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.firstKey());
+        assertEquals(two, sm.lastKey());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertFalse(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(three), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testHeadMapContents() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.headMap(four, false);
+        assertTrue(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(four, map.firstKey());
+    }
+
+    /**
+     * tailMap returns map with keys in requested range
+     */
+    public void testTailMapContents() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.tailMap(two, true);
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertTrue(sm.containsKey(four));
+        assertTrue(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(five, k);
+        k = (Integer)(r.next());
+        assertEquals(four, k);
+        k = (Integer)(r.next());
+        assertEquals(three, k);
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(two, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(three, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(four, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        NavigableMap ssm = sm.tailMap(four, true);
+        assertEquals(four, ssm.firstKey());
+        assertEquals(five, ssm.lastKey());
+        assertEquals("D", ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+    Random rnd = new Random(666);
+    BitSet bs;
+
+    /**
+     * Submaps of submaps subdivide correctly
+     */
+    public void testRecursiveSubMaps() throws Exception {
+        int mapSize = 1000;
+        Class cl = ConcurrentSkipListMap.class;
+        NavigableMap<Integer, Integer> map = newMap(cl);
+        bs = new BitSet(mapSize);
+
+        populate(map, mapSize);
+        check(map,                 0, mapSize - 1, true);
+        check(map.descendingMap(), 0, mapSize - 1, false);
+
+        mutateMap(map, 0, mapSize - 1);
+        check(map,                 0, mapSize - 1, true);
+        check(map.descendingMap(), 0, mapSize - 1, false);
+
+        bashSubMap(map.subMap(0, true, mapSize, false),
+                   0, mapSize - 1, true);
+    }
+
+    static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
+        NavigableMap<Integer, Integer> result =
+            (NavigableMap<Integer, Integer>) cl.newInstance();
+        assertEquals(result.size(), 0);
+        assertFalse(result.keySet().iterator().hasNext());
+        return result;
+    }
+
+    void populate(NavigableMap<Integer, Integer> map, int limit) {
+        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+            int key = rnd.nextInt(limit);
+            put(map, key);
+        }
+    }
+
+    void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
+        int size = map.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (map.size() < size) {
+            int key = min + rnd.nextInt(rangeSize);
+            assertTrue(key >= min && key<= max);
+            put(map, key);
+        }
+    }
+
+    void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
+        int size = map.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (map.size() < size) {
+            int key = min - 5 + rnd.nextInt(rangeSize + 10);
+            if (key >= min && key<= max) {
+                put(map, key);
+            } else {
+                try {
+                    map.put(key, 2 * key);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    void put(NavigableMap<Integer, Integer> map, int key) {
+        if (map.put(key, 2 * key) == null)
+            bs.set(key);
+    }
+
+    void remove(NavigableMap<Integer, Integer> map, int key) {
+        if (map.remove(key) != null)
+            bs.clear(key);
+    }
+
+    void bashSubMap(NavigableMap<Integer, Integer> map,
+                    int min, int max, boolean ascending) {
+        check(map, min, max, ascending);
+        check(map.descendingMap(), min, max, !ascending);
+
+        mutateSubMap(map, min, max);
+        check(map, min, max, ascending);
+        check(map.descendingMap(), min, max, !ascending);
+
+        // Recurse
+        if (max - min < 2)
+            return;
+        int midPoint = (min + max) / 2;
+
+        // headMap - pick direction and endpoint inclusion randomly
+        boolean incl = rnd.nextBoolean();
+        NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
+            else
+                bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+                           false);
+        } else {
+            if (rnd.nextBoolean())
+                bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
+            else
+                bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+                           true);
+        }
+
+        // tailMap - pick direction and endpoint inclusion randomly
+        incl = rnd.nextBoolean();
+        NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
+            else
+                bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+                           false);
+        } else {
+            if (rnd.nextBoolean()) {
+                bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
+            } else {
+                bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+                           true);
+            }
+        }
+
+        // subMap - pick direction and endpoint inclusion randomly
+        int rangeSize = max - min + 1;
+        int[] endpoints = new int[2];
+        endpoints[0] = min + rnd.nextInt(rangeSize);
+        endpoints[1] = min + rnd.nextInt(rangeSize);
+        Arrays.sort(endpoints);
+        boolean lowIncl = rnd.nextBoolean();
+        boolean highIncl = rnd.nextBoolean();
+        if (ascending) {
+            NavigableMap<Integer,Integer> sm = map.subMap(
+                endpoints[0], lowIncl, endpoints[1], highIncl);
+            if (rnd.nextBoolean())
+                bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+            else
+                bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+        } else {
+            NavigableMap<Integer,Integer> sm = map.subMap(
+                endpoints[1], highIncl, endpoints[0], lowIncl);
+            if (rnd.nextBoolean())
+                bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+            else
+                bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+        }
+    }
+
+    /**
+     * min and max are both inclusive.  If max < min, interval is empty.
+     */
+    void check(NavigableMap<Integer, Integer> map,
+                      final int min, final int max, final boolean ascending) {
+       class ReferenceSet {
+            int lower(int key) {
+                return ascending ? lowerAscending(key) : higherAscending(key);
+            }
+            int floor(int key) {
+                return ascending ? floorAscending(key) : ceilingAscending(key);
+            }
+            int ceiling(int key) {
+                return ascending ? ceilingAscending(key) : floorAscending(key);
+            }
+            int higher(int key) {
+                return ascending ? higherAscending(key) : lowerAscending(key);
+            }
+            int first() {
+                return ascending ? firstAscending() : lastAscending();
+            }
+            int last() {
+                return ascending ? lastAscending() : firstAscending();
+            }
+            int lowerAscending(int key) {
+                return floorAscending(key - 1);
+            }
+            int floorAscending(int key) {
+                if (key < min)
+                    return -1;
+                else if (key > max)
+                    key = max;
+
+                // BitSet should support this! Test would run much faster
+                while (key >= min) {
+                    if (bs.get(key))
+                        return(key);
+                    key--;
+                }
+                return -1;
+            }
+            int ceilingAscending(int key) {
+                if (key < min)
+                    key = min;
+                else if (key > max)
+                    return -1;
+                int result = bs.nextSetBit(key);
+                return result > max ? -1 : result;
+            }
+            int higherAscending(int key) {
+                return ceilingAscending(key + 1);
+            }
+            private int firstAscending() {
+                int result = ceilingAscending(min);
+                return result > max ? -1 : result;
+            }
+            private int lastAscending() {
+                int result = floorAscending(max);
+                return result < min ? -1 : result;
+            }
+        }
+        ReferenceSet rs = new ReferenceSet();
+
+        // Test contents using containsKey
+        int size = 0;
+        for (int i = min; i <= max; i++) {
+            boolean bsContainsI = bs.get(i);
+            assertEquals(bsContainsI, map.containsKey(i));
+            if (bsContainsI)
+                size++;
+        }
+        assertEquals(map.size(), size);
+
+        // Test contents using contains keySet iterator
+        int size2 = 0;
+        int previousKey = -1;
+        for (int key : map.keySet()) {
+            assertTrue(bs.get(key));
+            size2++;
+            assertTrue(previousKey < 0 ||
+                (ascending ? key - previousKey > 0 : key - previousKey < 0));
+            previousKey = key;
+        }
+        assertEquals(size2, size);
+
+        // Test navigation ops
+        for (int key = min - 1; key <= max + 1; key++) {
+            assertEq(map.lowerKey(key), rs.lower(key));
+            assertEq(map.floorKey(key), rs.floor(key));
+            assertEq(map.higherKey(key), rs.higher(key));
+            assertEq(map.ceilingKey(key), rs.ceiling(key));
+        }
+
+        // Test extrema
+        if (map.size() != 0) {
+            assertEq(map.firstKey(), rs.first());
+            assertEq(map.lastKey(), rs.last());
+        } else {
+            assertEq(rs.first(), -1);
+            assertEq(rs.last(),  -1);
+            try {
+                map.firstKey();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                map.lastKey();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        }
+    }
+
+    static void assertEq(Integer i, int j) {
+        if (i == null)
+            assertEquals(j, -1);
+        else
+            assertEquals((int) i, j);
+    }
+
+    static boolean eq(Integer i, int j) {
+        return i == null ? j == -1 : i == j;
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSetTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSetTest.java
new file mode 100644
index 0000000..2d03b3c
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSetTest.java
@@ -0,0 +1,961 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+public class ConcurrentSkipListSetTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListSetTest.class);
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Create a set of given size containing consecutive
+     * Integers 0 ... n.
+     */
+    private ConcurrentSkipListSet populatedSet(int n) {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        for (int i = n-1; i >= 0; i-=2)
+            assertTrue(q.add(new Integer(i)));
+        for (int i = (n & 1); i < n; i+=2)
+            assertTrue(q.add(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        return q;
+    }
+
+    /**
+     * Create set of first 5 ints
+     */
+    private ConcurrentSkipListSet set5() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        q.add(four);
+        q.add(five);
+        assertEquals(5, q.size());
+        return q;
+    }
+
+    /**
+     * A new set has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, new ConcurrentSkipListSet().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            Integer[] ints = new Integer[SIZE];
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        try {
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE-1; ++i)
+                ints[i] = new Integer(i);
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * The comparator used in constructor is used
+     */
+    public void testConstructor7() {
+        MyReverseComparator cmp = new MyReverseComparator();
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet(cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE-1; i >= 0; --i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.pollFirst();
+        q.pollFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        try {
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testAdd() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.add(zero));
+        assertTrue(q.add(one));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testAddDup() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.add(zero));
+        assertFalse(q.add(zero));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testAddNonComparable() {
+        try {
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+            q.add(new Object());
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        try {
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        try {
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+            Integer[] ints = new Integer[SIZE];
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        try {
+            ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE-1; ++i)
+                ints[i] = new Integer(i);
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE-1-i);
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(i, q.pollFirst());
+    }
+
+    /**
+     * pollFirst succeeds unless empty
+     */
+    public void testPollFirst() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollFirst());
+    }
+
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+            assertFalse(q.remove(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        ConcurrentSkipListSet p = new ConcurrentSkipListSet();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        ConcurrentSkipListSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE-i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ConcurrentSkipListSet q = populatedSet(SIZE);
+            ConcurrentSkipListSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE-i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer I = (Integer)(p.pollFirst());
+                assertFalse(q.contains(I));
+            }
+        }
+    }
+
+
+
+    /**
+     * lower returns preceding element
+     */
+    public void testLower() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.lower(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lower(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lower(one);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testHigher() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.higher(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higher(five);
+        assertNull(e3);
+
+        Object e4 = q.higher(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testFloor() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.floor(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floor(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floor(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testCeiling() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.ceiling(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceiling(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceiling(six);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testToArray() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testToArray2() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        ints = (Integer[])q.toArray(ints);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testEmptyIterator() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, 0);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove () {
+        final ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testSerialization() throws Exception {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ConcurrentSkipListSet r = (ConcurrentSkipListSet)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.pollFirst(), r.pollFirst());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testSubSetContents() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.subSet(two, four);
+        assertEquals(two, sm.first());
+        assertEquals(three, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.first());
+        assertEquals(three, sm.last());
+        assertTrue(sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testSubSetContents2() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.subSet(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.first());
+        assertEquals(two, sm.last());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertFalse(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(three));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testHeadSetContents() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.headSet(four);
+        assertTrue(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(four, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testTailSetContents() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.tailSet(two);
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertTrue(sm.contains(four));
+        assertTrue(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(four);
+        assertEquals(four, ssm.first());
+        assertEquals(five, ssm.last());
+        assertTrue(ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    Random rnd = new Random(666);
+    BitSet bs;
+
+    /**
+     * Subsets of subsets subdivide correctly
+     */
+    public void testRecursiveSubSets() throws Exception {
+        int setSize = 1000;
+        Class cl = ConcurrentSkipListSet.class;
+
+        NavigableSet<Integer> set = newSet(cl);
+        bs = new BitSet(setSize);
+
+        populate(set, setSize);
+        check(set,                 0, setSize - 1, true);
+        check(set.descendingSet(), 0, setSize - 1, false);
+
+        mutateSet(set, 0, setSize - 1);
+        check(set,                 0, setSize - 1, true);
+        check(set.descendingSet(), 0, setSize - 1, false);
+
+        bashSubSet(set.subSet(0, true, setSize, false),
+                   0, setSize - 1, true);
+    }
+
+    static NavigableSet<Integer> newSet(Class cl) throws Exception {
+        NavigableSet<Integer> result = (NavigableSet<Integer>) cl.newInstance();
+        assertEquals(result.size(), 0);
+        assertFalse(result.iterator().hasNext());
+        return result;
+    }
+
+    void populate(NavigableSet<Integer> set, int limit) {
+        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+            int element = rnd.nextInt(limit);
+            put(set, element);
+        }
+    }
+
+    void mutateSet(NavigableSet<Integer> set, int min, int max) {
+        int size = set.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (set.size() < size) {
+            int element = min + rnd.nextInt(rangeSize);
+            assertTrue(element >= min && element<= max);
+            put(set, element);
+        }
+    }
+
+    void mutateSubSet(NavigableSet<Integer> set, int min, int max) {
+        int size = set.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (set.size() < size) {
+            int element = min - 5 + rnd.nextInt(rangeSize + 10);
+            if (element >= min && element<= max) {
+                put(set, element);
+            } else {
+                try {
+                    set.add(element);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    void put(NavigableSet<Integer> set, int element) {
+        if (set.add(element))
+            bs.set(element);
+    }
+
+    void remove(NavigableSet<Integer> set, int element) {
+        if (set.remove(element))
+            bs.clear(element);
+    }
+
+    void bashSubSet(NavigableSet<Integer> set,
+                    int min, int max, boolean ascending) {
+        check(set, min, max, ascending);
+        check(set.descendingSet(), min, max, !ascending);
+
+        mutateSubSet(set, min, max);
+        check(set, min, max, ascending);
+        check(set.descendingSet(), min, max, !ascending);
+
+        // Recurse
+        if (max - min < 2)
+            return;
+        int midPoint = (min + max) / 2;
+
+        // headSet - pick direction and endpoint inclusion randomly
+        boolean incl = rnd.nextBoolean();
+        NavigableSet<Integer> hm = set.headSet(midPoint, incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true);
+            else
+                bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+                           false);
+        } else {
+            if (rnd.nextBoolean())
+                bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false);
+            else
+                bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+                           true);
+        }
+
+        // tailSet - pick direction and endpoint inclusion randomly
+        incl = rnd.nextBoolean();
+        NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true);
+            else
+                bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+                           false);
+        } else {
+            if (rnd.nextBoolean()) {
+                bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false);
+            } else {
+                bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+                           true);
+            }
+        }
+
+        // subSet - pick direction and endpoint inclusion randomly
+        int rangeSize = max - min + 1;
+        int[] endpoints = new int[2];
+        endpoints[0] = min + rnd.nextInt(rangeSize);
+        endpoints[1] = min + rnd.nextInt(rangeSize);
+        Arrays.sort(endpoints);
+        boolean lowIncl = rnd.nextBoolean();
+        boolean highIncl = rnd.nextBoolean();
+        if (ascending) {
+            NavigableSet<Integer> sm = set.subSet(
+                endpoints[0], lowIncl, endpoints[1], highIncl);
+            if (rnd.nextBoolean())
+                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+            else
+                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+        } else {
+            NavigableSet<Integer> sm = set.subSet(
+                endpoints[1], highIncl, endpoints[0], lowIncl);
+            if (rnd.nextBoolean())
+                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+            else
+                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+        }
+    }
+
+    /**
+     * min and max are both inclusive.  If max < min, interval is empty.
+     */
+    void check(NavigableSet<Integer> set,
+                      final int min, final int max, final boolean ascending) {
+       class ReferenceSet {
+            int lower(int element) {
+                return ascending ?
+                    lowerAscending(element) : higherAscending(element);
+            }
+            int floor(int element) {
+                return ascending ?
+                    floorAscending(element) : ceilingAscending(element);
+            }
+            int ceiling(int element) {
+                return ascending ?
+                    ceilingAscending(element) : floorAscending(element);
+            }
+            int higher(int element) {
+                return ascending ?
+                    higherAscending(element) : lowerAscending(element);
+            }
+            int first() {
+                return ascending ? firstAscending() : lastAscending();
+            }
+            int last() {
+                return ascending ? lastAscending() : firstAscending();
+            }
+            int lowerAscending(int element) {
+                return floorAscending(element - 1);
+            }
+            int floorAscending(int element) {
+                if (element < min)
+                    return -1;
+                else if (element > max)
+                    element = max;
+
+                // BitSet should support this! Test would run much faster
+                while (element >= min) {
+                    if (bs.get(element))
+                        return(element);
+                    element--;
+                }
+                return -1;
+            }
+            int ceilingAscending(int element) {
+                if (element < min)
+                    element = min;
+                else if (element > max)
+                    return -1;
+                int result = bs.nextSetBit(element);
+                return result > max ? -1 : result;
+            }
+            int higherAscending(int element) {
+                return ceilingAscending(element + 1);
+            }
+            private int firstAscending() {
+                int result = ceilingAscending(min);
+                return result > max ? -1 : result;
+            }
+            private int lastAscending() {
+                int result = floorAscending(max);
+                return result < min ? -1 : result;
+            }
+        }
+        ReferenceSet rs = new ReferenceSet();
+
+        // Test contents using containsElement
+        int size = 0;
+        for (int i = min; i <= max; i++) {
+            boolean bsContainsI = bs.get(i);
+            assertEquals(bsContainsI, set.contains(i));
+            if (bsContainsI)
+                size++;
+        }
+        assertEquals(set.size(), size);
+
+        // Test contents using contains elementSet iterator
+        int size2 = 0;
+        int previousElement = -1;
+        for (int element : set) {
+            assertTrue(bs.get(element));
+            size2++;
+            assertTrue(previousElement < 0 || (ascending ?
+                element - previousElement > 0 : element - previousElement < 0));
+            previousElement = element;
+        }
+        assertEquals(size2, size);
+
+        // Test navigation ops
+        for (int element = min - 1; element <= max + 1; element++) {
+            assertEq(set.lower(element), rs.lower(element));
+            assertEq(set.floor(element), rs.floor(element));
+            assertEq(set.higher(element), rs.higher(element));
+            assertEq(set.ceiling(element), rs.ceiling(element));
+        }
+
+        // Test extrema
+        if (set.size() != 0) {
+            assertEq(set.first(), rs.first());
+            assertEq(set.last(), rs.last());
+        } else {
+            assertEq(rs.first(), -1);
+            assertEq(rs.last(),  -1);
+            try {
+                set.first();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                set.last();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        }
+    }
+
+    static void assertEq(Integer i, int j) {
+        if (i == null)
+            assertEquals(j, -1);
+        else
+            assertEquals((int) i, j);
+    }
+
+    static boolean eq(Integer i, int j) {
+        return i == null ? j == -1 : i == j;
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSubMapTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSubMapTest.java
new file mode 100644
index 0000000..fc70935
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSubMapTest.java
@@ -0,0 +1,1438 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+public class ConcurrentSkipListSubMapTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListSubMapTest.class);
+    }
+
+    /**
+     * Create a map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentNavigableMap map5() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        map.put(zero, "Z");
+        map.put(one, "A");
+        map.put(five, "E");
+        map.put(three, "C");
+        map.put(two, "B");
+        map.put(four, "D");
+        map.put(seven, "F");
+        assertFalse(map.isEmpty());
+        assertEquals(7, map.size());
+        return map.subMap(one, true, seven, false);
+    }
+
+    /**
+     * Create a map from Integers -5 to -1 to Strings "A"-"E".
+     */
+    private static ConcurrentNavigableMap dmap5() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        map.put(m1, "A");
+        map.put(m5, "E");
+        map.put(m3, "C");
+        map.put(m2, "B");
+        map.put(m4, "D");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map.descendingMap();
+    }
+
+    private static ConcurrentNavigableMap map0() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        return map.tailMap(one, true);
+    }
+
+    private static ConcurrentNavigableMap dmap0() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        return map;
+    }
+
+    /**
+     *  clear removes all pairs
+     */
+    public void testClear() {
+        ConcurrentNavigableMap map = map5();
+        map.clear();
+        assertEquals(map.size(), 0);
+    }
+
+
+    /**
+     *  Maps with same contents are equal
+     */
+    public void testEquals() {
+        ConcurrentNavigableMap map1 = map5();
+        ConcurrentNavigableMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     *  containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        ConcurrentNavigableMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     *  containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        ConcurrentNavigableMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     *  get returns the correct element at the given key,
+     *  or null if not present
+     */
+    public void testGet() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        ConcurrentNavigableMap empty = map0();
+        assertNull(empty.get(one));
+    }
+
+    /**
+     *  isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        ConcurrentNavigableMap empty = map0();
+        ConcurrentNavigableMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     *   firstKey returns first key
+     */
+    public void testFirstKey() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals(one, map.firstKey());
+    }
+
+    /**
+     *   lastKey returns last key
+     */
+    public void testLastKey() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals(five, map.lastKey());
+    }
+
+
+    /**
+     *   keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     *   keySet is ordered
+     */
+    public void testKeySetOrder() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        ConcurrentNavigableMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     *  keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingKeySetToArray() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentNavigableMap map = map5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     *   putAll  adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        ConcurrentNavigableMap empty = map0();
+        ConcurrentNavigableMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     *   putIfAbsent works when the given key is not present
+     */
+    public void testPutIfAbsent() {
+        ConcurrentNavigableMap map = map5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     *   putIfAbsent does not add the pair if the key is already present
+     */
+    public void testPutIfAbsent2() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", map.putIfAbsent(one, "Z"));
+    }
+
+    /**
+     *   replace fails when the given key is not present
+     */
+    public void testReplace() {
+        ConcurrentNavigableMap map = map5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     *   replace succeeds if the key is already present
+     */
+    public void testReplace2() {
+        ConcurrentNavigableMap map = map5();
+        assertNotNull(map.replace(one, "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testReplaceValue() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", map.get(one));
+        assertFalse(map.replace(one, "Z", "Z"));
+        assertEquals("A", map.get(one));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testReplaceValue2() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", map.get(one));
+        assertTrue(map.replace(one, "A", "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+
+    /**
+     *   remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        ConcurrentNavigableMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testRemove2() {
+        ConcurrentNavigableMap map = map5();
+        assertTrue(map.containsKey(five));
+        assertEquals("E", map.get(five));
+        map.remove(five, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+        map.remove(four, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(four));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testLowerEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.lowerEntry(three);
+        assertEquals(two, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(one);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testHigherEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.higherEntry(three);
+        assertEquals(four, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(five);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testFloorEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.floorEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(one);
+        assertEquals(one, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testCeilingEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.ceilingEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(five);
+        assertEquals(five, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testPollFirstEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(two, e.getKey());
+        map.put(one, "A");
+        e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(three, e.getKey());
+        map.remove(four);
+        e = map.pollFirstEntry();
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testPollLastEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(four, e.getKey());
+        map.put(five, "E");
+        e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(three, e.getKey());
+        map.remove(two);
+        e = map.pollLastEntry();
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     *   size returns the correct values
+     */
+    public void testSize() {
+        ConcurrentNavigableMap map = map5();
+        ConcurrentNavigableMap empty = map0();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        ConcurrentNavigableMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testGet_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of nonempty map throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testContainsValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map0();
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testPut1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testPutIfAbsent1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testReplace_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testReplaceValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.replace(null, one, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testRemove1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testRemove2_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        ConcurrentNavigableMap q = map5();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ConcurrentNavigableMap r = (ConcurrentNavigableMap)in.readObject();
+        assertEquals(q.size(), r.size());
+        assertTrue(q.equals(r));
+        assertTrue(r.equals(q));
+    }
+
+
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testSubMapContents() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.subMap(two, four);
+        assertEquals(two, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals("C", sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testSubMapContents2() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.subMap(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.firstKey());
+        assertEquals(two, sm.lastKey());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertFalse(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(three), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testHeadMapContents() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.headMap(four);
+        assertTrue(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(four, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testTailMapContents() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.tailMap(two);
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertTrue(sm.containsKey(four));
+        assertTrue(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(two, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(three, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(four, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        SortedMap ssm = sm.tailMap(four);
+        assertEquals(four, ssm.firstKey());
+        assertEquals(five, ssm.lastKey());
+        assertEquals("D", ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+    /**
+     *  clear removes all pairs
+     */
+    public void testDescendingClear() {
+        ConcurrentNavigableMap map = dmap5();
+        map.clear();
+        assertEquals(map.size(), 0);
+    }
+
+
+    /**
+     *  Maps with same contents are equal
+     */
+    public void testDescendingEquals() {
+        ConcurrentNavigableMap map1 = dmap5();
+        ConcurrentNavigableMap map2 = dmap5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     *  containsKey returns true for contained key
+     */
+    public void testDescendingContainsKey() {
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(map.containsKey(m1));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     *  containsValue returns true for held values
+     */
+    public void testDescendingContainsValue() {
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     *  get returns the correct element at the given key,
+     *  or null if not present
+     */
+    public void testDescendingGet() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", (String)map.get(m1));
+        ConcurrentNavigableMap empty = dmap0();
+        assertNull(empty.get(m1));
+    }
+
+    /**
+     *  isEmpty is true of empty map and false for non-empty
+     */
+    public void testDescendingIsEmpty() {
+        ConcurrentNavigableMap empty = dmap0();
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     *   firstKey returns first key
+     */
+    public void testDescendingFirstKey() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals(m1, map.firstKey());
+    }
+
+    /**
+     *   lastKey returns last key
+     */
+    public void testDescendingLastKey() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals(m5, map.lastKey());
+    }
+
+
+    /**
+     *   keySet returns a Set containing all the keys
+     */
+    public void testDescendingKeySet() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(m1));
+        assertTrue(s.contains(m2));
+        assertTrue(s.contains(m3));
+        assertTrue(s.contains(m4));
+        assertTrue(s.contains(m5));
+    }
+
+    /**
+     *   keySet is ordered
+     */
+    public void testDescendingKeySetOrder() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, m1);
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testDescendingValues() {
+        ConcurrentNavigableMap map = dmap5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     *  keySet.toArray returns contains all keys
+     */
+    public void testDescendingAscendingKeySetToArray() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingDescendingKeySetToArray() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  Values.toArray contains all values
+     */
+    public void testDescendingValuesToArray() {
+        ConcurrentNavigableMap map = dmap5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testDescendingEntrySet() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(m1) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(m2) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(m3) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(m4) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(m5) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     *   putAll  adds all key-value pairs from the given map
+     */
+    public void testDescendingPutAll() {
+        ConcurrentNavigableMap empty = dmap0();
+        ConcurrentNavigableMap map = dmap5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(m1));
+        assertTrue(empty.containsKey(m2));
+        assertTrue(empty.containsKey(m3));
+        assertTrue(empty.containsKey(m4));
+        assertTrue(empty.containsKey(m5));
+    }
+
+    /**
+     *   putIfAbsent works when the given key is not present
+     */
+    public void testDescendingPutIfAbsent() {
+        ConcurrentNavigableMap map = dmap5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     *   putIfAbsent does not add the pair if the key is already present
+     */
+    public void testDescendingPutIfAbsent2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", map.putIfAbsent(m1, "Z"));
+    }
+
+    /**
+     *   replace fails when the given key is not present
+     */
+    public void testDescendingReplace() {
+        ConcurrentNavigableMap map = dmap5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     *   replace succeeds if the key is already present
+     */
+    public void testDescendingReplace2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertNotNull(map.replace(m1, "Z"));
+        assertEquals("Z", map.get(m1));
+    }
+
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testDescendingReplaceValue() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", map.get(m1));
+        assertFalse(map.replace(m1, "Z", "Z"));
+        assertEquals("A", map.get(m1));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testDescendingReplaceValue2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", map.get(m1));
+        assertTrue(map.replace(m1, "A", "Z"));
+        assertEquals("Z", map.get(m1));
+    }
+
+
+    /**
+     *   remove removes the correct key-value pair from the map
+     */
+    public void testDescendingRemove() {
+        ConcurrentNavigableMap map = dmap5();
+        map.remove(m5);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(m5));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testDescendingRemove2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(map.containsKey(m5));
+        assertEquals("E", map.get(m5));
+        map.remove(m5, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(m5));
+        map.remove(m4, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(m4));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testDescendingLowerEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.lowerEntry(m3);
+        assertEquals(m2, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(m6);
+        assertEquals(m5, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(m1);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testDescendingHigherEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.higherEntry(m3);
+        assertEquals(m4, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(m1, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(m5);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testDescendingFloorEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.floorEntry(m3);
+        assertEquals(m3, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(m6);
+        assertEquals(m5, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(m1);
+        assertEquals(m1, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testDescendingCeilingEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.ceilingEntry(m3);
+        assertEquals(m3, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(m1, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(m5);
+        assertEquals(m5, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testDescendingPollFirstEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(m1, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(m2, e.getKey());
+        map.put(m1, "A");
+        e = map.pollFirstEntry();
+        assertEquals(m1, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(m3, e.getKey());
+        map.remove(m4);
+        e = map.pollFirstEntry();
+        assertEquals(m5, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testDescendingPollLastEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(m4, e.getKey());
+        map.put(m5, "E");
+        e = map.pollLastEntry();
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(m3, e.getKey());
+        map.remove(m2);
+        e = map.pollLastEntry();
+        assertEquals(m1, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     *   size returns the correct values
+     */
+    public void testDescendingSize() {
+        ConcurrentNavigableMap map = dmap5();
+        ConcurrentNavigableMap empty = dmap0();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testDescendingToString() {
+        ConcurrentNavigableMap map = dmap5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    // Exception testDescendings
+
+    /**
+     * get(null) of empty map throws NPE
+     */
+    public void testDescendingGet_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of empty map throws NPE
+     */
+    public void testDescendingContainsKey_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testDescendingContainsValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap0();
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testDescendingPut1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testDescendingPutIfAbsent1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testDescendingReplace_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testDescendingReplaceValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.replace(null, m1, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testDescendingRemove1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testDescendingRemove2_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testDescendingSerialization() throws Exception {
+        ConcurrentNavigableMap q = dmap5();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ConcurrentNavigableMap r = (ConcurrentNavigableMap)in.readObject();
+        assertEquals(q.size(), r.size());
+        assertTrue(q.equals(r));
+        assertTrue(r.equals(q));
+    }
+
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testDescendingSubMapContents() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.subMap(m2, m4);
+        assertEquals(m2, sm.firstKey());
+        assertEquals(m3, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(m2));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(m3, sm.firstKey());
+        assertEquals(m3, sm.lastKey());
+        assertEquals("C", sm.remove(m3));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testDescendingSubMapContents2() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.subMap(m2, m3);
+        assertEquals(1, sm.size());
+        assertEquals(m2, sm.firstKey());
+        assertEquals(m2, sm.lastKey());
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertFalse(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(m2));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(m3), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testDescendingHeadMapContents() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.headMap(m4);
+        assertTrue(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m1, k);
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(m4, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testDescendingTailMapContents() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.tailMap(m2);
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertTrue(sm.containsKey(m4));
+        assertTrue(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        k = (Integer)(i.next());
+        assertEquals(m4, k);
+        k = (Integer)(i.next());
+        assertEquals(m5, k);
+        assertFalse(i.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(m2, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m3, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m4, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        SortedMap ssm = sm.tailMap(m4);
+        assertEquals(m4, ssm.firstKey());
+        assertEquals(m5, ssm.lastKey());
+        assertEquals("D", ssm.remove(m4));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSubSetTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSubSetTest.java
new file mode 100644
index 0000000..9f0a496
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ConcurrentSkipListSubSetTest.java
@@ -0,0 +1,1117 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+public class ConcurrentSkipListSubSetTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListSubSetTest.class);
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Create a set of given size containing consecutive
+     * Integers 0 ... n.
+     */
+    private NavigableSet populatedSet(int n) {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+
+        for (int i = n-1; i >= 0; i-=2)
+            assertTrue(q.add(new Integer(i)));
+        for (int i = (n & 1); i < n; i+=2)
+            assertTrue(q.add(new Integer(i)));
+        assertTrue(q.add(new Integer(-n)));
+        assertTrue(q.add(new Integer(n)));
+        NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false);
+        assertFalse(s.isEmpty());
+        assertEquals(n, s.size());
+        return s;
+    }
+
+    /**
+     * Create set of first 5 ints
+     */
+    private NavigableSet set5() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        q.add(four);
+        q.add(five);
+        q.add(zero);
+        q.add(seven);
+        NavigableSet s = q.subSet(one, true, seven, false);
+        assertEquals(5, s.size());
+        return s;
+    }
+
+    /**
+     * Create set of first 5 negative ints
+     */
+    private NavigableSet dset5() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(m1);
+        q.add(m2);
+        q.add(m3);
+        q.add(m4);
+        q.add(m5);
+        NavigableSet s = q.descendingSet();
+        assertEquals(5, s.size());
+        return s;
+    }
+
+    private static NavigableSet set0() {
+        ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+        assertTrue(set.isEmpty());
+        return set.tailSet(m1, true);
+    }
+
+    private static NavigableSet dset0() {
+        ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+        assertTrue(set.isEmpty());
+        return set;
+    }
+
+    /**
+     * A new set has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, set0().size());
+    }
+
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        NavigableSet q = set0();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.pollFirst();
+        q.pollFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        try {
+            NavigableSet q = set0();
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testAdd() {
+        NavigableSet q = set0();
+        assertTrue(q.add(six));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testAddDup() {
+        NavigableSet q = set0();
+        assertTrue(q.add(six));
+        assertFalse(q.add(six));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testAddNonComparable() {
+        try {
+            NavigableSet q = set0();
+            q.add(new Object());
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        try {
+            NavigableSet q = set0();
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        try {
+            NavigableSet q = set0();
+            Integer[] ints = new Integer[SIZE];
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        try {
+            NavigableSet q = set0();
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE-1; ++i)
+                ints[i] = new Integer(i+SIZE);
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE-1- i);
+        NavigableSet q = set0();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+            assertFalse(q.remove(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        NavigableSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = set0();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE-i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            NavigableSet q = populatedSet(SIZE);
+            NavigableSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE-i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer I = (Integer)(p.pollFirst());
+                assertFalse(q.contains(I));
+            }
+        }
+    }
+
+
+
+    /**
+     * lower returns preceding element
+     */
+    public void testLower() {
+        NavigableSet q = set5();
+        Object e1 = q.lower(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lower(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lower(one);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testHigher() {
+        NavigableSet q = set5();
+        Object e1 = q.higher(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higher(five);
+        assertNull(e3);
+
+        Object e4 = q.higher(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testFloor() {
+        NavigableSet q = set5();
+        Object e1 = q.floor(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floor(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floor(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testCeiling() {
+        NavigableSet q = set5();
+        Object e1 = q.ceiling(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceiling(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceiling(six);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testToArray() {
+        NavigableSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testToArray2() {
+        NavigableSet q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        ints = (Integer[])q.toArray(ints);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        NavigableSet q = populatedSet(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testEmptyIterator() {
+        NavigableSet q = set0();
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, 0);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove () {
+        final NavigableSet q = set0();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        NavigableSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testSerialization() throws Exception {
+        NavigableSet q = populatedSet(SIZE);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        NavigableSet r = (NavigableSet)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.pollFirst(), r.pollFirst());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testSubSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.subSet(two, four);
+        assertEquals(two, sm.first());
+        assertEquals(three, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.first());
+        assertEquals(three, sm.last());
+        assertTrue(sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testSubSetContents2() {
+        NavigableSet set = set5();
+        SortedSet sm = set.subSet(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.first());
+        assertEquals(two, sm.last());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertFalse(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(three));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testHeadSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.headSet(four);
+        assertTrue(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(four, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testTailSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.tailSet(two);
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertTrue(sm.contains(four));
+        assertTrue(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(four);
+        assertEquals(four, ssm.first());
+        assertEquals(five, ssm.last());
+        assertTrue(ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testDescendingSize() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testDescendingAddNull() {
+        try {
+            NavigableSet q = dset0();
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testDescendingAdd() {
+        NavigableSet q = dset0();
+        assertTrue(q.add(m6));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testDescendingAddDup() {
+        NavigableSet q = dset0();
+        assertTrue(q.add(m6));
+        assertFalse(q.add(m6));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testDescendingAddNonComparable() {
+        try {
+            NavigableSet q = dset0();
+            q.add(new Object());
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testDescendingAddAll1() {
+        try {
+            NavigableSet q = dset0();
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testDescendingAddAll2() {
+        try {
+            NavigableSet q = dset0();
+            Integer[] ints = new Integer[SIZE];
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testDescendingAddAll3() {
+        try {
+            NavigableSet q = dset0();
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE-1; ++i)
+                ints[i] = new Integer(i+SIZE);
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testDescendingAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE-1- i);
+        NavigableSet q = dset0();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testDescendingPoll() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testDescendingRemoveElement() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+            assertFalse(q.remove(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testDescendingContains() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testDescendingClear() {
+        NavigableSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testDescendingContainsAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = dset0();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testDescendingRetainAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE-i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testDescendingRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            NavigableSet q = populatedSet(SIZE);
+            NavigableSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE-i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer I = (Integer)(p.pollFirst());
+                assertFalse(q.contains(I));
+            }
+        }
+    }
+
+
+
+    /**
+     * lower returns preceding element
+     */
+    public void testDescendingLower() {
+        NavigableSet q = dset5();
+        Object e1 = q.lower(m3);
+        assertEquals(m2, e1);
+
+        Object e2 = q.lower(m6);
+        assertEquals(m5, e2);
+
+        Object e3 = q.lower(m1);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testDescendingHigher() {
+        NavigableSet q = dset5();
+        Object e1 = q.higher(m3);
+        assertEquals(m4, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(m1, e2);
+
+        Object e3 = q.higher(m5);
+        assertNull(e3);
+
+        Object e4 = q.higher(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testDescendingFloor() {
+        NavigableSet q = dset5();
+        Object e1 = q.floor(m3);
+        assertEquals(m3, e1);
+
+        Object e2 = q.floor(m6);
+        assertEquals(m5, e2);
+
+        Object e3 = q.floor(m1);
+        assertEquals(m1, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testDescendingCeiling() {
+        NavigableSet q = dset5();
+        Object e1 = q.ceiling(m3);
+        assertEquals(m3, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(m1, e2);
+
+        Object e3 = q.ceiling(m5);
+        assertEquals(m5, e3);
+
+        Object e4 = q.ceiling(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testDescendingToArray() {
+        NavigableSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testDescendingToArray2() {
+        NavigableSet q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        ints = (Integer[])q.toArray(ints);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        NavigableSet q = populatedSet(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testDescendingEmptyIterator() {
+        NavigableSet q = dset0();
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, 0);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove () {
+        final NavigableSet q = dset0();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testDescendingToString() {
+        NavigableSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testDescendingSerialization() throws Exception {
+        NavigableSet q = populatedSet(SIZE);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        NavigableSet r = (NavigableSet)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.pollFirst(), r.pollFirst());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testDescendingSubSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.subSet(m2, m4);
+        assertEquals(m2, sm.first());
+        assertEquals(m3, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(m2));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(m3, sm.first());
+        assertEquals(m3, sm.last());
+        assertTrue(sm.remove(m3));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testDescendingSubSetContents2() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.subSet(m2, m3);
+        assertEquals(1, sm.size());
+        assertEquals(m2, sm.first());
+        assertEquals(m2, sm.last());
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertFalse(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(m2));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(m3));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testDescendingHeadSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.headSet(m4);
+        assertTrue(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m1, k);
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(m4, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testDescendingTailSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.tailSet(m2);
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertTrue(sm.contains(m4));
+        assertTrue(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        k = (Integer)(i.next());
+        assertEquals(m4, k);
+        k = (Integer)(i.next());
+        assertEquals(m5, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(m4);
+        assertEquals(m4, ssm.first());
+        assertEquals(m5, ssm.last());
+        assertTrue(ssm.remove(m4));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java
index d208039..90d708a 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArrayListTest.java
@@ -2,31 +2,26 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.io.*;
 
-public class CopyOnWriteArrayListTest extends JSR166TestCase{
-    
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
-
+public class CopyOnWriteArrayListTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(CopyOnWriteArrayListTest.class);
     }
 
-    static CopyOnWriteArrayList populatedArray(int n){
+    static CopyOnWriteArrayList populatedArray(int n) {
         CopyOnWriteArrayList a = new CopyOnWriteArrayList();
         assertTrue(a.isEmpty());
-        for (int i = 0; i < n; ++i) 
+        for (int i = 0; i < n; ++i)
             a.add(new Integer(i));
         assertFalse(a.isEmpty());
         assertEquals(n, a.size());
@@ -50,7 +45,7 @@
         for (int i = 0; i < SIZE-1; ++i)
             ints[i] = new Integer(i);
         CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints);
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertEquals(ints[i], a.get(i));
     }
 
@@ -62,10 +57,10 @@
         for (int i = 0; i < SIZE-1; ++i)
             ints[i] = new Integer(i);
         CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints));
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertEquals(ints[i], a.get(i));
     }
-        
+
 
     /**
      *   addAll  adds each element from the given collection
@@ -176,7 +171,7 @@
         assertEquals(a.hashCode(), b.hashCode());
     }
 
-    
+
     /**
      *   containsAll returns true for collection with subset of elements
      */
@@ -191,11 +186,11 @@
     }
 
     /**
-     *   get returns the  value at the given index
+     *   get returns the value at the given index
      */
     public void testGet() {
         CopyOnWriteArrayList full = populatedArray(3);
-        assertEquals(0, ((Integer)full.get(0)).intValue());
+        assertEquals(0, full.get(0));
     }
 
     /**
@@ -228,14 +223,14 @@
     }
 
     /**
-     *   iterator() returns an iterator containing the elements of the list 
+     *   iterator() returns an iterator containing the elements of the list
      */
     public void testIterator() {
         CopyOnWriteArrayList full = populatedArray(SIZE);
         Iterator i = full.iterator();
         int j;
-        for(j = 0; i.hasNext(); j++)
-            assertEquals(j, ((Integer)i.next()).intValue());
+        for (j = 0; i.hasNext(); j++)
+            assertEquals(j, i.next());
         assertEquals(SIZE, j);
     }
 
@@ -249,8 +244,7 @@
         try {
             it.remove();
             shouldThrow();
-        }
-        catch (UnsupportedOperationException success) {}
+        } catch (UnsupportedOperationException success) {}
     }
 
     /**
@@ -262,7 +256,7 @@
         for (int i = 0; i < 3; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
     /**
      *   lastIndexOf returns the index for the given object
@@ -293,8 +287,8 @@
         CopyOnWriteArrayList full = populatedArray(SIZE);
         ListIterator i = full.listIterator();
         int j;
-        for(j = 0; i.hasNext(); j++)
-            assertEquals(j, ((Integer)i.next()).intValue());
+        for (j = 0; i.hasNext(); j++)
+            assertEquals(j, i.next());
         assertEquals(SIZE, j);
     }
 
@@ -305,8 +299,8 @@
         CopyOnWriteArrayList full = populatedArray(3);
         ListIterator i = full.listIterator(1);
         int j;
-        for(j = 0; i.hasNext(); j++)
-            assertEquals(j+1, ((Integer)i.next()).intValue());
+        for (j = 0; i.hasNext(); j++)
+            assertEquals(j+1, i.next());
         assertEquals(2, j);
     }
 
@@ -315,7 +309,7 @@
      */
     public void testRemove() {
         CopyOnWriteArrayList full = populatedArray(3);
-        assertEquals(two, full.remove(2));
+        assertEquals(2, full.remove(2));
         assertEquals(2, full.size());
     }
 
@@ -336,8 +330,8 @@
      */
     public void testSet() {
         CopyOnWriteArrayList full = populatedArray(3);
-        assertEquals(two, full.set(2, four));
-        assertEquals(4, ((Integer)full.get(2)).intValue());
+        assertEquals(2, full.set(2, four));
+        assertEquals(4, full.get(2));
     }
 
     /**
@@ -357,9 +351,9 @@
         CopyOnWriteArrayList full = populatedArray(3);
         Object[] o = full.toArray();
         assertEquals(3, o.length);
-        assertEquals(0, ((Integer)o[0]).intValue());
-        assertEquals(1, ((Integer)o[1]).intValue());
-        assertEquals(2, ((Integer)o[2]).intValue());
+        assertEquals(0, o[0]);
+        assertEquals(1, o[1]);
+        assertEquals(2, o[2]);
     }
 
     /**
@@ -383,10 +377,10 @@
     public void testSubList() {
         CopyOnWriteArrayList a = populatedArray(10);
         assertTrue(a.subList(1,1).isEmpty());
-        for(int j = 0; j < 9; ++j) {
-            for(int i = j ; i < 10; ++i) {
+        for (int j = 0; j < 9; ++j) {
+            for (int i = j ; i < 10; ++i) {
                 List b = a.subList(j,i);
-                for(int k = j; k < i; ++k) {
+                for (int k = j; k < i; ++k) {
                     assertEquals(new Integer(k), b.get(k-j));
                 }
             }
@@ -413,7 +407,7 @@
             c.add("asdadasd");
             c.toArray(new Long[5]);
             shouldThrow();
-        } catch(ArrayStoreException e){}
+        } catch (ArrayStoreException success) {}
     }
 
     /**
@@ -424,9 +418,9 @@
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.get(-1);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
-    
+
     /**
      *   get throws an IndexOutOfBoundsException on a too high index
      */
@@ -437,7 +431,7 @@
             c.add("asdad");
             c.get(100);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -448,9 +442,9 @@
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.set(-1,"qwerty");
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
-    
+
     /**
      *   set throws an IndexOutOfBoundsException on a too high index
      */
@@ -461,7 +455,7 @@
             c.add("asdad");
             c.set(100, "qwerty");
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -472,9 +466,9 @@
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.add(-1,"qwerty");
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
-    
+
     /**
      *   add throws an IndexOutOfBoundsException on a too high index
      */
@@ -485,7 +479,7 @@
             c.add("asdasdasd");
             c.add(100, "qwerty");
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -496,7 +490,7 @@
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.remove(-1);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -509,9 +503,9 @@
             c.add("adasdasd");
             c.remove(100);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
-    
+
     /**
      *   addAll throws an IndexOutOfBoundsException on a negative index
      */
@@ -520,9 +514,9 @@
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.addAll(-1,new LinkedList());
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
-    
+
     /**
      *   addAll throws an IndexOutOfBoundsException on a too high index
      */
@@ -533,7 +527,7 @@
             c.add("asdasdasd");
             c.addAll(100, new LinkedList());
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -544,7 +538,7 @@
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.listIterator(-1);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -557,7 +551,7 @@
             c.add("asdasdas");
             c.listIterator(100);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -567,9 +561,8 @@
         try {
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.subList(-1,100);
-
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
@@ -581,43 +574,38 @@
             c.add("asdasd");
             c.subList(1,100);
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
      *   subList throws IndexOutOfBoundsException when the second index
-     *  is lower then the first 
+     *  is lower then the first
      */
     public void testSubList3_IndexOutOfBoundsException() {
         try {
             CopyOnWriteArrayList c = new CopyOnWriteArrayList();
             c.subList(3,1);
-
             shouldThrow();
-        } catch(IndexOutOfBoundsException e){}
+        } catch (IndexOutOfBoundsException success) {}
     }
 
     /**
-     * a deserialized serialiszed list is equal
+     * a deserialized serialized list is equal
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         CopyOnWriteArrayList q = populatedArray(SIZE);
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            CopyOnWriteArrayList r = (CopyOnWriteArrayList)in.readObject();
-            assertEquals(q.size(), r.size());
-            assertTrue(q.equals(r));
-            assertTrue(r.equals(q));
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        CopyOnWriteArrayList r = (CopyOnWriteArrayList)in.readObject();
+        assertEquals(q.size(), r.size());
+        assertTrue(q.equals(r));
+        assertTrue(r.equals(q));
     }
-    
+
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java
index 809fc59..c78ac50 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CopyOnWriteArraySetTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
@@ -14,17 +14,14 @@
 import java.io.*;
 
 public class CopyOnWriteArraySetTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(CopyOnWriteArraySetTest.class);
     }
 
-    static CopyOnWriteArraySet populatedSet(int n){
+    static CopyOnWriteArraySet populatedSet(int n) {
         CopyOnWriteArraySet a = new CopyOnWriteArraySet();
         assertTrue(a.isEmpty());
-        for (int i = 0; i < n; ++i) 
+        for (int i = 0; i < n; ++i)
             a.add(new Integer(i));
         assertFalse(a.isEmpty());
         assertEquals(n, a.size());
@@ -47,13 +44,13 @@
         for (int i = 0; i < SIZE-1; ++i)
             ints[i] = new Integer(i);
         CopyOnWriteArraySet a = new CopyOnWriteArraySet(Arrays.asList(ints));
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertTrue(a.contains(ints[i]));
     }
-        
+
 
     /**
-     *   addAll  adds each element from the given collection
+     *  addAll adds each element from the given collection
      */
     public void testAddAll() {
         CopyOnWriteArraySet full = populatedSet(3);
@@ -66,7 +63,7 @@
     }
 
     /**
-     *   addAll adds each element from the given collection that did not
+     *  addAll adds each element from the given collection that did not
      *  already exist in the set
      */
     public void testAddAll2() {
@@ -80,7 +77,7 @@
     }
 
     /**
-     *   add will not add the element if it already exists in the set
+     *  add will not add the element if it already exists in the set
      */
     public void testAdd2() {
         CopyOnWriteArraySet full = populatedSet(3);
@@ -89,8 +86,8 @@
     }
 
     /**
-     *   add  adds the element when it does not exist
-     *   in the set
+     *  add  adds the element when it does not exist
+     *  in the set
      */
     public void testAdd3() {
         CopyOnWriteArraySet full = populatedSet(3);
@@ -99,7 +96,7 @@
     }
 
     /**
-     *   clear  removes all elements from the set
+     *  clear removes all elements from the set
      */
     public void testClear() {
         CopyOnWriteArraySet full = populatedSet(3);
@@ -134,9 +131,9 @@
         assertEquals(a.hashCode(), b.hashCode());
     }
 
-    
+
     /**
-     *   containsAll returns true for collections with subset of elements
+     *  containsAll returns true for collections with subset of elements
      */
     public void testContainsAll() {
         CopyOnWriteArraySet full = populatedSet(3);
@@ -149,7 +146,7 @@
     }
 
     /**
-     *   isEmpty is true when empty, else false
+     *  isEmpty is true when empty, else false
      */
     public void testIsEmpty() {
         CopyOnWriteArraySet empty = new CopyOnWriteArraySet();
@@ -159,14 +156,14 @@
     }
 
     /**
-     *   iterator() returns an iterator containing the elements of the set 
+     *  iterator() returns an iterator containing the elements of the set
      */
     public void testIterator() {
         CopyOnWriteArraySet full = populatedSet(3);
         Iterator i = full.iterator();
         int j;
-        for(j = 0; i.hasNext(); j++)
-            assertEquals(j, ((Integer)i.next()).intValue());
+        for (j = 0; i.hasNext(); j++)
+            assertEquals(j, i.next());
         assertEquals(3, j);
     }
 
@@ -180,8 +177,7 @@
         try {
             it.remove();
             shouldThrow();
-        }
-        catch (UnsupportedOperationException success) {}
+        } catch (UnsupportedOperationException success) {}
     }
 
     /**
@@ -193,11 +189,11 @@
         for (int i = 0; i < 3; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
 
     /**
-     *   removeAll  removes all elements from the given collection
+     *  removeAll  removes all elements from the given collection
      */
     public void testRemoveAll() {
         CopyOnWriteArraySet full = populatedSet(3);
@@ -220,7 +216,7 @@
     }
 
     /**
-     *   size returns the number of elements
+     *  size returns the number of elements
      */
     public void testSize() {
         CopyOnWriteArraySet empty = new CopyOnWriteArraySet();
@@ -230,29 +226,29 @@
     }
 
     /**
-     *   toArray returns an Object array containing all elements from the set
+     *  toArray returns an Object array containing all elements from the set
      */
     public void testToArray() {
         CopyOnWriteArraySet full = populatedSet(3);
         Object[] o = full.toArray();
         assertEquals(3, o.length);
-        assertEquals(0, ((Integer)o[0]).intValue());
-        assertEquals(1, ((Integer)o[1]).intValue());
-        assertEquals(2, ((Integer)o[2]).intValue());
+        assertEquals(0, o[0]);
+        assertEquals(1, o[1]);
+        assertEquals(2, o[2]);
     }
 
     /**
-     *   toArray returns an Integer array containing all elements from
-     *   the set
+     *  toArray returns an Integer array containing all elements from
+     *  the set
      */
     public void testToArray2() {
         CopyOnWriteArraySet full = populatedSet(3);
         Integer[] i = new Integer[3];
         i = (Integer[])full.toArray(i);
         assertEquals(3, i.length);
-        assertEquals(0, i[0].intValue());
-        assertEquals(1, i[1].intValue());
-        assertEquals(2, i[2].intValue());
+        assertEquals(0, (int) i[0]);
+        assertEquals(1, (int) i[1]);
+        assertEquals(2, (int) i[2]);
     }
 
 
@@ -267,30 +263,26 @@
             c.add("asdadasd");
             c.toArray(new Long[5]);
             shouldThrow();
-        } catch(ArrayStoreException e){}
+        } catch (ArrayStoreException success) {}
     }
 
     /**
      * A deserialized serialized set is equal
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         CopyOnWriteArraySet q = populatedSet(SIZE);
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            CopyOnWriteArraySet r = (CopyOnWriteArraySet)in.readObject();
-            assertEquals(q.size(), r.size());
-            assertTrue(q.equals(r));
-            assertTrue(r.equals(q));
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        CopyOnWriteArraySet r = (CopyOnWriteArraySet)in.readObject();
+        assertEquals(q.size(), r.size());
+        assertTrue(q.equals(r));
+        assertTrue(r.equals(q));
     }
 
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java
index 0d69889..b06004e4 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CountDownLatchTest.java
@@ -2,20 +2,18 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
 public class CountDownLatchTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(CountDownLatchTest.class);
     }
@@ -27,7 +25,7 @@
         try {
             new CountDownLatch(-1);
             shouldThrow();
-        } catch(IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -55,137 +53,99 @@
     /**
      * await returns after countDown to zero, but not before
      */
-    public void testAwait() {
+    public void testAwait() throws InterruptedException {
         final CountDownLatch l = new CountDownLatch(2);
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(l.getCount() > 0);
-                        l.await();
-                        threadAssertTrue(l.getCount() == 0);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertTrue(l.getCount() > 0);
+                l.await();
+                threadAssertTrue(l.getCount() == 0);
+            }});
+
         t.start();
-        try {
-            assertEquals(l.getCount(), 2);
-            Thread.sleep(SHORT_DELAY_MS);
-            l.countDown();
-            assertEquals(l.getCount(), 1);
-            l.countDown();
-            assertEquals(l.getCount(), 0);
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        assertEquals(l.getCount(), 2);
+        Thread.sleep(SHORT_DELAY_MS);
+        l.countDown();
+        assertEquals(l.getCount(), 1);
+        l.countDown();
+        assertEquals(l.getCount(), 0);
+        t.join();
     }
-    
+
 
     /**
      * timed await returns after countDown to zero
      */
-    public void testTimedAwait() {
+    public void testTimedAwait() throws InterruptedException {
         final CountDownLatch l = new CountDownLatch(2);
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(l.getCount() > 0);
-                        threadAssertTrue(l.await(SMALL_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertTrue(l.getCount() > 0);
+                threadAssertTrue(l.await(SMALL_DELAY_MS, MILLISECONDS));
+            }});
+
         t.start();
-        try {
-            assertEquals(l.getCount(), 2);
-            Thread.sleep(SHORT_DELAY_MS);
-            l.countDown();
-            assertEquals(l.getCount(), 1);
-            l.countDown();
-            assertEquals(l.getCount(), 0);
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        assertEquals(l.getCount(), 2);
+        Thread.sleep(SHORT_DELAY_MS);
+        l.countDown();
+        assertEquals(l.getCount(), 1);
+        l.countDown();
+        assertEquals(l.getCount(), 0);
+        t.join();
     }
-    
+
     /**
      * await throws IE if interrupted before counted down
      */
-    public void testAwait_InterruptedException() {
+    public void testAwait_InterruptedException() throws InterruptedException {
         final CountDownLatch l = new CountDownLatch(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(l.getCount() > 0);
-                        l.await();
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertTrue(l.getCount() > 0);
+                l.await();
+            }});
+
         t.start();
-        try {
-            assertEquals(l.getCount(), 1);
-            t.interrupt();
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        assertEquals(l.getCount(), 1);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timed await throws IE if interrupted before counted down
      */
-    public void testTimedAwait_InterruptedException() {
+    public void testTimedAwait_InterruptedException() throws InterruptedException {
         final CountDownLatch l = new CountDownLatch(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(l.getCount() > 0);
-                        l.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();                        
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertTrue(l.getCount() > 0);
+                l.await(MEDIUM_DELAY_MS, MILLISECONDS);
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(l.getCount(), 1);
-            t.interrupt();
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(l.getCount(), 1);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timed await times out if not counted down before timeout
      */
-    public void testAwaitTimeout() {
+    public void testAwaitTimeout() throws InterruptedException {
         final CountDownLatch l = new CountDownLatch(1);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(l.getCount() > 0);
-                        threadAssertFalse(l.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(l.getCount() > 0);
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertTrue(l.getCount() > 0);
+                threadAssertFalse(l.await(SHORT_DELAY_MS, MILLISECONDS));
+                threadAssertTrue(l.getCount() > 0);
+            }});
+
         t.start();
-        try {
-            assertEquals(l.getCount(), 1);
-            t.join();
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        assertEquals(l.getCount(), 1);
+        t.join();
     }
 
     /**
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java
index ecd6e45..b8f8b24 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/CyclicBarrierTest.java
@@ -2,22 +2,20 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.locks.*;
 import java.util.concurrent.atomic.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
-public class CyclicBarrierTest extends JSR166TestCase{
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
+public class CyclicBarrierTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(CyclicBarrierTest.class);
     }
@@ -26,7 +24,7 @@
     private class MyAction implements Runnable {
         public void run() { ++countAction; }
     }
-    
+
     /**
      * Creating with negative parties throws IAE
      */
@@ -34,7 +32,7 @@
         try {
             new CyclicBarrier(-1, (Runnable)null);
             shouldThrow();
-        } catch(IllegalArgumentException e){}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -44,7 +42,7 @@
         try {
             new CyclicBarrier(-1);
             shouldThrow();
-        } catch(IllegalArgumentException e){}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -59,65 +57,48 @@
     /**
      * A 1-party barrier triggers after single await
      */
-    public void testSingleParty() {
-        try {
-            CyclicBarrier b = new CyclicBarrier(1);
-            assertEquals(1, b.getParties());
-            assertEquals(0, b.getNumberWaiting());
-            b.await();
-            b.await();
-            assertEquals(0, b.getNumberWaiting());
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testSingleParty() throws Exception {
+        CyclicBarrier b = new CyclicBarrier(1);
+        assertEquals(1, b.getParties());
+        assertEquals(0, b.getNumberWaiting());
+        b.await();
+        b.await();
+        assertEquals(0, b.getNumberWaiting());
     }
-    
+
     /**
      * The supplied barrier action is run at barrier
      */
-    public void testBarrierAction() {
-        try {
-            countAction = 0;
-            CyclicBarrier b = new CyclicBarrier(1, new MyAction());
-            assertEquals(1, b.getParties());
-            assertEquals(0, b.getNumberWaiting());
-            b.await();
-            b.await();
-            assertEquals(0, b.getNumberWaiting());
-            assertEquals(countAction, 2);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testBarrierAction() throws Exception {
+        countAction = 0;
+        CyclicBarrier b = new CyclicBarrier(1, new MyAction());
+        assertEquals(1, b.getParties());
+        assertEquals(0, b.getNumberWaiting());
+        b.await();
+        b.await();
+        assertEquals(0, b.getNumberWaiting());
+        assertEquals(countAction, 2);
     }
 
     /**
      * A 2-party/thread barrier triggers after both threads invoke await
      */
-    public void testTwoParties() {
+    public void testTwoParties() throws Exception {
         final CyclicBarrier b = new CyclicBarrier(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        b.await();
-                        b.await();
-                        b.await();
-                        b.await();
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }}});
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                b.await();
+                b.await();
+                b.await();
+                b.await();
+            }});
 
-        try {
-            t.start();
-            b.await();
-            b.await();
-            b.await();
-            b.await();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t.start();
+        b.await();
+        b.await();
+        b.await();
+        b.await();
+        t.join();
     }
 
 
@@ -125,502 +106,320 @@
      * An interruption in one party causes others waiting in await to
      * throw BrokenBarrierException
      */
-    public void testAwait1_Interrupted_BrokenBarrier() {
+    public void testAwait1_Interrupted_BrokenBarrier() throws Exception {
         final CyclicBarrier c = new CyclicBarrier(3);
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}                
-                    catch(Exception b){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                        threadShouldThrow();                        
-                    } catch(BrokenBarrierException success){
-                    } catch(Exception i){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t1.interrupt();
-            t1.join(); 
-            t2.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws Exception {
+                c.await();
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                c.await();
+            }};
+
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t1.interrupt();
+        t1.join();
+        t2.join();
     }
 
     /**
      * An interruption in one party causes others waiting in timed await to
      * throw BrokenBarrierException
      */
-    public void testAwait2_Interrupted_BrokenBarrier() {
+    public void testAwait2_Interrupted_BrokenBarrier() throws Exception {
         final CyclicBarrier c = new CyclicBarrier(3);
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    } catch(Exception b){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();                        
-                    } catch(BrokenBarrierException success){
-                    } catch(Exception i){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t1.interrupt();
-            t1.join(); 
-            t2.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws Exception {
+                c.await(LONG_DELAY_MS, MILLISECONDS);
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                c.await(LONG_DELAY_MS, MILLISECONDS);
+            }};
+
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t1.interrupt();
+        t1.join();
+        t2.join();
     }
-    
+
     /**
      * A timeout in timed await throws TimeoutException
      */
-    public void testAwait3_TimeOutException() {
+    public void testAwait3_TimeOutException() throws InterruptedException {
         final CyclicBarrier c = new CyclicBarrier(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(TimeoutException success){
-                    } catch(Exception b){
-                        threadUnexpectedException();
-                        
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join(); 
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new ThreadShouldThrow(TimeoutException.class) {
+            public void realRun() throws Exception {
+                c.await(SHORT_DELAY_MS, MILLISECONDS);
+            }};
+
+        t.start();
+        t.join();
     }
 
     /**
      * A timeout in one party causes others waiting in timed await to
      * throw BrokenBarrierException
      */
-    public void testAwait4_Timeout_BrokenBarrier() {
+    public void testAwait4_Timeout_BrokenBarrier() throws InterruptedException {
         final CyclicBarrier c = new CyclicBarrier(3);
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(TimeoutException success){
-                    } catch(Exception b){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();                        
-                    } catch(BrokenBarrierException success){
-                    } catch(Exception i){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            t1.join(); 
-            t2.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread t1 = new ThreadShouldThrow(TimeoutException.class) {
+            public void realRun() throws Exception {
+                c.await(SHORT_DELAY_MS, MILLISECONDS);
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                c.await(MEDIUM_DELAY_MS, MILLISECONDS);
+            }};
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
     }
 
     /**
      * A timeout in one party causes others waiting in await to
      * throw BrokenBarrierException
      */
-    public void testAwait5_Timeout_BrokenBarrier() {
+    public void testAwait5_Timeout_BrokenBarrier() throws InterruptedException {
         final CyclicBarrier c = new CyclicBarrier(3);
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(TimeoutException success){
-                    } catch(Exception b){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                        threadShouldThrow();                        
-                    } catch(BrokenBarrierException success){
-                    } catch(Exception i){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            t1.join(); 
-            t2.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread t1 = new ThreadShouldThrow(TimeoutException.class) {
+            public void realRun() throws Exception {
+                c.await(SHORT_DELAY_MS, MILLISECONDS);
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                c.await();
+            }};
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
     }
-    
+
     /**
      * A reset of an active barrier causes waiting threads to throw
      * BrokenBarrierException
      */
-    public void testReset_BrokenBarrier() {
+    public void testReset_BrokenBarrier() throws InterruptedException {
         final CyclicBarrier c = new CyclicBarrier(3);
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                        threadShouldThrow();
-                    } catch(BrokenBarrierException success){}                
-                    catch(Exception b){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                        threadShouldThrow();                        
-                    } catch(BrokenBarrierException success){
-                    } catch(Exception i){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            c.reset();
-            t1.join(); 
-            t2.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                c.await();
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                c.await();
+            }};
+
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        c.reset();
+        t1.join();
+        t2.join();
     }
 
     /**
      * A reset before threads enter barrier does not throw
      * BrokenBarrierException
      */
-    public void testReset_NoBrokenBarrier() {
+    public void testReset_NoBrokenBarrier() throws Exception {
         final CyclicBarrier c = new CyclicBarrier(3);
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                    } catch(Exception b){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        c.await();
-                    } catch(Exception i){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            c.reset();
-            t1.start();
-            t2.start();
-            c.await();
-            t1.join(); 
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                c.await();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                c.await();
+            }});
+
+        c.reset();
+        t1.start();
+        t2.start();
+        c.await();
+        t1.join();
+        t2.join();
     }
 
     /**
      * All threads block while a barrier is broken.
      */
-    public void testReset_Leakage() {
-        try {
-            final CyclicBarrier c = new CyclicBarrier(2);
-            final AtomicBoolean done = new AtomicBoolean();
-            Thread t = new Thread() {
-                    public void run() {
-                        while (!done.get()) {
-                            try {
-                                while (c.isBroken())
-                                    c.reset();
-                                
-                                c.await();
-                                threadFail("await should not return");
-                            }
-                            catch (BrokenBarrierException e) {
-                            }
-                            catch (InterruptedException ie) {
-                            }
+    public void testReset_Leakage() throws InterruptedException {
+        final CyclicBarrier c = new CyclicBarrier(2);
+        final AtomicBoolean done = new AtomicBoolean();
+        Thread t = new Thread() {
+                public void run() {
+                    while (!done.get()) {
+                        try {
+                            while (c.isBroken())
+                                c.reset();
+
+                            c.await();
+                            threadFail("await should not return");
+                        }
+                        catch (BrokenBarrierException e) {
+                        }
+                        catch (InterruptedException ie) {
                         }
                     }
-                };
-            
-            t.start();
-            for( int i = 0; i < 4; i++) {
-                Thread.sleep(SHORT_DELAY_MS);
-                t.interrupt();
-            }
-            done.set(true);
+                }
+            };
+
+        t.start();
+        for (int i = 0; i < 4; i++) {
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
         }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        done.set(true);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * Reset of a non-broken barrier does not break barrier
      */
-    public void testResetWithoutBreakage() {
-        try {
-            final CyclicBarrier start = new CyclicBarrier(3);
-            final CyclicBarrier barrier = new CyclicBarrier(3);
-            for (int i = 0; i < 3; i++) {
-                Thread t1 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                Thread t2 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                
-                t1.start();
-                t2.start();
-                try { start.await(); }
-                catch (Exception ie) { threadFail("start barrier"); }
-                barrier.await();
-                t1.join();
-                t2.join();
-                assertFalse(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-                if (i == 1) barrier.reset();
-                assertFalse(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-            }
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
-    }
-        
-    /**
-     * Reset of a barrier after interruption reinitializes it.
-     */
-    public void testResetAfterInterrupt() {
-        try {
-            final CyclicBarrier start = new CyclicBarrier(3);
-            final CyclicBarrier barrier = new CyclicBarrier(3);
-            for (int i = 0; i < 2; i++) {
-                Thread t1 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch(InterruptedException ok) {}
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                Thread t2 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch(BrokenBarrierException ok) {}
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                t1.start();
-                t2.start();
-                try { start.await(); }
-                catch (Exception ie) { threadFail("start barrier"); }
-                t1.interrupt();
-                t1.join();
-                t2.join();
-                assertTrue(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-                barrier.reset();
-                assertFalse(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-            }
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
-    }
-        
-    /**
-     * Reset of a barrier after timeout reinitializes it.
-     */
-    public void testResetAfterTimeout() {
-        try {
-            final CyclicBarrier start = new CyclicBarrier(3);
-            final CyclicBarrier barrier = new CyclicBarrier(3);
-            for (int i = 0; i < 2; i++) {
-                Thread t1 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); }
-                            catch(TimeoutException ok) {}
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                Thread t2 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch(BrokenBarrierException ok) {}
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                t1.start();
-                t2.start();
-                try { start.await(); }
-                catch (Exception ie) { threadFail("start barrier"); }
-                t1.join();
-                t2.join();
-                assertTrue(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-                barrier.reset();
-                assertFalse(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-            }
-        }
-        catch (Exception ex) {
-            unexpectedException();
+    public void testResetWithoutBreakage() throws Exception {
+        final CyclicBarrier start = new CyclicBarrier(3);
+        final CyclicBarrier barrier = new CyclicBarrier(3);
+        for (int i = 0; i < 3; i++) {
+            Thread t1 = new Thread(new CheckedRunnable() {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }});
+
+            Thread t2 = new Thread(new CheckedRunnable() {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }});
+
+            t1.start();
+            t2.start();
+            start.await();
+            barrier.await();
+            t1.join();
+            t2.join();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            if (i == 1) barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
         }
     }
 
-    
+    /**
+     * Reset of a barrier after interruption reinitializes it.
+     */
+    public void testResetAfterInterrupt() throws Exception {
+        final CyclicBarrier start = new CyclicBarrier(3);
+        final CyclicBarrier barrier = new CyclicBarrier(3);
+        for (int i = 0; i < 2; i++) {
+            Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            t1.start();
+            t2.start();
+            start.await();
+            t1.interrupt();
+            t1.join();
+            t2.join();
+            assertTrue(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+        }
+    }
+
+    /**
+     * Reset of a barrier after timeout reinitializes it.
+     */
+    public void testResetAfterTimeout() throws Exception {
+        final CyclicBarrier start = new CyclicBarrier(3);
+        final CyclicBarrier barrier = new CyclicBarrier(3);
+        for (int i = 0; i < 2; i++) {
+            Thread t1 = new ThreadShouldThrow(TimeoutException.class) {
+                    public void realRun() throws Exception {
+                        start.await();
+                        barrier.await(MEDIUM_DELAY_MS, MILLISECONDS);
+                    }};
+
+            Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            t1.start();
+            t2.start();
+            start.await();
+            t1.join();
+            t2.join();
+            assertTrue(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+        }
+    }
+
+
     /**
      * Reset of a barrier after a failed command reinitializes it.
      */
-    public void testResetAfterCommandException() {
-        try {
-            final CyclicBarrier start = new CyclicBarrier(3);
-            final CyclicBarrier barrier = 
-                new CyclicBarrier(3, new Runnable() {
-                        public void run() { 
-                            throw new NullPointerException(); }});
-            for (int i = 0; i < 2; i++) {
-                Thread t1 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch(BrokenBarrierException ok) {}
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                Thread t2 = new Thread(new Runnable() {
-                        public void run() {
-                            try { start.await(); }
-                            catch (Exception ie) { 
-                                threadFail("start barrier"); 
-                            }
-                            try { barrier.await(); }
-                            catch(BrokenBarrierException ok) {}
-                            catch (Throwable thrown) { 
-                                unexpectedException(); 
-                            }}});
-                
-                t1.start();
-                t2.start();
-                try { start.await(); }
-                catch (Exception ie) { threadFail("start barrier"); }
-                while (barrier.getNumberWaiting() < 2) { Thread.yield(); }
-                try { barrier.await(); }
-                catch (Exception ok) { }
-                t1.join();
-                t2.join();
-                assertTrue(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-                barrier.reset();
-                assertFalse(barrier.isBroken());
-                assertEquals(0, barrier.getNumberWaiting());
-            }
-        }
-        catch (Exception ex) {
-            unexpectedException();
+    public void testResetAfterCommandException() throws Exception {
+        final CyclicBarrier start = new CyclicBarrier(3);
+        final CyclicBarrier barrier =
+            new CyclicBarrier(3, new Runnable() {
+                    public void run() {
+                        throw new NullPointerException(); }});
+        for (int i = 0; i < 2; i++) {
+            Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            t1.start();
+            t2.start();
+            start.await();
+            while (barrier.getNumberWaiting() < 2) { Thread.yield(); }
+            try {
+                barrier.await();
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            t1.join();
+            t2.join();
+            assertTrue(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
         }
     }
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
index 978edb4..7aeceda 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/DelayQueueTest.java
@@ -2,30 +2,27 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.concurrent.*;
 
 public class DelayQueueTest extends JSR166TestCase {
-    public static void main(String[] args) {
-	junit.textui.TestRunner.run (suite());
-    }
-
     public static Test suite() {
-	return new TestSuite(DelayQueueTest.class);
+        return new TestSuite(DelayQueueTest.class);
     }
 
     private static final int NOCAP = Integer.MAX_VALUE;
 
     /**
      * A delayed implementation for testing.
-     * Most  tests use Pseudodelays, where delays are all elapsed
+     * Most tests use Pseudodelays, where delays are all elapsed
      * (so, no blocking solely for delays) but are still ordered
      */
     static class PDelay implements Delayed {
@@ -33,25 +30,21 @@
         PDelay(int i) { pseudodelay = Integer.MIN_VALUE + i; }
         public int compareTo(PDelay y) {
             int i = pseudodelay;
-            int j = ((PDelay)y).pseudodelay;
+            int j = y.pseudodelay;
             if (i < j) return -1;
             if (i > j) return 1;
             return 0;
         }
 
         public int compareTo(Delayed y) {
-            int i = pseudodelay;
-            int j = ((PDelay)y).pseudodelay;
-            if (i < j) return -1;
-            if (i > j) return 1;
-            return 0;
+            return compareTo((PDelay)y);
         }
 
         public boolean equals(Object other) {
-            return ((PDelay)other).pseudodelay == pseudodelay;
+            return equals((PDelay)other);
         }
         public boolean equals(PDelay other) {
-            return ((PDelay)other).pseudodelay == pseudodelay;
+            return other.pseudodelay == pseudodelay;
         }
 
 
@@ -78,25 +71,21 @@
         }
         public int compareTo(NanoDelay y) {
             long i = trigger;
-            long j = ((NanoDelay)y).trigger;
+            long j = y.trigger;
             if (i < j) return -1;
             if (i > j) return 1;
             return 0;
         }
 
         public int compareTo(Delayed y) {
-            long i = trigger;
-            long j = ((NanoDelay)y).trigger;
-            if (i < j) return -1;
-            if (i > j) return 1;
-            return 0;
+            return compareTo((NanoDelay)y);
         }
 
         public boolean equals(Object other) {
-            return ((NanoDelay)other).trigger == trigger;
+            return equals((NanoDelay)other);
         }
         public boolean equals(NanoDelay other) {
-            return ((NanoDelay)other).trigger == trigger;
+            return other.trigger == trigger;
         }
 
         public long getDelay(TimeUnit unit) {
@@ -121,13 +110,13 @@
     private DelayQueue populatedQueue(int n) {
         DelayQueue q = new DelayQueue();
         assertTrue(q.isEmpty());
-	for(int i = n-1; i >= 0; i-=2)
-	    assertTrue(q.offer(new PDelay(i)));
-	for(int i = (n & 1); i < n; i+=2)
-	    assertTrue(q.offer(new PDelay(i)));
+        for (int i = n-1; i >= 0; i-=2)
+            assertTrue(q.offer(new PDelay(i)));
+        for (int i = (n & 1); i < n; i+=2)
+            assertTrue(q.offer(new PDelay(i)));
         assertFalse(q.isEmpty());
         assertEquals(NOCAP, q.remainingCapacity());
-	assertEquals(n, q.size());
+        assertEquals(n, q.size());
         return q;
     }
 
@@ -145,8 +134,7 @@
         try {
             DelayQueue q = new DelayQueue(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -157,8 +145,7 @@
             PDelay[] ints = new PDelay[SIZE];
             DelayQueue q = new DelayQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -171,23 +158,19 @@
                 ints[i] = new PDelay(i);
             DelayQueue q = new DelayQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of collection used to initialize
      */
     public void testConstructor6() {
-        try {
-            PDelay[] ints = new PDelay[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new PDelay(i);
-            DelayQueue q = new DelayQueue(Arrays.asList(ints));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        PDelay[] ints = new PDelay[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new PDelay(i);
+        DelayQueue q = new DelayQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -206,7 +189,7 @@
     }
 
     /**
-     * remainingCapacity does not change when elementa added or removed,
+     * remainingCapacity does not change when elements added or removed,
      * but size does
      */
     public void testRemainingCapacity() {
@@ -227,22 +210,22 @@
      * offer(null) throws NPE
      */
     public void testOfferNull() {
-	try {
+        try {
             DelayQueue q = new DelayQueue();
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * add(null) throws NPE
      */
     public void testAddNull() {
-	try {
+        try {
             DelayQueue q = new DelayQueue();
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -273,8 +256,7 @@
             DelayQueue q = new DelayQueue();
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
 
@@ -286,8 +268,7 @@
             DelayQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -299,8 +280,7 @@
             PDelay[] ints = new PDelay[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with any null elements throws NPE after
@@ -314,179 +294,133 @@
                 ints[i] = new PDelay(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of successful addAll
      */
     public void testAddAll5() {
-        try {
-            PDelay[] empty = new PDelay[0];
-            PDelay[] ints = new PDelay[SIZE];
-            for (int i = SIZE-1; i >= 0; --i)
-                ints[i] = new PDelay(i);
-            DelayQueue q = new DelayQueue();
-            assertFalse(q.addAll(Arrays.asList(empty)));
-            assertTrue(q.addAll(Arrays.asList(ints)));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        PDelay[] empty = new PDelay[0];
+        PDelay[] ints = new PDelay[SIZE];
+        for (int i = SIZE-1; i >= 0; --i)
+            ints[i] = new PDelay(i);
+        DelayQueue q = new DelayQueue();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
      * put(null) throws NPE
      */
      public void testPutNull() {
-	try {
+        try {
             DelayQueue q = new DelayQueue();
             q.put(null);
             shouldThrow();
-        }
-        catch (NullPointerException success){
-	}
+        } catch (NullPointerException success) {}
      }
 
     /**
      * all elements successfully put are contained
      */
      public void testPut() {
-         try {
-             DelayQueue q = new DelayQueue();
-             for (int i = 0; i < SIZE; ++i) {
-                 PDelay I = new PDelay(i);
-                 q.put(I);
-                 assertTrue(q.contains(I));
-             }
-             assertEquals(SIZE, q.size());
+         DelayQueue q = new DelayQueue();
+         for (int i = 0; i < SIZE; ++i) {
+             PDelay I = new PDelay(i);
+             q.put(I);
+             assertTrue(q.contains(I));
          }
-         finally {
-        }
+         assertEquals(SIZE, q.size());
     }
 
     /**
      * put doesn't block waiting for take
      */
-    public void testPutWithTake() {
+    public void testPutWithTake() throws InterruptedException {
         final DelayQueue q = new DelayQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        q.put(new PDelay(0));
-                        ++added;
-                        q.put(new PDelay(0));
-                        ++added;
-                        q.put(new PDelay(0));
-                        ++added;
-                        q.put(new PDelay(0));
-                        ++added;
-                        threadAssertTrue(added == 4);
-                    } finally {
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.take();
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        q.take();
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timed offer does not time out
      */
-    public void testTimedOffer() {
+    public void testTimedOffer() throws InterruptedException {
         final DelayQueue q = new DelayQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new PDelay(0));
-                        q.put(new PDelay(0));
-                        threadAssertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } finally { }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+                assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, MILLISECONDS));
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * take retrieves elements in priority order
      */
-    public void testTake() {
-	try {
-            DelayQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(new PDelay(i), ((PDelay)q.take()));
-            }
-        } catch (InterruptedException e){
-	    unexpectedException();
-	}
+    public void testTake() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), ((PDelay)q.take()));
+        }
     }
 
     /**
      * take blocks interruptibly when empty
      */
-    public void testTakeFromEmpty() {
+    public void testTakeFromEmpty() throws InterruptedException {
         final DelayQueue q = new DelayQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.take();
-			threadShouldThrow();
-                    } catch (InterruptedException success){ }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }};
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * Take removes existing elements until empty, then blocks interruptibly
      */
-    public void testBlockingTake() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        DelayQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(new PDelay(i), ((PDelay)q.take()));
-                        }
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){
-                    }
-                }});
+    public void testBlockingTake() throws InterruptedException {
+        final DelayQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(new PDelay(i), ((PDelay)q.take()));
+                }
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
         t.start();
-        try {
-           Thread.sleep(SHORT_DELAY_MS);
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-	    unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
@@ -498,91 +432,76 @@
         for (int i = 0; i < SIZE; ++i) {
             assertEquals(new PDelay(i), ((PDelay)q.poll()));
         }
-	assertNull(q.poll());
+        assertNull(q.poll());
     }
 
     /**
      * timed pool with zero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll0() {
-        try {
-            DelayQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(new PDelay(i), ((PDelay)q.poll(0, TimeUnit.MILLISECONDS)));
-            }
-            assertNull(q.poll(0, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-	    unexpectedException();
-	}
+    public void testTimedPoll0() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), ((PDelay)q.poll(0, MILLISECONDS)));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
     }
 
     /**
      * timed pool with nonzero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll() {
-        try {
-            DelayQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)));
-            }
-            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-	    unexpectedException();
-	}
+    public void testTimedPoll() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
+        }
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
     }
 
     /**
      * Interrupted timed poll throws InterruptedException instead of
      * returning timeout status
      */
-    public void testInterruptedTimedPoll() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        DelayQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)));
-                        }
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch (InterruptedException success){
-                    }
-                }});
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                DelayQueue q = populatedQueue(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
+                }
+                try {
+                    q.poll(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
         t.start();
-        try {
-           Thread.sleep(SHORT_DELAY_MS);
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-	    unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  timed poll before a delayed offer fails; after offer succeeds;
      *  on interruption throws
      */
-    public void testTimedPollWithOffer() {
+    public void testTimedPollWithOffer() throws InterruptedException {
         final DelayQueue q = new DelayQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-			threadFail("Should block");
-                    } catch (InterruptedException success) { }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        final PDelay pdelay = new PDelay(0);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(pdelay, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(pdelay, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
     }
 
 
@@ -593,13 +512,13 @@
         DelayQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
             assertEquals(new PDelay(i), ((PDelay)q.peek()));
-            q.poll();
+            assertEquals(new PDelay(i), ((PDelay)q.poll()));
             if (q.isEmpty())
                 assertNull(q.peek());
             else
-                assertTrue(i != ((PDelay)q.peek()).intValue());
+                assertFalse(new PDelay(i).equals(q.peek()));
         }
-	assertNull(q.peek());
+        assertNull(q.peek());
     }
 
     /**
@@ -614,8 +533,7 @@
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -629,8 +547,7 @@
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-	}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -729,32 +646,24 @@
     /**
      * toArray contains all elements
      */
-    public void testToArray() {
+    public void testToArray() throws InterruptedException {
         DelayQueue q = populatedQueue(SIZE);
-	Object[] o = q.toArray();
+        Object[] o = q.toArray();
         Arrays.sort(o);
-	try {
-	for(int i = 0; i < o.length; i++)
-	    assertEquals(o[i], q.take());
-	} catch (InterruptedException e){
-	    unexpectedException();
-	}
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.take());
     }
 
     /**
      * toArray(a) contains all elements
      */
-    public void testToArray2() {
+    public void testToArray2() throws InterruptedException {
         DelayQueue q = populatedQueue(SIZE);
-	PDelay[] ints = new PDelay[SIZE];
-	ints = (PDelay[])q.toArray(ints);
+        PDelay[] ints = new PDelay[SIZE];
+        ints = (PDelay[])q.toArray(ints);
         Arrays.sort(ints);
-	try {
-	    for(int i = 0; i < ints.length; i++)
-		assertEquals(ints[i], q.take());
-	} catch (InterruptedException e){
-	    unexpectedException();
-	}
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.take());
     }
 
 
@@ -762,22 +671,22 @@
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
-	try {
-            DelayQueue q = populatedQueue(SIZE);
-	    Object o[] = q.toArray(null);
-	    shouldThrow();
-	} catch(NullPointerException success){}
+        DelayQueue q = populatedQueue(SIZE);
+        try {
+            Object o[] = q.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
      * toArray with incompatible array type throws CCE
      */
     public void testToArray1_BadArg() {
-	try {
-            DelayQueue q = populatedQueue(SIZE);
-	    Object o[] = q.toArray(new String[10] );
-	    shouldThrow();
-	} catch(ArrayStoreException  success){}
+        DelayQueue q = populatedQueue(SIZE);
+        try {
+            Object o[] = q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
     }
 
     /**
@@ -786,8 +695,8 @@
     public void testIterator() {
         DelayQueue q = populatedQueue(SIZE);
         int i = 0;
-	Iterator it = q.iterator();
-        while(it.hasNext()) {
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
             assertTrue(q.contains(it.next()));
             ++i;
         }
@@ -829,39 +738,27 @@
     public void testPollInExecutor() {
         final DelayQueue q = new DelayQueue();
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertNull(q.poll());
-                try {
-                    threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertTrue(q.isEmpty());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll());
+                assertTrue(null != q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(q.isEmpty());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SHORT_DELAY_MS);
-                    q.put(new PDelay(1));
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SHORT_DELAY_MS);
+                q.put(new PDelay(1));
+            }});
+
         joinPool(executor);
-
     }
 
 
     /**
      * Delayed actions do not occur until their delay elapses
      */
-    public void testDelay() {
+    public void testDelay() throws InterruptedException {
         DelayQueue q = new DelayQueue();
         NanoDelay[] elements = new NanoDelay[SIZE];
         for (int i = 0; i < SIZE; ++i) {
@@ -871,19 +768,14 @@
             q.add(elements[i]);
         }
 
-        try {
-            long last = 0;
-            for (int i = 0; i < SIZE; ++i) {
-                NanoDelay e = (NanoDelay)(q.take());
-                long tt = e.getTriggerTime();
-                assertTrue(tt <= System.nanoTime());
-                if (i != 0)
-                    assertTrue(tt >= last);
-                last = tt;
-            }
-        }
-        catch(InterruptedException ie) {
-            unexpectedException();
+        long last = 0;
+        for (int i = 0; i < SIZE; ++i) {
+            NanoDelay e = (NanoDelay)(q.take());
+            long tt = e.getTriggerTime();
+            assertTrue(tt <= System.nanoTime());
+            if (i != 0)
+                assertTrue(tt >= last);
+            last = tt;
         }
     }
 
@@ -909,14 +801,10 @@
     /**
      * timed poll of a non-empty queue returns null if no expired elements.
      */
-    public void testTimedPollDelayed() {
+    public void testTimedPollDelayed() throws InterruptedException {
         DelayQueue q = new DelayQueue();
         q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
-        try {
-            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
     }
 
     /**
@@ -927,8 +815,7 @@
         try {
             q.drainTo(null);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -939,8 +826,7 @@
         try {
             q.drainTo(q);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -973,53 +859,47 @@
 
     /**
      * drainTo empties queue
-     */ 
-    public void testDrainToWithActivePut() {
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
         final DelayQueue q = populatedQueue(SIZE);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    q.put(new PDelay(SIZE+1));
-                }
-            });
-        try {
-            t.start();
-            ArrayList l = new ArrayList();
-            q.drainTo(l);
-            assertTrue(l.size() >= SIZE);
-            t.join();
-            assertTrue(q.size() + l.size() >= SIZE);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new PDelay(SIZE+1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
     }
 
     /**
      * drainTo(null, n) throws NPE
-     */ 
+     */
     public void testDrainToNullN() {
         DelayQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(null, 0);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this, n) throws IAE
-     */ 
+     */
     public void testDrainToSelfN() {
         DelayQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(q, 0);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c, n) empties first max {n, size} elements of queue into c
-     */ 
+     */
     public void testDrainToN() {
         for (int i = 0; i < SIZE + 2; ++i) {
             DelayQueue q = populatedQueue(SIZE);
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/EntryTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/EntryTest.java
new file mode 100644
index 0000000..893fd48
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/EntryTest.java
@@ -0,0 +1,131 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+public class EntryTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(EntryTest.class);
+    }
+
+    static final String k1 = "1";
+    static final String v1 = "a";
+    static final String k2 = "2";
+    static final String v2 = "b";
+
+
+    /**
+     * A new SimpleEntry(k, v) holds k, v.
+     */
+    public void testConstructor1() {
+        Map.Entry e = new AbstractMap.SimpleEntry(k1, v1);
+        assertEquals(k1, e.getKey());
+        assertEquals(v1, e.getValue());
+    }
+
+    /**
+     * A new SimpleImmutableEntry(k, v) holds k, v.
+     */
+    public void testConstructor2() {
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        assertEquals(k1, s.getKey());
+        assertEquals(v1, s.getValue());
+    }
+
+
+    /**
+     * A new SimpleEntry(entry(k, v)) holds k, v.
+     */
+    public void testConstructor3() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(e2);
+        assertEquals(k1, e.getKey());
+        assertEquals(v1, e.getValue());
+    }
+
+    /**
+     * A new SimpleImmutableEntry(entry(k, v)) holds k, v.
+     */
+    public void testConstructor4() {
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+        assertEquals(k1, s.getKey());
+        assertEquals(v1, s.getValue());
+    }
+
+    /**
+     * Entries with same key-value pairs are equal and have same
+     * hashcodes
+     */
+    public void testEquals() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(e2);
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+        assertEquals(e2, e);
+        assertEquals(e2.hashCode(), e.hashCode());
+        assertEquals(s2, s);
+        assertEquals(s2.hashCode(), s.hashCode());
+        assertEquals(e2, s2);
+        assertEquals(e2.hashCode(), s2.hashCode());
+        assertEquals(e, s);
+        assertEquals(e.hashCode(), s.hashCode());
+    }
+
+    /**
+     * Entries with different key-value pairs are not equal
+     */
+    public void testNotEquals() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(k2, v1);
+        assertFalse(e2.equals( e));
+        e = new AbstractMap.SimpleEntry(k1, v2);
+        assertFalse(e2.equals( e));
+        e = new AbstractMap.SimpleEntry(k2, v2);
+        assertFalse(e2.equals( e));
+
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(k2, v1);
+        assertFalse(s2.equals( s));
+        s = new AbstractMap.SimpleImmutableEntry(k1, v2);
+        assertFalse(s2.equals( s));
+        s = new AbstractMap.SimpleImmutableEntry(k2, v2);
+        assertFalse(s2.equals( s));
+    }
+
+
+    /**
+     * getValue returns last setValue for SimpleEntry
+     */
+    public void testSetValue1() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(e2);
+        assertEquals(k1, e.getKey());
+        assertEquals(v1, e.getValue());
+        e.setValue(k2);
+        assertEquals(k2, e.getValue());
+        assertFalse(e2.equals( e));
+    }
+
+    /**
+     * setValue for SimpleImmutableEntry throws UnsupportedOperationException
+     */
+    public void testsetValue2() {
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+        assertEquals(k1, s.getKey());
+        assertEquals(v1, s.getValue());
+        try {
+            s.setValue(k2);
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java
index 9811e82..be1eaa3 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ExchangerTest.java
@@ -2,21 +2,18 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
 public class ExchangerTest extends JSR166TestCase {
-   
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(ExchangerTest.class);
     }
@@ -24,211 +21,123 @@
     /**
      * exchange exchanges objects across two threads
      */
-    public void testExchange() {
+    public void testExchange() throws InterruptedException {
         final Exchanger e = new Exchanger();
-        Thread t1 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Object v = e.exchange(one);
-                        threadAssertEquals(v, two);
-                        Object w = e.exchange(v);
-                        threadAssertEquals(w, one);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Object v = e.exchange(two);
-                        threadAssertEquals(v, one);
-                        Object w = e.exchange(v);
-                        threadAssertEquals(w, two);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            t1.join();
-            t2.join();
-        } catch(InterruptedException ex) {
-            unexpectedException();
-        }
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(one, e.exchange(two));
+                assertSame(two, e.exchange(one));
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(two, e.exchange(one));
+                assertSame(one, e.exchange(two));
+            }});
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
     }
 
     /**
      * timed exchange exchanges objects across two threads
      */
-    public void testTimedExchange() {
+    public void testTimedExchange() throws InterruptedException {
         final Exchanger e = new Exchanger();
-        Thread t1 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Object v = e.exchange(one, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadAssertEquals(v, two);
-                        Object w = e.exchange(v, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadAssertEquals(w, one);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    } catch(TimeoutException toe) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Object v = e.exchange(two, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadAssertEquals(v, one);
-                        Object w = e.exchange(v, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadAssertEquals(w, two);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    } catch(TimeoutException toe) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t1.start();
-            t2.start();
-            t1.join();
-            t2.join();
-        } catch(InterruptedException ex) {
-            unexpectedException();
-        }
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                assertSame(one, e.exchange(two, SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(two, e.exchange(one, SHORT_DELAY_MS, MILLISECONDS));
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                assertSame(two, e.exchange(one, SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(one, e.exchange(two, SHORT_DELAY_MS, MILLISECONDS));
+            }});
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
     }
 
     /**
      * interrupt during wait for exchange throws IE
      */
-    public void testExchange_InterruptedException(){
+    public void testExchange_InterruptedException() throws InterruptedException {
         final Exchanger e = new Exchanger();
-        Thread t = new Thread(new Runnable() {
-                public void run(){
-                    try {
-                        e.exchange(one);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException ex) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                e.exchange(one);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * interrupt during wait for timed exchange throws IE
      */
-    public void testTimedExchange_InterruptedException(){
+    public void testTimedExchange_InterruptedException() throws InterruptedException {
         final Exchanger e = new Exchanger();
-        Thread t = new Thread(new Runnable() {
-                public void run(){
-                    try {
-                        e.exchange(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    } catch(Exception e2){
-                        threadFail("should throw IE");
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException ex){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws Exception {
+                e.exchange(null, SMALL_DELAY_MS, MILLISECONDS);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timeout during wait for timed exchange throws TOE
      */
-    public void testExchange_TimeOutException(){
+    public void testExchange_TimeOutException() throws InterruptedException {
         final Exchanger e = new Exchanger();
-        Thread t = new Thread(new Runnable() {
-                public void run(){
-                    try {
-                        e.exchange(null, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(TimeoutException success){
-                    } catch(InterruptedException e2){
-                        threadFail("should throw TOE");
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-        } catch(InterruptedException ex){
-            unexpectedException();
-        }
+        Thread t = new ThreadShouldThrow(TimeoutException.class) {
+            public void realRun() throws Exception {
+                e.exchange(null, SHORT_DELAY_MS, MILLISECONDS);
+            }};
+
+        t.start();
+        t.join();
     }
 
     /**
      * If one exchanging thread is interrupted, another succeeds.
      */
-    public void testReplacementAfterExchange() {
+    public void testReplacementAfterExchange() throws InterruptedException {
         final Exchanger e = new Exchanger();
-        Thread t1 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Object v = e.exchange(one);
-                        threadAssertEquals(v, two);
-                        Object w = e.exchange(v);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Object v = e.exchange(two);
-                        threadAssertEquals(v, one);
-                        Thread.sleep(SMALL_DELAY_MS);
-                        Object w = e.exchange(v);
-                        threadAssertEquals(w, three);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t3 = new Thread(new Runnable(){
-                public void run(){
-                    try {
-                        Thread.sleep(SMALL_DELAY_MS);
-                        Object w = e.exchange(three);
-                        threadAssertEquals(w, one);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(two, e.exchange(one));
+                e.exchange(two);
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(one, e.exchange(two));
+                Thread.sleep(SMALL_DELAY_MS);
+                assertSame(three, e.exchange(one));
+            }});
+        Thread t3 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                assertSame(one, e.exchange(three));
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            t3.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t1.interrupt();
-            t1.join();
-            t2.join();
-            t3.join();
-        } catch(InterruptedException ex) {
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        t3.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t1.interrupt();
+        t1.join();
+        t2.join();
+        t3.join();
     }
 
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java
index b1988cc..dfa8f7d 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorCompletionServiceTest.java
@@ -2,23 +2,21 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.concurrent.atomic.*;
 import java.math.BigInteger;
 import java.security.*;
 
-public class ExecutorCompletionServiceTest extends JSR166TestCase{
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());  
-    }
+public class ExecutorCompletionServiceTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(ExecutorCompletionServiceTest.class);
     }
@@ -26,30 +24,28 @@
 
     /**
      * Creating a new ECS with null Executor throw NPE
-     */ 
+     */
     public void testConstructorNPE() {
         try {
             ExecutorCompletionService ecs = new ExecutorCompletionService(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Creating a new ECS with null queue throw NPE
-     */ 
+     */
     public void testConstructorNPE2() {
         try {
             ExecutorService e = Executors.newCachedThreadPool();
             ExecutorCompletionService ecs = new ExecutorCompletionService(e, null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Submitting a null callable throws NPE
-     */ 
+     */
     public void testSubmitNPE() {
         ExecutorService e = Executors.newCachedThreadPool();
         ExecutorCompletionService ecs = new ExecutorCompletionService(e);
@@ -65,7 +61,7 @@
 
     /**
      * Submitting a null runnable throws NPE
-     */ 
+     */
     public void testSubmitNPE2() {
         ExecutorService e = Executors.newCachedThreadPool();
         ExecutorCompletionService ecs = new ExecutorCompletionService(e);
@@ -81,8 +77,8 @@
 
     /**
      * A taken submitted task is completed
-     */ 
-    public void testTake() {
+     */
+    public void testTake() throws InterruptedException {
         ExecutorService e = Executors.newCachedThreadPool();
         ExecutorCompletionService ecs = new ExecutorCompletionService(e);
         try {
@@ -90,8 +86,6 @@
             ecs.submit(c);
             Future f = ecs.take();
             assertTrue(f.isDone());
-        } catch (Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -99,8 +93,8 @@
 
     /**
      * Take returns the same future object returned by submit
-     */ 
-    public void testTake2() {
+     */
+    public void testTake2() throws InterruptedException {
         ExecutorService e = Executors.newCachedThreadPool();
         ExecutorCompletionService ecs = new ExecutorCompletionService(e);
         try {
@@ -108,8 +102,6 @@
             Future f1 = ecs.submit(c);
             Future f2 = ecs.take();
             assertSame(f1, f2);
-        } catch (Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -117,8 +109,8 @@
 
     /**
      * If poll returns non-null, the returned task is completed
-     */ 
-    public void testPoll1() {
+     */
+    public void testPoll1() throws InterruptedException {
         ExecutorService e = Executors.newCachedThreadPool();
         ExecutorCompletionService ecs = new ExecutorCompletionService(e);
         try {
@@ -133,8 +125,6 @@
                     break;
                 }
             }
-        } catch (Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -142,21 +132,85 @@
 
     /**
      * If timed poll returns non-null, the returned task is completed
-     */ 
-    public void testPoll2() {
+     */
+    public void testPoll2() throws InterruptedException {
         ExecutorService e = Executors.newCachedThreadPool();
         ExecutorCompletionService ecs = new ExecutorCompletionService(e);
         try {
             assertNull(ecs.poll());
             Callable c = new StringTask();
             ecs.submit(c);
-            Future f = ecs.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            if (f != null) 
+            Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS);
+            if (f != null)
                 assertTrue(f.isDone());
-        } catch (Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
     }
+     /**
+      * Submitting to underlying AES that overrides newTaskFor(Callable)
+      * returns and eventually runs Future returned by newTaskFor.
+      */
+     public void testNewTaskForCallable() throws InterruptedException {
+         final AtomicBoolean done = new AtomicBoolean(false);
+         class MyCallableFuture<V> extends FutureTask<V> {
+             MyCallableFuture(Callable<V> c) { super(c); }
+             protected void done() { done.set(true); }
+         }
+         ExecutorService e = new ThreadPoolExecutor(
+                                 1, 1, 30L, TimeUnit.SECONDS,
+                                 new ArrayBlockingQueue<Runnable>(1)) {
+             protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) {
+                 return new MyCallableFuture<T>(c);
+             }
+         };
+         ExecutorCompletionService<String> ecs =
+             new ExecutorCompletionService<String>(e);
+         try {
+             assertNull(ecs.poll());
+             Callable<String> c = new StringTask();
+             Future f1 = ecs.submit(c);
+             assertTrue("submit must return MyCallableFuture",
+                        f1 instanceof MyCallableFuture);
+             Future f2 = ecs.take();
+             assertSame("submit and take must return same objects", f1, f2);
+             assertTrue("completed task must have set done", done.get());
+         } finally {
+             joinPool(e);
+         }
+     }
+
+     /**
+      * Submitting to underlying AES that overrides newTaskFor(Runnable,T)
+      * returns and eventually runs Future returned by newTaskFor.
+      */
+     public void testNewTaskForRunnable() throws InterruptedException {
+         final AtomicBoolean done = new AtomicBoolean(false);
+         class MyRunnableFuture<V> extends FutureTask<V> {
+             MyRunnableFuture(Runnable t, V r) { super(t, r); }
+             protected void done() { done.set(true); }
+         }
+         ExecutorService e = new ThreadPoolExecutor(
+                                 1, 1, 30L, TimeUnit.SECONDS,
+                                 new ArrayBlockingQueue<Runnable>(1)) {
+             protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) {
+                 return new MyRunnableFuture<T>(t, r);
+             }
+         };
+         ExecutorCompletionService<String> ecs =
+             new ExecutorCompletionService<String>(e);
+         try {
+             assertNull(ecs.poll());
+             Runnable r = new NoOpRunnable();
+             Future f1 = ecs.submit(r, null);
+             assertTrue("submit must return MyRunnableFuture",
+                        f1 instanceof MyRunnableFuture);
+             Future f2 = ecs.take();
+             assertSame("submit and take must return same objects", f1, f2);
+             assertTrue("completed task must have set done", done.get());
+         } finally {
+             joinPool(e);
+         }
+     }
+
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
index e8fc7e5..f29a712 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ExecutorsTest.java
@@ -2,66 +2,24 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.math.BigInteger;
 import java.security.*;
 
-public class ExecutorsTest extends JSR166TestCase{
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class ExecutorsTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(ExecutorsTest.class);
     }
 
-    static class TimedCallable<T> implements Callable<T> {
-        private final ExecutorService exec;
-        private final Callable<T> func;
-        private final long msecs;
-
-        TimedCallable(ExecutorService exec, Callable<T> func, long msecs) {
-            this.exec = exec;
-            this.func = func;
-            this.msecs = msecs;
-        }
-
-        public T call() throws Exception {
-            Future<T> ftask = exec.submit(func);
-            try {
-                return ftask.get(msecs, TimeUnit.MILLISECONDS);
-            } finally {
-                ftask.cancel(true);
-            }
-        }
-    }
-
-
-    private static class Fib implements Callable<BigInteger> {
-        private final BigInteger n;
-        Fib(long n) {
-            if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n);
-            this.n = BigInteger.valueOf(n);
-        }
-        public BigInteger call() {
-            BigInteger f1 = BigInteger.ONE;
-            BigInteger f2 = f1;
-            for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
-                BigInteger t = f1.add(f2);
-                f1 = f2;
-                f2 = t;
-            }
-            return f1;
-        }
-    };
-
     /**
      * A newCachedThreadPool can execute runnables
      */
@@ -91,9 +49,7 @@
         try {
             ExecutorService e = Executors.newCachedThreadPool(null);
             shouldThrow();
-        }
-        catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -126,9 +82,7 @@
         try {
             ExecutorService e = Executors.newSingleThreadExecutor(null);
             shouldThrow();
-        }
-        catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -138,6 +92,7 @@
         ExecutorService e = Executors.newSingleThreadExecutor();
         try {
             ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
+            shouldThrow();
         } catch (ClassCastException success) {
         } finally {
             joinPool(e);
@@ -174,9 +129,7 @@
         try {
             ExecutorService e = Executors.newFixedThreadPool(2, null);
             shouldThrow();
-        }
-        catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -186,9 +139,7 @@
         try {
             ExecutorService e = Executors.newFixedThreadPool(0);
             shouldThrow();
-        }
-        catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
 
@@ -209,9 +160,8 @@
     public void testunconfigurableExecutorServiceNPE() {
         try {
             ExecutorService e = Executors.unconfigurableExecutorService(null);
-        }
-        catch (NullPointerException success) {
-        }
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -220,109 +170,82 @@
     public void testunconfigurableScheduledExecutorServiceNPE() {
         try {
             ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
-        }
-        catch (NullPointerException success) {
-        }
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
 
     /**
      * a newSingleThreadScheduledExecutor successfully runs delayed task
      */
-    public void testNewSingleThreadScheduledExecutor() {
-        try {
-            TrackedCallable callable = new TrackedCallable();
-            ScheduledExecutorService p1 = Executors.newSingleThreadScheduledExecutor();
-            Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertFalse(callable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(callable.done);
-            assertEquals(Boolean.TRUE, f.get());
-            joinPool(p1);
-        } catch(RejectedExecutionException e){}
-        catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+    public void testNewSingleThreadScheduledExecutor() throws Exception {
+        TrackedCallable callable = new TrackedCallable();
+        ScheduledExecutorService p1 = Executors.newSingleThreadScheduledExecutor();
+        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(callable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(callable.done);
+        assertEquals(Boolean.TRUE, f.get());
+        joinPool(p1);
     }
 
     /**
      * a newScheduledThreadPool successfully runs delayed task
      */
-    public void testnewScheduledThreadPool() {
-        try {
-            TrackedCallable callable = new TrackedCallable();
-            ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2);
-            Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertFalse(callable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(callable.done);
-            assertEquals(Boolean.TRUE, f.get());
-            joinPool(p1);
-        } catch(RejectedExecutionException e){}
-        catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+    public void testnewScheduledThreadPool() throws Exception {
+        TrackedCallable callable = new TrackedCallable();
+        ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2);
+        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(callable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(callable.done);
+        assertEquals(Boolean.TRUE, f.get());
+        joinPool(p1);
     }
 
     /**
-     * an unconfigurable  newScheduledThreadPool successfully runs delayed task
+     * an unconfigurable newScheduledThreadPool successfully runs delayed task
      */
-    public void testunconfigurableScheduledExecutorService() {
-        try {
-            TrackedCallable callable = new TrackedCallable();
-            ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2));
-            Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertFalse(callable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(callable.done);
-            assertEquals(Boolean.TRUE, f.get());
-            joinPool(p1);
-        } catch(RejectedExecutionException e){}
-        catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+    public void testunconfigurableScheduledExecutorService() throws Exception {
+        TrackedCallable callable = new TrackedCallable();
+        ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2));
+        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(callable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(callable.done);
+        assertEquals(Boolean.TRUE, f.get());
+        joinPool(p1);
     }
 
     /**
-     *  timeouts from execute will time out if they compute too long.
+     *  Future.get on submitted tasks will time out if they compute too long.
      */
-    public void testTimedCallable() {
-        int N = 10000;
-        ExecutorService executor = Executors.newSingleThreadExecutor();
-        List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
-        try {
-            long startTime = System.currentTimeMillis();
-
-            long i = 0;
-            while (tasks.size() < N) {
-                tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
-                i += 10;
-            }
-
-            int iters = 0;
-            BigInteger sum = BigInteger.ZERO;
-            for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
+    public void testTimedCallable() throws Exception {
+        final Runnable sleeper =
+            new RunnableShouldThrow(InterruptedException.class) {
+                public void realRun() throws InterruptedException {
+                    Thread.sleep(LONG_DELAY_MS);
+                }};
+        for (ExecutorService executor :
+                 new ExecutorService[] {
+                     Executors.newSingleThreadExecutor(),
+                     Executors.newCachedThreadPool(),
+                     Executors.newFixedThreadPool(2),
+                     Executors.newScheduledThreadPool(2),
+                 }) {
+            try {
+                Future future = executor.submit(sleeper);
                 try {
-                    ++iters;
-                    sum = sum.add(it.next().call());
-                }
-                catch (TimeoutException success) {
-                    assertTrue(iters > 0);
-                    return;
-                }
-                catch (Exception e) {
-                    unexpectedException();
+                    future.get(SHORT_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (TimeoutException success) {
+                } finally {
+                    future.cancel(true);
                 }
             }
-            // if by chance we didn't ever time out, total time must be small
-            long elapsed = System.currentTimeMillis() - startTime;
-            assertTrue(elapsed < N);
-        }
-        finally {
-            joinPool(executor);
+            finally {
+                joinPool(executor);
+            }
         }
     }
 
@@ -331,25 +254,25 @@
      * ThreadPoolExecutor using defaultThreadFactory has
      * specified group, priority, daemon status, and name
      */
-    public void testDefaultThreadFactory() {
+    public void testDefaultThreadFactory() throws Exception {
         final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
         Runnable r = new Runnable() {
                 public void run() {
-		    try {
-			Thread current = Thread.currentThread();
-			threadAssertTrue(!current.isDaemon());
-			threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
-			ThreadGroup g = current.getThreadGroup();
-			SecurityManager s = System.getSecurityManager();
-			if (s != null)
-			    threadAssertTrue(g == s.getThreadGroup());
-			else
-			    threadAssertTrue(g == egroup);
-			String name = current.getName();
-			threadAssertTrue(name.endsWith("thread-1"));
-		    } catch (SecurityException ok) {
-			// Also pass if not allowed to change setting
-		    }
+                    try {
+                        Thread current = Thread.currentThread();
+                        threadAssertTrue(!current.isDaemon());
+                        threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+                        ThreadGroup g = current.getThreadGroup();
+                        SecurityManager s = System.getSecurityManager();
+                        if (s != null)
+                            threadAssertTrue(g == s.getThreadGroup());
+                        else
+                            threadAssertTrue(g == egroup);
+                        String name = current.getName();
+                        threadAssertTrue(name.endsWith("thread-1"));
+                    } catch (SecurityException ok) {
+                        // Also pass if not allowed to change setting
+                    }
                 }
             };
         ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
@@ -357,13 +280,11 @@
         e.execute(r);
         try {
             e.shutdown();
-        } catch(SecurityException ok) {
+        } catch (SecurityException ok) {
         }
 
         try {
             Thread.sleep(SHORT_DELAY_MS);
-        } catch (Exception eX) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -374,61 +295,60 @@
      * specified group, priority, daemon status, name,
      * access control context and context class loader
      */
-    public void testPrivilegedThreadFactory() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            policy.addPermission(new RuntimePermission("getContextClassLoader"));
-            policy.addPermission(new RuntimePermission("setContextClassLoader"));
-            Policy.setPolicy(policy);
-        } catch (AccessControlException ok) {
-            return;
-        }
-        final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
-        final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
-        final AccessControlContext thisacc = AccessController.getContext();
-        Runnable r = new Runnable() {
-                public void run() {
-		    try {
-			Thread current = Thread.currentThread();
-			threadAssertTrue(!current.isDaemon());
-			threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
-			ThreadGroup g = current.getThreadGroup();
-			SecurityManager s = System.getSecurityManager();
-			if (s != null)
-			    threadAssertTrue(g == s.getThreadGroup());
-			else
-			    threadAssertTrue(g == egroup);
-			String name = current.getName();
-			threadAssertTrue(name.endsWith("thread-1"));
-			threadAssertTrue(thisccl == current.getContextClassLoader());
-			threadAssertTrue(thisacc.equals(AccessController.getContext()));
-		    } catch(SecurityException ok) {
-			// Also pass if not allowed to change settings
-		    }
-                }
-            };
-        ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
+    public void testPrivilegedThreadFactory() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
+                final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
+                final AccessControlContext thisacc = AccessController.getContext();
+                Runnable r = new CheckedRunnable() {
+                    public void realRun() {
+                        Thread current = Thread.currentThread();
+                        assertTrue(!current.isDaemon());
+                        assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+                        ThreadGroup g = current.getThreadGroup();
+                        SecurityManager s = System.getSecurityManager();
+                        if (s != null)
+                            assertTrue(g == s.getThreadGroup());
+                        else
+                            assertTrue(g == egroup);
+                        String name = current.getName();
+                        assertTrue(name.endsWith("thread-1"));
+                        assertTrue(thisccl == current.getContextClassLoader());
+                        assertTrue(thisacc.equals(AccessController.getContext()));
+                    }};
+                ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
+                e.execute(r);
+                e.shutdown();
+                Thread.sleep(SHORT_DELAY_MS);
+                joinPool(e);
+            }};
 
-        Policy.setPolicy(savedPolicy);
-        e.execute(r);
-        try {
-            e.shutdown();
-        } catch(SecurityException ok) {
-        }
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-        } catch (Exception ex) {
-            unexpectedException();
-        } finally {
-            joinPool(e);
-        }
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"),
+                           new RuntimePermission("modifyThread"));
+    }
 
+    boolean haveCCLPermissions() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            try {
+                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+                sm.checkPermission(new RuntimePermission("getClassLoader"));
+            } catch (AccessControlException e) {
+                return false;
+            }
+        }
+        return true;
     }
 
     void checkCCL() {
-            AccessController.getContext().checkPermission(new RuntimePermission("getContextClassLoader"));
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+            sm.checkPermission(new RuntimePermission("getClassLoader"));
+        }
     }
 
     class CheckCCL implements Callable<Object> {
@@ -444,222 +364,192 @@
      * privilegedCallableUsingCurrentClassLoader throws ACE
      */
     public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            Policy.setPolicy(policy);
-        } catch (AccessControlException ok) {
-            return;
-        }
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                if (System.getSecurityManager() == null)
+                    return;
+                try {
+                    Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
+                    shouldThrow();
+                } catch (AccessControlException success) {}
+            }};
 
-        // Check if program still has too many permissions to run test
-        try {
-            checkCCL();
-            // too many privileges to test; so return
-            Policy.setPolicy(savedPolicy);
-            return;
-        } catch(AccessControlException ok) {
-        }
-
-        try {
-            Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
-            shouldThrow();
-        } catch(AccessControlException success) {
-        } catch(Exception ex) {
-            unexpectedException();
-        }
-        finally {
-            Policy.setPolicy(savedPolicy);
-        }
+        runWithoutPermissions(r);
     }
 
     /**
      * With class loader permissions, calling
      * privilegedCallableUsingCurrentClassLoader does not throw ACE
      */
-    public void testprivilegedCallableUsingCCLWithPrivs() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            policy.addPermission(new RuntimePermission("getContextClassLoader"));
-            policy.addPermission(new RuntimePermission("setContextClassLoader"));
-            Policy.setPolicy(policy);
-        } catch (AccessControlException ok) {
-            return;
-        }
+    public void testprivilegedCallableUsingCCLWithPrivs() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                Executors.privilegedCallableUsingCurrentClassLoader
+                    (new NoOpCallable())
+                    .call();
+            }};
 
-        try {
-            Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
-            task.call();
-        } catch(Exception ex) {
-            unexpectedException();
-        }
-        finally {
-            Policy.setPolicy(savedPolicy);
-        }
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"));
     }
 
     /**
      * Without permissions, calling privilegedCallable throws ACE
      */
-    public void testprivilegedCallableWithNoPrivs() {
-        Callable task;
-        Policy savedPolicy = null;
-        AdjustablePolicy policy = null;
-        AccessControlContext noprivAcc = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            policy = new AdjustablePolicy();
-            Policy.setPolicy(policy);
-            noprivAcc = AccessController.getContext();
-            task = Executors.privilegedCallable(new CheckCCL());
-            Policy.setPolicy(savedPolicy);
-        } catch (AccessControlException ok) {
-            return; // program has too few permissions to set up test
-        }
+    public void testprivilegedCallableWithNoPrivs() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                if (System.getSecurityManager() == null)
+                    return;
+                Callable task = Executors.privilegedCallable(new CheckCCL());
+                try {
+                    task.call();
+                    shouldThrow();
+                } catch (AccessControlException success) {}
+            }};
 
-        // Make sure that program doesn't have too many permissions
-        try {
-            AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
-                        checkCCL();
-                        return null;
-                    }}, noprivAcc);
-            // too many permssions; skip test
-            return;
-        } catch(AccessControlException ok) {
-        }
+        runWithoutPermissions(r);
 
-        try {
-            task.call();
-            shouldThrow();
-        } catch(AccessControlException success) {
-        } catch(Exception ex) {
-            unexpectedException();
-        }
+        // It seems rather difficult to test that the
+        // AccessControlContext of the privilegedCallable is used
+        // instead of its caller.  Below is a failed attempt to do
+        // that, which does not work because the AccessController
+        // cannot capture the internal state of the current Policy.
+        // It would be much more work to differentiate based on,
+        // e.g. CodeSource.
+
+//         final AccessControlContext[] noprivAcc = new AccessControlContext[1];
+//         final Callable[] task = new Callable[1];
+
+//         runWithPermissions
+//             (new CheckedRunnable() {
+//                 public void realRun() {
+//                     if (System.getSecurityManager() == null)
+//                         return;
+//                     noprivAcc[0] = AccessController.getContext();
+//                     task[0] = Executors.privilegedCallable(new CheckCCL());
+//                     try {
+//                         AccessController.doPrivileged(new PrivilegedAction<Void>() {
+//                                                           public Void run() {
+//                                                               checkCCL();
+//                                                               return null;
+//                                                           }}, noprivAcc[0]);
+//                         shouldThrow();
+//                     } catch (AccessControlException success) {}
+//                 }});
+
+//         runWithPermissions
+//             (new CheckedRunnable() {
+//                 public void realRun() throws Exception {
+//                     if (System.getSecurityManager() == null)
+//                         return;
+//                     // Verify that we have an underprivileged ACC
+//                     try {
+//                         AccessController.doPrivileged(new PrivilegedAction<Void>() {
+//                                                           public Void run() {
+//                                                               checkCCL();
+//                                                               return null;
+//                                                           }}, noprivAcc[0]);
+//                         shouldThrow();
+//                     } catch (AccessControlException success) {}
+
+//                     try {
+//                         task[0].call();
+//                         shouldThrow();
+//                     } catch (AccessControlException success) {}
+//                 }},
+//              new RuntimePermission("getClassLoader"),
+//              new RuntimePermission("setContextClassLoader"));
     }
 
     /**
      * With permissions, calling privilegedCallable succeeds
      */
-    public void testprivilegedCallableWithPrivs() {
-        Policy savedPolicy = null;
-        try {
-            savedPolicy = Policy.getPolicy();
-            AdjustablePolicy policy = new AdjustablePolicy();
-            policy.addPermission(new RuntimePermission("getContextClassLoader"));
-            policy.addPermission(new RuntimePermission("setContextClassLoader"));
-            Policy.setPolicy(policy);
-        } catch (AccessControlException ok) {
-            return;
-        }
-            
-        Callable task = Executors.privilegedCallable(new CheckCCL());
-        try {
-            task.call();
-        } catch(Exception ex) {
-            unexpectedException();
-        } finally {
-            Policy.setPolicy(savedPolicy);
-        }
+    public void testprivilegedCallableWithPrivs() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                Executors.privilegedCallable(new CheckCCL()).call();
+            }};
+
+         runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"));
     }
 
     /**
      * callable(Runnable) returns null when called
-     */ 
-    public void testCallable1() {
-        try {
-            Callable c = Executors.callable(new NoOpRunnable());
-            assertNull(c.call());
-        } catch(Exception ex) {
-            unexpectedException();
-        }
-        
+     */
+    public void testCallable1() throws Exception {
+        Callable c = Executors.callable(new NoOpRunnable());
+        assertNull(c.call());
     }
 
     /**
      * callable(Runnable, result) returns result when called
-     */ 
-    public void testCallable2() {
-        try {
-            Callable c = Executors.callable(new NoOpRunnable(), one);
-            assertEquals(one, c.call());
-        } catch(Exception ex) {
-            unexpectedException();
-        }
+     */
+    public void testCallable2() throws Exception {
+        Callable c = Executors.callable(new NoOpRunnable(), one);
+        assertSame(one, c.call());
     }
 
     /**
      * callable(PrivilegedAction) returns its result when called
-     */ 
-    public void testCallable3() {
-        try {
-            Callable c = Executors.callable(new PrivilegedAction() {
-                    public Object run() { return one; }});
-        assertEquals(one, c.call());
-        } catch(Exception ex) {
-            unexpectedException();
-        }
+     */
+    public void testCallable3() throws Exception {
+        Callable c = Executors.callable(new PrivilegedAction() {
+                public Object run() { return one; }});
+        assertSame(one, c.call());
     }
 
     /**
      * callable(PrivilegedExceptionAction) returns its result when called
-     */ 
-    public void testCallable4() {
-        try {
-            Callable c = Executors.callable(new PrivilegedExceptionAction() {
-                    public Object run() { return one; }});
-            assertEquals(one, c.call());
-        } catch(Exception ex) {
-            unexpectedException();
-        }
+     */
+    public void testCallable4() throws Exception {
+        Callable c = Executors.callable(new PrivilegedExceptionAction() {
+                public Object run() { return one; }});
+        assertSame(one, c.call());
     }
 
 
     /**
      * callable(null Runnable) throws NPE
-     */ 
+     */
     public void testCallableNPE1() {
         try {
-            Runnable r = null;
-            Callable c = Executors.callable(r);
-        } catch (NullPointerException success) {
-        }
+            Callable c = Executors.callable((Runnable) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
      * callable(null, result) throws NPE
-     */ 
+     */
     public void testCallableNPE2() {
         try {
-            Runnable r = null;
-            Callable c = Executors.callable(r, one);
-        } catch (NullPointerException success) {
-        }
+            Callable c = Executors.callable((Runnable) null, one);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
      * callable(null PrivilegedAction) throws NPE
-     */ 
+     */
     public void testCallableNPE3() {
         try {
-            PrivilegedAction r = null;
-            Callable c = Executors.callable(r);
-        } catch (NullPointerException success) {
-        }
+            Callable c = Executors.callable((PrivilegedAction) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
     /**
      * callable(null PrivilegedExceptionAction) throws NPE
-     */ 
+     */
     public void testCallableNPE4() {
         try {
-            PrivilegedExceptionAction r = null;
-            Callable c = Executors.callable(r);
-        } catch (NullPointerException success) {
-        }
+            Callable c = Executors.callable((PrivilegedExceptionAction) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
     }
 
 
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java
index 2108986..b1f9f40 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/FutureTaskTest.java
@@ -2,21 +2,18 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.*;
 
 public class FutureTaskTest extends JSR166TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(FutureTaskTest.class);
     }
@@ -38,9 +35,7 @@
         try {
             FutureTask task = new FutureTask(null);
             shouldThrow();
-        }
-        catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -50,16 +45,14 @@
         try {
             FutureTask task = new FutureTask(null, Boolean.TRUE);
             shouldThrow();
-        }
-        catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * isDone is true when a task completes
      */
     public void testIsDone() {
-        FutureTask task = new FutureTask( new NoOpCallable());
+        FutureTask task = new FutureTask(new NoOpCallable());
         task.run();
         assertTrue(task.isDone());
         assertFalse(task.isCancelled());
@@ -90,34 +83,24 @@
     /**
      * setting value causes get to return it
      */
-    public void testSet() {
+    public void testSet() throws Exception {
         PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
         task.set(one);
-        try {
-            assertEquals(task.get(), one);
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        assertSame(task.get(), one);
     }
 
     /**
      * setException causes get to throw ExecutionException
      */
-    public void testSetException() {
+    public void testSetException() throws Exception {
         Exception nse = new NoSuchElementException();
         PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
         task.setException(nse);
         try {
             Object x = task.get();
             shouldThrow();
-        }
-        catch(ExecutionException ee) {
-            Throwable cause = ee.getCause();
-            assertEquals(cause, nse);
-        }
-        catch(Exception e) {
-            unexpectedException();
+        } catch (ExecutionException success) {
+            assertSame(success.getCause(), nse);
         }
     }
 
@@ -125,7 +108,7 @@
      *  Cancelling before running succeeds
      */
     public void testCancelBeforeRun() {
-        FutureTask task = new FutureTask( new NoOpCallable());
+        FutureTask task = new FutureTask(new NoOpCallable());
         assertTrue(task.cancel(false));
         task.run();
         assertTrue(task.isDone());
@@ -136,7 +119,7 @@
      * Cancel(true) before run succeeds
      */
     public void testCancelBeforeRun2() {
-        FutureTask task = new FutureTask( new NoOpCallable());
+        FutureTask task = new FutureTask(new NoOpCallable());
         assertTrue(task.cancel(true));
         task.run();
         assertTrue(task.isDone());
@@ -147,7 +130,7 @@
      * cancel of a completed task fails
      */
     public void testCancelAfterRun() {
-        FutureTask task = new FutureTask( new NoOpCallable());
+        FutureTask task = new FutureTask(new NoOpCallable());
         task.run();
         assertFalse(task.cancel(false));
         assertTrue(task.isDone());
@@ -157,320 +140,219 @@
     /**
      * cancel(true) interrupts a running task
      */
-    public void testCancelInterrupt() {
-        FutureTask task = new FutureTask( new Callable() {
-                public Object call() {
-                    try {
-                        Thread.sleep(MEDIUM_DELAY_MS);
-                        threadShouldThrow();
-                    }
-                    catch (InterruptedException success) {}
+    public void testCancelInterrupt() throws InterruptedException {
+        final FutureTask task =
+            new FutureTask(new CheckedInterruptedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
+                    Thread.sleep(SMALL_DELAY_MS);
                     return Boolean.TRUE;
-                } });
-        Thread t = new  Thread(task);
+                }});
+
+        Thread t = new Thread(task);
         t.start();
-        
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(task.cancel(true));
-            t.join();
-            assertTrue(task.isDone());
-            assertTrue(task.isCancelled());
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(task.cancel(true));
+        t.join();
+        assertTrue(task.isDone());
+        assertTrue(task.isCancelled());
     }
 
 
     /**
      * cancel(false) does not interrupt a running task
      */
-    public void testCancelNoInterrupt() {
-        FutureTask task = new FutureTask( new Callable() {
-                public Object call() {
-                    try {
-                        Thread.sleep(MEDIUM_DELAY_MS);
-                    }
-                    catch (InterruptedException success) {
-                        threadFail("should not interrupt");
-                    }
+    public void testCancelNoInterrupt() throws InterruptedException {
+        final FutureTask task =
+            new FutureTask(new CheckedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
+                    Thread.sleep(MEDIUM_DELAY_MS);
                     return Boolean.TRUE;
-                } });
-        Thread t = new  Thread(task);
+                }});
+
+        Thread t = new Thread(task);
         t.start();
-        
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(task.cancel(false));
-            t.join();
-            assertTrue(task.isDone());
-            assertTrue(task.isCancelled());
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(task.cancel(false));
+        t.join();
+        assertTrue(task.isDone());
+        assertTrue(task.isCancelled());
     }
 
     /**
      * set in one thread causes get in another thread to retrieve value
      */
-    public void testGet1() {
-        final FutureTask ft = new FutureTask(new Callable() {
-                public Object call() {
-                    try {
-                        Thread.sleep(MEDIUM_DELAY_MS);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
+    public void testGet1() throws InterruptedException {
+        final FutureTask ft =
+            new FutureTask(new CheckedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
                     return Boolean.TRUE;
-                }
-        });
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        ft.get();
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            assertFalse(ft.isDone());
-            assertFalse(ft.isCancelled());
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            ft.run();
-            t.join();
-            assertTrue(ft.isDone());
-            assertFalse(ft.isCancelled());
-        } catch(InterruptedException e){
-            unexpectedException();
+                }});
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                assertSame(Boolean.TRUE, ft.get());
+            }});
 
-        }        
+        assertFalse(ft.isDone());
+        assertFalse(ft.isCancelled());
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        ft.run();
+        t.join();
+        assertTrue(ft.isDone());
+        assertFalse(ft.isCancelled());
     }
 
     /**
      * set in one thread causes timed get in another thread to retrieve value
      */
-    public void testTimedGet1() {
-        final FutureTask ft = new FutureTask(new Callable() {
-                public Object call() {
-                    try {
-                        Thread.sleep(MEDIUM_DELAY_MS);
-                    } catch(InterruptedException e){
-                        threadUnexpectedException();
-                    }
+    public void testTimedGet1() throws InterruptedException {
+        final FutureTask ft =
+            new FutureTask(new CheckedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
                     return Boolean.TRUE;
-                }
-            });
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        ft.get(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-                    } catch(TimeoutException success) {
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            assertFalse(ft.isDone());
-            assertFalse(ft.isCancelled());
-            t.start();
-            ft.run();
-            t.join();
-            assertTrue(ft.isDone());
-            assertFalse(ft.isCancelled());
-        } catch(InterruptedException e){
-            unexpectedException();
-            
-        }        
+                }});
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                assertSame(Boolean.TRUE, ft.get(SMALL_DELAY_MS, MILLISECONDS));
+            }});
+
+        assertFalse(ft.isDone());
+        assertFalse(ft.isCancelled());
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        ft.run();
+        t.join();
+        assertTrue(ft.isDone());
+        assertFalse(ft.isCancelled());
     }
 
     /**
      *  Cancelling a task causes timed get in another thread to throw CancellationException
      */
-    public void testTimedGet_Cancellation() {
-        final FutureTask ft = new FutureTask(new Callable() {
-                public Object call() {
-                    try {
-                        Thread.sleep(SMALL_DELAY_MS);
-                        threadShouldThrow();
-                    } catch(InterruptedException e) {
-                    }
+    public void testTimedGet_Cancellation() throws InterruptedException {
+        final FutureTask ft =
+            new FutureTask(new CheckedInterruptedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
+                    Thread.sleep(SMALL_DELAY_MS);
                     return Boolean.TRUE;
-                }
-            });
-        try {
-            Thread t1 = new Thread(new Runnable() {
-                    public void run() {
-                        try {
-                            ft.get(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                            threadShouldThrow();
-                        } catch(CancellationException success) {}
-                        catch(Exception e){
-                            threadUnexpectedException();
-                        }
-                    }
-                });
-            Thread t2 = new Thread(ft);
-            t1.start(); 
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            ft.cancel(true);
-            t1.join();
-            t2.join();
-        } catch(InterruptedException ie){
-            unexpectedException();
-        }
+                }});
+
+        Thread t1 = new ThreadShouldThrow(CancellationException.class) {
+            public void realRun() throws Exception {
+                ft.get(MEDIUM_DELAY_MS, MILLISECONDS);
+            }};
+        Thread t2 = new Thread(ft);
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        ft.cancel(true);
+        t1.join();
+        t2.join();
     }
 
     /**
      * Cancelling a task causes get in another thread to throw CancellationException
      */
-    public void testGet_Cancellation() {
-        final FutureTask ft = new FutureTask(new Callable() {
-                public Object call() {
-                    try {
-                        Thread.sleep(MEDIUM_DELAY_MS);
-                        threadShouldThrow();
-                    } catch(InterruptedException e){
-                    }
+    public void testGet_Cancellation() throws InterruptedException {
+        final FutureTask ft =
+            new FutureTask(new CheckedInterruptedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
+                    Thread.sleep(SMALL_DELAY_MS);
                     return Boolean.TRUE;
-                }
-            });
-        try {
-            Thread t1 = new Thread(new Runnable() {
-                    public void run() {
-                        try {
-                            ft.get();
-                            threadShouldThrow();
-                        } catch(CancellationException success){
-                        }
-                        catch(Exception e){
-                            threadUnexpectedException();
-                        }
-                    }
-                });
-            Thread t2 = new Thread(ft);
-            t1.start(); 
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            ft.cancel(true);
-            t1.join();
-            t2.join();
-        } catch(InterruptedException success){
-            unexpectedException();
-        }
+                }});
+        Thread t1 = new ThreadShouldThrow(CancellationException.class) {
+            public void realRun() throws Exception {
+                ft.get();
+            }};
+
+        Thread t2 = new Thread(ft);
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        ft.cancel(true);
+        t1.join();
+        t2.join();
     }
-    
+
 
     /**
      * A runtime exception in task causes get to throw ExecutionException
      */
-    public void testGet_ExecutionException() {
+    public void testGet_ExecutionException() throws InterruptedException {
         final FutureTask ft = new FutureTask(new Callable() {
-                public Object call() {
-                    int i = 5/0;
-                    return Boolean.TRUE;
-                }
-            });
+            public Object call() {
+                return 5/0;
+            }});
+
+        ft.run();
         try {
-            ft.run();
             ft.get();
             shouldThrow();
-        } catch(ExecutionException success){
-        }
-        catch(Exception e){
-            unexpectedException();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof ArithmeticException);
         }
     }
-  
+
     /**
      *  A runtime exception in task causes timed get to throw ExecutionException
      */
-    public void testTimedGet_ExecutionException2() {
+    public void testTimedGet_ExecutionException2() throws Exception {
         final FutureTask ft = new FutureTask(new Callable() {
-                public Object call() {
-                    int i = 5/0;
-                    return Boolean.TRUE;
-                }
-            });
+            public Object call() {
+                return 5/0;
+            }});
+
+        ft.run();
         try {
-            ft.run();
-            ft.get(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
+            ft.get(SHORT_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(ExecutionException success) { 
-        } catch(TimeoutException success) { } // unlikely but OK
-        catch(Exception e){
-            unexpectedException();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof ArithmeticException);
         }
     }
-      
+
 
     /**
      * Interrupting a waiting get causes it to throw InterruptedException
      */
-    public void testGet_InterruptedException() {
+    public void testGet_InterruptedException() throws InterruptedException {
         final FutureTask ft = new FutureTask(new NoOpCallable());
-        Thread t = new Thread(new Runnable() {
-                public void run() {                    
-                    try {
-                        ft.get();
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws Exception {
+                ft.get();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  Interrupting a waiting timed get causes it to throw InterruptedException
      */
-    public void testTimedGet_InterruptedException2() {
+    public void testTimedGet_InterruptedException2() throws InterruptedException {
         final FutureTask ft = new FutureTask(new NoOpCallable());
-        Thread t = new Thread(new Runnable() {
-                 public void run() {                    
-                    try {
-                        ft.get(LONG_DELAY_MS,TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                    catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws Exception {
+                ft.get(LONG_DELAY_MS,MILLISECONDS);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
-    
+
     /**
      * A timed out timed get throws TimeoutException
      */
-    public void testGet_TimeoutException() {
+    public void testGet_TimeoutException() throws Exception {
         try {
             FutureTask ft = new FutureTask(new NoOpCallable());
-            ft.get(1,TimeUnit.MILLISECONDS);
+            ft.get(1,MILLISECONDS);
             shouldThrow();
-        } catch(TimeoutException success){}
-        catch(Exception success){
-            unexpectedException();
-        }
+        } catch (TimeoutException success) {}
     }
-    
+
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java b/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
index 1c872f1..b764855 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/JSR166TestCase.java
@@ -6,11 +6,12 @@
  * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 import java.security.*;
 
@@ -88,71 +89,91 @@
  * </ul>
  */
 public class JSR166TestCase extends TestCase {
-    /**
-     * Runs all JSR166 unit tests using junit.textui.TestRunner
-     */
-    public static void main (String[] args) {
-        int iters = 1;
-        if (args.length > 0)
-            iters = Integer.parseInt(args[0]);
-        Test s = suite();
-        for (int i = 0; i < iters; ++i) {
-            junit.textui.TestRunner.run (s);
-            System.gc();
-            System.runFinalization();
-        }
-        System.exit(0);
-    }
+    private static final boolean useSecurityManager =
+        Boolean.getBoolean("jsr166.useSecurityManager");
+
+    // BEGIN android-removed
+    // /**
+    //  * Runs all JSR166 unit tests using junit.textui.TestRunner
+    //  */
+    // public static void main(String[] args) {
+    //     if (useSecurityManager) {
+    //         System.err.println("Setting a permissive security manager");
+    //         Policy.setPolicy(permissivePolicy());
+    //         System.setSecurityManager(new SecurityManager());
+    //     }
+    //     int iters = 1;
+    //     if (args.length > 0)
+    //         iters = Integer.parseInt(args[0]);
+    //     Test s = suite();
+    //     for (int i = 0; i < iters; ++i) {
+    //         junit.textui.TestRunner.run(s);
+    //         System.gc();
+    //         System.runFinalization();
+    //     }
+    //     System.exit(0);
+    // }
+    // END android-removed
 
     /**
      * Collects all JSR166 unit tests as one suite
      */
-    public static Test suite ( ) {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("JSR166 Unit Tests");
-        // BEGIN android-changed
-        suite.addTest(AbstractExecutorServiceTest.suite());
-        suite.addTest(AbstractQueueTest.suite());
-        suite.addTest(AbstractQueuedSynchronizerTest.suite());
-        suite.addTest(ArrayBlockingQueueTest.suite());
-        suite.addTest(AtomicBooleanTest.suite());
-        suite.addTest(AtomicIntegerArrayTest.suite());
-        suite.addTest(AtomicIntegerFieldUpdaterTest.suite());
-        suite.addTest(AtomicIntegerTest.suite());
-        suite.addTest(AtomicLongArrayTest.suite());
-        suite.addTest(AtomicLongFieldUpdaterTest.suite());
-        suite.addTest(AtomicLongTest.suite());
-        suite.addTest(AtomicMarkableReferenceTest.suite());
-        suite.addTest(AtomicReferenceArrayTest.suite());
-        suite.addTest(AtomicReferenceFieldUpdaterTest.suite());
-        suite.addTest(AtomicReferenceTest.suite());
-        suite.addTest(AtomicStampedReferenceTest.suite());
-        suite.addTest(ConcurrentHashMapTest.suite());
-        suite.addTest(ConcurrentLinkedQueueTest.suite());
-        suite.addTest(CopyOnWriteArrayListTest.suite());
-        suite.addTest(CopyOnWriteArraySetTest.suite());
-        suite.addTest(CountDownLatchTest.suite());
-        suite.addTest(CyclicBarrierTest.suite());
-        suite.addTest(DelayQueueTest.suite());
-        suite.addTest(ExchangerTest.suite());
-        suite.addTest(ExecutorsTest.suite());
-        suite.addTest(ExecutorCompletionServiceTest.suite());
-        suite.addTest(FutureTaskTest.suite());
-        suite.addTest(LinkedBlockingQueueTest.suite());
-        suite.addTest(LinkedListTest.suite());
-        suite.addTest(LockSupportTest.suite());
-        suite.addTest(PriorityBlockingQueueTest.suite());
-        suite.addTest(PriorityQueueTest.suite());
-        suite.addTest(ReentrantLockTest.suite());
-        suite.addTest(ReentrantReadWriteLockTest.suite());
-        suite.addTest(ScheduledExecutorTest.suite());
-        suite.addTest(SemaphoreTest.suite());
-        suite.addTest(SynchronousQueueTest.suite());
-        suite.addTest(SystemTest.suite());
-        suite.addTest(ThreadLocalTest.suite());
-        suite.addTest(ThreadPoolExecutorTest.suite());
-        suite.addTest(ThreadTest.suite());
-        suite.addTest(TimeUnitTest.suite());
-        // END android-changed
+    public static Test suite() {
+        TestSuite suite = new TestSuite("JSR166 Unit Tests");
+
+        suite.addTest(new TestSuite(AbstractExecutorServiceTest.class));
+        suite.addTest(new TestSuite(AbstractQueueTest.class));
+        suite.addTest(new TestSuite(AbstractQueuedSynchronizerTest.class));
+        suite.addTest(new TestSuite(AbstractQueuedLongSynchronizerTest.class));
+        suite.addTest(new TestSuite(ArrayBlockingQueueTest.class));
+        suite.addTest(new TestSuite(ArrayDequeTest.class));
+        suite.addTest(new TestSuite(AtomicBooleanTest.class));
+        suite.addTest(new TestSuite(AtomicIntegerArrayTest.class));
+        suite.addTest(new TestSuite(AtomicIntegerFieldUpdaterTest.class));
+        suite.addTest(new TestSuite(AtomicIntegerTest.class));
+        suite.addTest(new TestSuite(AtomicLongArrayTest.class));
+        suite.addTest(new TestSuite(AtomicLongFieldUpdaterTest.class));
+        suite.addTest(new TestSuite(AtomicLongTest.class));
+        suite.addTest(new TestSuite(AtomicMarkableReferenceTest.class));
+        suite.addTest(new TestSuite(AtomicReferenceArrayTest.class));
+        suite.addTest(new TestSuite(AtomicReferenceFieldUpdaterTest.class));
+        suite.addTest(new TestSuite(AtomicReferenceTest.class));
+        suite.addTest(new TestSuite(AtomicStampedReferenceTest.class));
+        suite.addTest(new TestSuite(ConcurrentHashMapTest.class));
+        suite.addTest(new TestSuite(ConcurrentLinkedQueueTest.class));
+        suite.addTest(new TestSuite(ConcurrentSkipListMapTest.class));
+        suite.addTest(new TestSuite(ConcurrentSkipListSubMapTest.class));
+        suite.addTest(new TestSuite(ConcurrentSkipListSetTest.class));
+        suite.addTest(new TestSuite(ConcurrentSkipListSubSetTest.class));
+        suite.addTest(new TestSuite(CopyOnWriteArrayListTest.class));
+        suite.addTest(new TestSuite(CopyOnWriteArraySetTest.class));
+        suite.addTest(new TestSuite(CountDownLatchTest.class));
+        suite.addTest(new TestSuite(CyclicBarrierTest.class));
+        suite.addTest(new TestSuite(DelayQueueTest.class));
+        suite.addTest(new TestSuite(EntryTest.class));
+        suite.addTest(new TestSuite(ExchangerTest.class));
+        suite.addTest(new TestSuite(ExecutorsTest.class));
+        suite.addTest(new TestSuite(ExecutorCompletionServiceTest.class));
+        suite.addTest(new TestSuite(FutureTaskTest.class));
+        suite.addTest(new TestSuite(LinkedBlockingDequeTest.class));
+        suite.addTest(new TestSuite(LinkedBlockingQueueTest.class));
+        suite.addTest(new TestSuite(LinkedListTest.class));
+        suite.addTest(new TestSuite(LockSupportTest.class));
+        suite.addTest(new TestSuite(PriorityBlockingQueueTest.class));
+        suite.addTest(new TestSuite(PriorityQueueTest.class));
+        suite.addTest(new TestSuite(ReentrantLockTest.class));
+        suite.addTest(new TestSuite(ReentrantReadWriteLockTest.class));
+        suite.addTest(new TestSuite(ScheduledExecutorTest.class));
+        suite.addTest(new TestSuite(ScheduledExecutorSubclassTest.class));
+        suite.addTest(new TestSuite(SemaphoreTest.class));
+        suite.addTest(new TestSuite(SynchronousQueueTest.class));
+        suite.addTest(new TestSuite(SystemTest.class));
+        suite.addTest(new TestSuite(ThreadLocalTest.class));
+        suite.addTest(new TestSuite(ThreadPoolExecutorTest.class));
+        suite.addTest(new TestSuite(ThreadPoolExecutorSubclassTest.class));
+        suite.addTest(new TestSuite(ThreadTest.class));
+        suite.addTest(new TestSuite(TimeUnitTest.class));
+
         return suite;
     }
 
@@ -178,7 +199,7 @@
     /**
      * Sets delays as multiples of SHORT_DELAY.
      */
-    protected  void setDelays() {
+    protected void setDelays() {
         SHORT_DELAY_MS = getShortDelay();
         SMALL_DELAY_MS = SHORT_DELAY_MS * 5;
         MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
@@ -272,13 +293,16 @@
      * threadFail with message "should throw exception"
      */
     public void threadShouldThrow() {
-       try {
-           threadFailed = true;
-           fail("should throw exception");
-       } catch (AssertionFailedError e) {
-           e.printStackTrace();
-           throw e;
-       }
+        threadFailed = true;
+        fail("should throw exception");
+    }
+
+    /**
+     * threadFail with message "should throw" + exceptionName
+     */
+    public void threadShouldThrow(String exceptionName) {
+        threadFailed = true;
+        fail("should throw " + exceptionName);
     }
 
     /**
@@ -304,11 +328,11 @@
     public void joinPool(ExecutorService exec) {
         try {
             exec.shutdown();
-            assertTrue(exec.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch(SecurityException ok) {
+            assertTrue(exec.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        } catch (SecurityException ok) {
             // Allowed in case test doesn't have privs
-        } catch(InterruptedException ie) {
-            fail("Unexpected exception");
+        } catch (InterruptedException ie) {
+            fail("Unexpected InterruptedException");
         }
     }
 
@@ -321,46 +345,105 @@
     }
 
     /**
+     * fail with message "should throw " + exceptionName
+     */
+    public void shouldThrow(String exceptionName) {
+        fail("Should throw " + exceptionName);
+    }
+
+    /**
      * fail with message "Unexpected exception"
      */
     public void unexpectedException() {
         fail("Unexpected exception");
     }
 
+    /**
+     * fail with message "Unexpected exception", with argument
+     */
+    public void unexpectedException(Throwable ex) {
+        ex.printStackTrace();
+        fail("Unexpected exception: " + ex);
+    }
+
 
     /**
      * The number of elements to place in collections, arrays, etc.
      */
-    static final int SIZE = 20;
+    public static final int SIZE = 20;
 
     // Some convenient Integer constants
 
-    static final Integer zero = new Integer(0);
-    static final Integer one = new Integer(1);
-    static final Integer two = new Integer(2);
-    static final Integer three  = new Integer(3);
-    static final Integer four  = new Integer(4);
-    static final Integer five  = new Integer(5);
-    static final Integer six = new Integer(6);
-    static final Integer seven = new Integer(7);
-    static final Integer eight = new Integer(8);
-    static final Integer nine = new Integer(9);
-    static final Integer m1  = new Integer(-1);
-    static final Integer m2  = new Integer(-2);
-    static final Integer m3  = new Integer(-3);
-    static final Integer m4 = new Integer(-4);
-    static final Integer m5 = new Integer(-5);
-    static final Integer m6 = new Integer(-6);
-    static final Integer m10 = new Integer(-10);
+    public static final Integer zero  = new Integer(0);
+    public static final Integer one   = new Integer(1);
+    public static final Integer two   = new Integer(2);
+    public static final Integer three = new Integer(3);
+    public static final Integer four  = new Integer(4);
+    public static final Integer five  = new Integer(5);
+    public static final Integer six   = new Integer(6);
+    public static final Integer seven = new Integer(7);
+    public static final Integer eight = new Integer(8);
+    public static final Integer nine  = new Integer(9);
+    public static final Integer m1  = new Integer(-1);
+    public static final Integer m2  = new Integer(-2);
+    public static final Integer m3  = new Integer(-3);
+    public static final Integer m4  = new Integer(-4);
+    public static final Integer m5  = new Integer(-5);
+    public static final Integer m6  = new Integer(-6);
+    public static final Integer m10 = new Integer(-10);
 
 
     /**
+     * Runs Runnable r with a security policy that permits precisely
+     * the specified permissions.  If there is no current security
+     * manager, the runnable is run twice, both with and without a
+     * security manager.  We require that any security manager permit
+     * getPolicy/setPolicy.
+     */
+    public void runWithPermissions(Runnable r, Permission... permissions) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            r.run();
+            Policy savedPolicy = Policy.getPolicy();
+            try {
+                Policy.setPolicy(permissivePolicy());
+                System.setSecurityManager(new SecurityManager());
+                runWithPermissions(r, permissions);
+            } finally {
+                System.setSecurityManager(null);
+                Policy.setPolicy(savedPolicy);
+            }
+        } else {
+            Policy savedPolicy = Policy.getPolicy();
+            AdjustablePolicy policy = new AdjustablePolicy(permissions);
+            Policy.setPolicy(policy);
+
+            try {
+                r.run();
+            } finally {
+                policy.addPermission(new SecurityPermission("setPolicy"));
+                Policy.setPolicy(savedPolicy);
+            }
+        }
+    }
+
+    /**
+     * Runs a runnable without any permissions.
+     */
+    public void runWithoutPermissions(Runnable r) {
+        runWithPermissions(r);
+    }
+
+    /**
      * A security policy where new permissions can be dynamically added
      * or all cleared.
      */
-    static class AdjustablePolicy extends java.security.Policy {
+    public static class AdjustablePolicy extends java.security.Policy {
         Permissions perms = new Permissions();
-        AdjustablePolicy() { }
+        AdjustablePolicy(Permission... permissions) {
+            for (Permission permission : permissions)
+                perms.add(permission);
+        }
         void addPermission(Permission perm) { perms.add(perm); }
         void clearPermissions() { perms = new Permissions(); }
         public PermissionCollection getPermissions(CodeSource cs) {
@@ -375,197 +458,293 @@
         public void refresh() {}
     }
 
+    /**
+     * Returns a policy containing all the permissions we ever need.
+     */
+    public static Policy permissivePolicy() {
+        return new AdjustablePolicy
+            // Permissions j.u.c. needs directly
+            (new RuntimePermission("modifyThread"),
+             new RuntimePermission("getClassLoader"),
+             new RuntimePermission("setContextClassLoader"),
+             // Permissions needed to change permissions!
+             new SecurityPermission("getPolicy"),
+             new SecurityPermission("setPolicy"),
+             new RuntimePermission("setSecurityManager"),
+             // Permissions needed by the junit test harness
+             new RuntimePermission("accessDeclaredMembers"),
+             new PropertyPermission("*", "read"),
+             new java.io.FilePermission("<<ALL FILES>>", "read"));
+    }
+
+    /**
+     * Sleep until the timeout has elapsed, or interrupted.
+     * Does <em>NOT</em> throw InterruptedException.
+     */
+    void sleepTillInterrupted(long timeoutMillis) {
+        try {
+            Thread.sleep(timeoutMillis);
+        } catch (InterruptedException wakeup) {}
+    }
+
+    /**
+     * Returns a new started Thread running the given runnable.
+     */
+    Thread newStartedThread(Runnable runnable) {
+        Thread t = new Thread(runnable);
+        t.start();
+        return t;
+    }
 
     // Some convenient Runnable classes
 
-    static class NoOpRunnable implements Runnable {
+    public abstract class CheckedRunnable implements Runnable {
+        protected abstract void realRun() throws Throwable;
+
+        public final void run() {
+            try {
+                realRun();
+            } catch (Throwable t) {
+                threadUnexpectedException(t);
+            }
+        }
+    }
+
+    public abstract class RunnableShouldThrow implements Runnable {
+        protected abstract void realRun() throws Throwable;
+
+        final Class<?> exceptionClass;
+
+        <T extends Throwable> RunnableShouldThrow(Class<T> exceptionClass) {
+            this.exceptionClass = exceptionClass;
+        }
+
+        public final void run() {
+            try {
+                realRun();
+                threadShouldThrow(exceptionClass.getSimpleName());
+            } catch (Throwable t) {
+                if (! exceptionClass.isInstance(t))
+                    threadUnexpectedException(t);
+            }
+        }
+    }
+
+    public abstract class ThreadShouldThrow extends Thread {
+        protected abstract void realRun() throws Throwable;
+
+        final Class<?> exceptionClass;
+
+        <T extends Throwable> ThreadShouldThrow(Class<T> exceptionClass) {
+            this.exceptionClass = exceptionClass;
+        }
+
+        public final void run() {
+            try {
+                realRun();
+                threadShouldThrow(exceptionClass.getSimpleName());
+            } catch (Throwable t) {
+                if (! exceptionClass.isInstance(t))
+                    threadUnexpectedException(t);
+            }
+        }
+    }
+
+    public abstract class CheckedInterruptedRunnable implements Runnable {
+        protected abstract void realRun() throws Throwable;
+
+        public final void run() {
+            try {
+                realRun();
+                threadShouldThrow("InterruptedException");
+            } catch (InterruptedException success) {
+            } catch (Throwable t) {
+                threadUnexpectedException(t);
+            }
+        }
+    }
+
+    public abstract class CheckedCallable<T> implements Callable<T> {
+        protected abstract T realCall() throws Throwable;
+
+        public final T call() {
+            try {
+                return realCall();
+            } catch (Throwable t) {
+                threadUnexpectedException(t);
+            }
+            return null;
+        }
+    }
+
+    public abstract class CheckedInterruptedCallable<T> implements Callable<T> {
+        protected abstract T realCall() throws Throwable;
+
+        public final T call() {
+            try {
+                T result = realCall();
+                threadShouldThrow("InterruptedException");
+                return result;
+            } catch (InterruptedException success) {
+            } catch (Throwable t) {
+                threadUnexpectedException(t);
+            }
+            return null;
+        }
+    }
+
+    public static class NoOpRunnable implements Runnable {
         public void run() {}
     }
 
-    static class NoOpCallable implements Callable {
+    public static class NoOpCallable implements Callable {
         public Object call() { return Boolean.TRUE; }
     }
 
-    static final String TEST_STRING = "a test string";
+    public static final String TEST_STRING = "a test string";
 
-    static class StringTask implements Callable<String> {
+    public static class StringTask implements Callable<String> {
         public String call() { return TEST_STRING; }
     }
 
-    static class NPETask implements Callable<String> {
+    public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) {
+        return new CheckedCallable<String>() {
+            public String realCall() {
+                try {
+                    latch.await();
+                } catch (InterruptedException quittingTime) {}
+                return TEST_STRING;
+            }};
+    }
+
+    public static class NPETask implements Callable<String> {
         public String call() { throw new NullPointerException(); }
     }
 
-    static class CallableOne implements Callable<Integer> {
+    public static class CallableOne implements Callable<Integer> {
         public Integer call() { return one; }
     }
 
-    class ShortRunnable implements Runnable {
-        public void run() {
-            try {
-                Thread.sleep(SHORT_DELAY_MS);
-            }
-            catch(Exception e) {
-                threadUnexpectedException(e);
-            }
+    public class ShortRunnable extends CheckedRunnable {
+        protected void realRun() throws Throwable {
+            Thread.sleep(SHORT_DELAY_MS);
         }
     }
 
-    class ShortInterruptedRunnable implements Runnable {
-        public void run() {
-            try {
-                Thread.sleep(SHORT_DELAY_MS);
-                threadShouldThrow();
-            }
-            catch(InterruptedException success) {
-            }
+    public class ShortInterruptedRunnable extends CheckedInterruptedRunnable {
+        protected void realRun() throws InterruptedException {
+            Thread.sleep(SHORT_DELAY_MS);
         }
     }
 
-    class SmallRunnable implements Runnable {
-        public void run() {
+    public class SmallRunnable extends CheckedRunnable {
+        protected void realRun() throws Throwable {
+            Thread.sleep(SMALL_DELAY_MS);
+        }
+    }
+
+    public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
+        protected void realRun() {
             try {
                 Thread.sleep(SMALL_DELAY_MS);
-            }
-            catch(Exception e) {
-                threadUnexpectedException(e);
-            }
+            } catch (InterruptedException ok) {}
         }
     }
 
-    class SmallPossiblyInterruptedRunnable implements Runnable {
-        public void run() {
-            try {
-                Thread.sleep(SMALL_DELAY_MS);
-            }
-            catch(Exception e) {
-            }
-        }
-    }
-
-    class SmallCallable implements Callable {
-        public Object call() {
-            try {
-                Thread.sleep(SMALL_DELAY_MS);
-            }
-            catch(Exception e) {
-                threadUnexpectedException(e);
-            }
+    public class SmallCallable extends CheckedCallable {
+        protected Object realCall() throws InterruptedException {
+            Thread.sleep(SMALL_DELAY_MS);
             return Boolean.TRUE;
         }
     }
 
-    class SmallInterruptedRunnable implements Runnable {
-        public void run() {
-            try {
-                Thread.sleep(SMALL_DELAY_MS);
-                threadShouldThrow();
-            }
-            catch(InterruptedException success) {
-            }
+    public class SmallInterruptedRunnable extends CheckedInterruptedRunnable {
+        protected void realRun() throws InterruptedException {
+            Thread.sleep(SMALL_DELAY_MS);
         }
     }
 
+    public class MediumRunnable extends CheckedRunnable {
+        protected void realRun() throws Throwable {
+            Thread.sleep(MEDIUM_DELAY_MS);
+        }
+    }
 
-    class MediumRunnable implements Runnable {
-        public void run() {
+    public class MediumInterruptedRunnable extends CheckedInterruptedRunnable {
+        protected void realRun() throws InterruptedException {
+            Thread.sleep(MEDIUM_DELAY_MS);
+        }
+    }
+
+    public class MediumPossiblyInterruptedRunnable extends CheckedRunnable {
+        protected void realRun() {
             try {
                 Thread.sleep(MEDIUM_DELAY_MS);
-            }
-            catch(Exception e) {
-                threadUnexpectedException(e);
-            }
+            } catch (InterruptedException ok) {}
         }
     }
 
-    class MediumInterruptedRunnable implements Runnable {
-        public void run() {
-            try {
-                Thread.sleep(MEDIUM_DELAY_MS);
-                threadShouldThrow();
-            }
-            catch(InterruptedException success) {
-            }
-        }
-    }
-
-    class MediumPossiblyInterruptedRunnable implements Runnable {
-        public void run() {
-            try {
-                Thread.sleep(MEDIUM_DELAY_MS);
-            }
-            catch(InterruptedException success) {
-            }
-        }
-    }
-
-    class LongPossiblyInterruptedRunnable implements Runnable {
-        public void run() {
+    public class LongPossiblyInterruptedRunnable extends CheckedRunnable {
+        protected void realRun() {
             try {
                 Thread.sleep(LONG_DELAY_MS);
-            }
-            catch(InterruptedException success) {
-            }
+            } catch (InterruptedException ok) {}
         }
     }
 
     /**
      * For use as ThreadFactory in constructors
      */
-    static class SimpleThreadFactory implements ThreadFactory{
-        public Thread newThread(Runnable r){
+    public static class SimpleThreadFactory implements ThreadFactory {
+        public Thread newThread(Runnable r) {
             return new Thread(r);
         }
     }
 
-    static class TrackedShortRunnable implements Runnable {
-        volatile boolean done = false;
+    public static class TrackedShortRunnable implements Runnable {
+        public volatile boolean done = false;
         public void run() {
             try {
                 Thread.sleep(SMALL_DELAY_MS);
                 done = true;
-            } catch(Exception e){
-            }
+            } catch (InterruptedException ok) {}
         }
     }
 
-    static class TrackedMediumRunnable implements Runnable {
-        volatile boolean done = false;
+    public static class TrackedMediumRunnable implements Runnable {
+        public volatile boolean done = false;
         public void run() {
             try {
                 Thread.sleep(MEDIUM_DELAY_MS);
                 done = true;
-            } catch(Exception e){
-            }
+            } catch (InterruptedException ok) {}
         }
     }
 
-    static class TrackedLongRunnable implements Runnable {
-        volatile boolean done = false;
+    public static class TrackedLongRunnable implements Runnable {
+        public volatile boolean done = false;
         public void run() {
             try {
                 Thread.sleep(LONG_DELAY_MS);
                 done = true;
-            } catch(Exception e){
-            }
+            } catch (InterruptedException ok) {}
         }
     }
 
-    static class TrackedNoOpRunnable implements Runnable {
-        volatile boolean done = false;
+    public static class TrackedNoOpRunnable implements Runnable {
+        public volatile boolean done = false;
         public void run() {
             done = true;
         }
     }
 
-    static class TrackedCallable implements Callable {
-        volatile boolean done = false;
+    public static class TrackedCallable implements Callable {
+        public volatile boolean done = false;
         public Object call() {
             try {
                 Thread.sleep(SMALL_DELAY_MS);
                 done = true;
-            } catch(Exception e){
-            }
+            } catch (InterruptedException ok) {}
             return Boolean.TRUE;
         }
     }
@@ -574,9 +753,9 @@
     /**
      * For use as RejectedExecutionHandler in constructors
      */
-    static class NoOpREHandler implements RejectedExecutionHandler{
-        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor){}
+    public static class NoOpREHandler implements RejectedExecutionHandler {
+        public void rejectedExecution(Runnable r,
+                                      ThreadPoolExecutor executor) {}
     }
 
-
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingDequeTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingDequeTest.java
new file mode 100644
index 0000000..a858bb9
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingDequeTest.java
@@ -0,0 +1,1671 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.io.*;
+
+public class LinkedBlockingDequeTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(LinkedBlockingDequeTest.class);
+    }
+
+    /**
+     * Create a deque of given size containing consecutive
+     * Integers 0 ... n.
+     */
+    private LinkedBlockingDeque populatedDeque(int n) {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(n);
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; i++)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(n, q.size());
+        return q;
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.removeFirst();
+        q.removeFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i, q.size());
+            q.removeFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferFirstNull() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque();
+            q.offerFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * OfferFirst succeeds
+     */
+    public void testOfferFirst() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        assertTrue(q.offerFirst(new Integer(0)));
+        assertTrue(q.offerFirst(new Integer(1)));
+    }
+
+    /**
+     * OfferLast succeeds
+     */
+    public void testOfferLast() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        assertTrue(q.offerLast(new Integer(0)));
+        assertTrue(q.offerLast(new Integer(1)));
+    }
+
+    /**
+     *  pollFirst succeeds unless empty
+     */
+    public void testPollFirst() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     *  pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollLast());
+    }
+
+    /**
+     *  peekFirst returns next element, or null if empty
+     */
+    public void testPeekFirst() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peekFirst());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peekFirst() == null ||
+                       !q.peekFirst().equals(i));
+        }
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     *  peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     *  peekLast returns next element, or null if empty
+     */
+    public void testPeekLast() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.peekLast());
+            assertEquals(i, q.pollLast());
+            assertTrue(q.peekLast() == null ||
+                       !q.peekLast().equals(i));
+        }
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * getFirst returns next getFirst, or throws NSEE if empty
+     */
+    public void testFirstElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.getFirst());
+            assertEquals(i, q.pollFirst());
+        }
+        try {
+            q.getFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     *  getLast returns next element, or throws NSEE if empty
+     */
+    public void testLastElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE-1; i >= 0; --i) {
+            assertEquals(i, q.getLast());
+            assertEquals(i, q.pollLast());
+        }
+        try {
+            q.getLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     *  removeFirst removes next element, or throws NSEE if empty
+     */
+    public void testRemoveFirst() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.removeFirst());
+        }
+        try {
+            q.removeFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     *  removeLast removes last element, or throws NSEE if empty
+     */
+    public void testRemoveLast() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.removeLast());
+        }
+        try {
+            q.removeLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     *  remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * removeFirstOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveFirstOccurrence() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * removeLastOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveLastOccurrence() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+            assertFalse(q.removeLastOccurrence(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * peekFirst returns element inserted with addFirst
+     */
+    public void testAddFirst() {
+        LinkedBlockingDeque q = populatedDeque(3);
+        q.pollLast();
+        q.addFirst(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * peekLast returns element inserted with addLast
+     */
+    public void testAddLast() {
+        LinkedBlockingDeque q = populatedDeque(3);
+        q.pollLast();
+        q.addLast(four);
+        assertSame(four, q.peekLast());
+    }
+
+
+    /**
+     * A new deque has the indicated capacity, or Integer.MAX_VALUE if
+     * none given
+     */
+    public void testConstructor1() {
+        assertEquals(SIZE, new LinkedBlockingDeque(SIZE).remainingCapacity());
+        assertEquals(Integer.MAX_VALUE, new LinkedBlockingDeque().remainingCapacity());
+    }
+
+    /**
+     * Constructor throws IAE if capacity argument nonpositive
+     */
+    public void testConstructor2() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            Integer[] ints = new Integer[SIZE];
+            LinkedBlockingDeque q = new LinkedBlockingDeque(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        try {
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE-1; ++i)
+                ints[i] = new Integer(i);
+            LinkedBlockingDeque q = new LinkedBlockingDeque(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Deque contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingDeque q = new LinkedBlockingDeque(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * Deque transitions from empty to full when elements added
+     */
+    public void testEmptyFull() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        assertTrue(q.isEmpty());
+        assertEquals("should have room for 2", 2, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.add(two);
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertFalse(q.offer(three));
+    }
+
+    /**
+     * remainingCapacity decreases on add, increases on remove
+     */
+    public void testRemainingCapacity() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remainingCapacity());
+            assertEquals(SIZE-i, q.size());
+            q.remove();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i, q.remainingCapacity());
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferNull() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+            q.offer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * push(null) throws NPE
+     */
+    public void testPushNull() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+            q.push(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * push succeeds if not full; throws ISE if full
+     */
+    public void testPush() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            for (int i = 0; i < SIZE; ++i) {
+                Integer I = new Integer(i);
+                q.push(I);
+                assertEquals(I, q.peek());
+            }
+            assertEquals(0, q.remainingCapacity());
+            q.push(new Integer(SIZE));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * peekFirst returns element inserted with push
+     */
+    public void testPushWithPeek() {
+        LinkedBlockingDeque q = populatedDeque(3);
+        q.pollLast();
+        q.push(four);
+        assertSame(four, q.peekFirst());
+    }
+
+
+    /**
+     *  pop removes next element, or throws NSEE if empty
+     */
+    public void testPop() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pop());
+        }
+        try {
+            q.pop();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+
+    /**
+     * Offer succeeds if not full; fails if full
+     */
+    public void testOffer() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+        assertTrue(q.offer(zero));
+        assertFalse(q.offer(one));
+    }
+
+    /**
+     * add succeeds if not full; throws ISE if full
+     */
+    public void testAdd() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            for (int i = 0; i < SIZE; ++i) {
+                assertTrue(q.add(new Integer(i)));
+            }
+            assertEquals(0, q.remainingCapacity());
+            q.add(new Integer(SIZE));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        try {
+            LinkedBlockingDeque q = populatedDeque(SIZE);
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            Integer[] ints = new Integer[SIZE];
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE-1; ++i)
+                ints[i] = new Integer(i);
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+    /**
+     * addAll throws ISE if not enough room
+     */
+    public void testAddAll4() {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+            Integer[] ints = new Integer[SIZE];
+            for (int i = 0; i < SIZE; ++i)
+                ints[i] = new Integer(i);
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * Deque contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+
+    /**
+     * put(null) throws NPE
+     */
+    public void testPutNull() throws InterruptedException {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            q.put(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() throws InterruptedException {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer I = new Integer(i);
+            q.put(I);
+            assertTrue(q.contains(I));
+        }
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly if full
+     */
+    public void testBlockingPut() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.put(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks waiting for take when full
+     */
+    public void testPutWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity + 1; i++)
+                    q.put(i);
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(q.remainingCapacity(), 0);
+        assertEquals(0, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(q.remainingCapacity(), 0);
+    }
+
+    /**
+     * timed offer times out if full and elements not taken
+     */
+    public void testTimedOffer() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Object());
+                q.put(new Object());
+                assertFalse(q.offer(new Object(), SHORT_DELAY_MS, MILLISECONDS));
+                try {
+                    q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTake() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
+    }
+
+    /**
+     * take blocks interruptibly when empty
+     */
+    public void testTakeFromEmpty() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }};
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * Take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
+        }
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                LinkedBlockingDeque q = populatedDeque(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                }
+                try {
+                    q.poll(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     *  timed poll before a delayed offer fails; after offer succeeds;
+     *  on interruption throws
+     */
+    public void testTimedPollWithOffer() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
+
+
+    /**
+     * putFirst(null) throws NPE
+     */
+     public void testPutFirstNull() throws InterruptedException {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            q.putFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+     }
+
+    /**
+     * all elements successfully putFirst are contained
+     */
+     public void testPutFirst() throws InterruptedException {
+         LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+         for (int i = 0; i < SIZE; ++i) {
+             Integer I = new Integer(i);
+             q.putFirst(I);
+             assertTrue(q.contains(I));
+         }
+         assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putFirst blocks interruptibly if full
+     */
+    public void testBlockingPutFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.putFirst(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+                try {
+                    q.putFirst(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putFirst blocks waiting for take when full
+     */
+    public void testPutFirstWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity + 1; i++)
+                    q.putFirst(i);
+                try {
+                    q.putFirst(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(q.remainingCapacity(), 0);
+        assertEquals(capacity - 1, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(q.remainingCapacity(), 0);
+    }
+
+    /**
+     * timed offerFirst times out if full and elements not taken
+     */
+    public void testTimedOfferFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.putFirst(new Object());
+                q.putFirst(new Object());
+                assertFalse(q.offerFirst(new Object(), SHORT_DELAY_MS, MILLISECONDS));
+                try {
+                    q.offerFirst(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTakeFirst() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.takeFirst());
+        }
+    }
+
+    /**
+     * takeFirst blocks interruptibly when empty
+     */
+    public void testTakeFirstFromEmpty() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws InterruptedException {
+                q.takeFirst();
+            }};
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * TakeFirst removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTakeFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    assertEquals(i, q.takeFirst());
+                try {
+                    q.takeFirst();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+
+    /**
+     * timed pollFirst with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollFirst0() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst(0, MILLISECONDS));
+        }
+        assertNull(q.pollFirst(0, MILLISECONDS));
+    }
+
+    /**
+     * timed pollFirst with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollFirst() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst(SHORT_DELAY_MS, MILLISECONDS));
+        }
+        assertNull(q.pollFirst(SHORT_DELAY_MS, MILLISECONDS));
+    }
+
+    /**
+     * Interrupted timed pollFirst throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPollFirst() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                LinkedBlockingDeque q = populatedDeque(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.pollFirst(SHORT_DELAY_MS, MILLISECONDS));
+                }
+                try {
+                    q.pollFirst(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     *  timed pollFirst before a delayed offerFirst fails; after offerFirst succeeds;
+     *  on interruption throws
+     */
+    public void testTimedPollFirstWithOfferFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.pollFirst(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offerFirst(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * putLast(null) throws NPE
+     */
+     public void testPutLastNull() throws InterruptedException {
+        try {
+            LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+            q.putLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+     }
+
+    /**
+     * all elements successfully putLast are contained
+     */
+     public void testPutLast() throws InterruptedException {
+         LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+         for (int i = 0; i < SIZE; ++i) {
+             Integer I = new Integer(i);
+             q.putLast(I);
+             assertTrue(q.contains(I));
+         }
+         assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putLast blocks interruptibly if full
+     */
+    public void testBlockingPutLast() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.putLast(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+                try {
+                    q.putLast(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putLast blocks waiting for take when full
+     */
+    public void testPutLastWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity + 1; i++)
+                    q.putLast(i);
+                try {
+                    q.putLast(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(q.remainingCapacity(), 0);
+        assertEquals(0, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(q.remainingCapacity(), 0);
+    }
+
+    /**
+     * timed offerLast times out if full and elements not taken
+     */
+    public void testTimedOfferLast() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.putLast(new Object());
+                q.putLast(new Object());
+                assertFalse(q.offerLast(new Object(), SHORT_DELAY_MS, MILLISECONDS));
+                try {
+                    q.offerLast(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * takeLast retrieves elements in FIFO order
+     */
+    public void testTakeLast() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i-1, q.takeLast());
+        }
+    }
+
+    /**
+     * takeLast blocks interruptibly when empty
+     */
+    public void testTakeLastFromEmpty() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws InterruptedException {
+                q.takeLast();
+            }};
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * TakeLast removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTakeLast() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    assertEquals(SIZE - 1 - i, q.takeLast());
+                try {
+                    q.takeLast();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * timed pollLast with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollLast0() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i-1, q.pollLast(0, MILLISECONDS));
+        }
+        assertNull(q.pollLast(0, MILLISECONDS));
+    }
+
+    /**
+     * timed pollLast with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollLast() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE-i-1, q.pollLast(SHORT_DELAY_MS, MILLISECONDS));
+        }
+        assertNull(q.pollLast(SHORT_DELAY_MS, MILLISECONDS));
+    }
+
+    /**
+     * Interrupted timed pollLast throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPollLast() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                LinkedBlockingDeque q = populatedDeque(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(SIZE-i-1, q.pollLast(SHORT_DELAY_MS, MILLISECONDS));
+                }
+                try {
+                    q.pollLast(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     *  timed poll before a delayed offerLast fails; after offerLast succeeds;
+     *  on interruption throws
+     */
+    public void testTimedPollWithOfferLast() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offerLast(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
+
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            q.poll();
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i+=2) {
+            assertTrue(q.remove(new Integer(i)));
+            assertFalse(q.remove(new Integer(i+1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertEquals(SIZE, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        LinkedBlockingDeque p = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        LinkedBlockingDeque p = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE-i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            LinkedBlockingDeque q = populatedDeque(SIZE);
+            LinkedBlockingDeque p = populatedDeque(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE-i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer I = (Integer)(p.remove());
+                assertFalse(q.contains(I));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testToArray() throws InterruptedException{
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.take());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testToArray2() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        ints = (Integer[])q.toArray(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.take());
+    }
+
+    /**
+     * toArray(null) throws NPE
+     */
+    public void testToArray_BadArg() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            Object o[] = q.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray with incompatible array type throws CCE
+     */
+    public void testToArray1_BadArg() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            Object o[] = q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertEquals(it.next(), q.take());
+        }
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove () {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+        q.add(two);
+        q.add(one);
+        q.add(three);
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        assertEquals(0, q.remainingCapacity());
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration () {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+        assertEquals(0, q.size());
+    }
+
+
+    /**
+     *  Descending iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        int i = 0;
+        Iterator it = q.descendingIterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     *  Descending iterator ordering is reverse FIFO
+     */
+    public void testDescendingIteratorOrdering() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            int k = 0;
+            for (Iterator it = q.descendingIterator(); it.hasNext();) {
+                assertEquals(++k, it.next());
+            }
+
+            assertEquals(3, k);
+            q.remove();
+            q.remove();
+            q.remove();
+        }
+    }
+
+    /**
+     * descendingIterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove () {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            Iterator it = q.descendingIterator();
+            assertEquals(it.next(), new Integer(1));
+            it.remove();
+            assertEquals(it.next(), new Integer(2));
+            it = q.descendingIterator();
+            assertEquals(it.next(), new Integer(2));
+            assertEquals(it.next(), new Integer(3));
+            it.remove();
+            assertFalse(it.hasNext());
+            q.remove();
+        }
+    }
+
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
+        }
+    }
+
+
+    /**
+     * offer transfers elements across Executor tasks
+     */
+    public void testOfferInExecutor() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        q.add(one);
+        q.add(two);
+        ExecutorService executor = Executors.newFixedThreadPool(2);
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(q.offer(three));
+                assertTrue(q.offer(three, MEDIUM_DELAY_MS, MILLISECONDS));
+                assertEquals(0, q.remainingCapacity());
+            }});
+
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                assertSame(one, q.take());
+            }});
+
+        joinPool(executor);
+    }
+
+    /**
+     * poll retrieves elements across Executor threads
+     */
+    public void testPollInExecutor() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        ExecutorService executor = Executors.newFixedThreadPool(2);
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll());
+                assertSame(one, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(q.isEmpty());
+            }});
+
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                q.put(one);
+            }});
+
+        joinPool(executor);
+    }
+
+    /**
+     * A deserialized serialized deque has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        LinkedBlockingDeque r = (LinkedBlockingDeque)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
+    }
+
+    /**
+     * drainTo(null) throws NPE
+     */
+    public void testDrainToNull() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            q.drainTo(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * drainTo(this) throws IAE
+     */
+    public void testDrainToSelf() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            q.drainTo(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * drainTo(c) empties deque into another collection c
+     */
+    public void testDrainTo() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), 2);
+        for (int i = 0; i < 2; ++i)
+            assertEquals(l.get(i), new Integer(i));
+    }
+
+    /**
+     * drainTo empties full deque, unblocking a waiting put.
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(SIZE+1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(null, n) throws NPE
+     */
+    public void testDrainToNullN() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            q.drainTo(null, 0);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * drainTo(this, n) throws IAE
+     */
+    public void testDrainToSelfN() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            q.drainTo(q, 0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * drainTo(c, n) empties first max {n, size} elements of deque into c
+     */
+    public void testDrainToN() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        for (int i = 0; i < SIZE + 2; ++i) {
+            for (int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE)? i : SIZE;
+            assertEquals(l.size(), k);
+            assertEquals(q.size(), SIZE-k);
+            for (int j = 0; j < k; ++j)
+                assertEquals(l.get(j), new Integer(j));
+            while (q.poll() != null) ;
+        }
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
index 6648afb..a98dc21 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedBlockingQueueTest.java
@@ -2,23 +2,19 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 
 public class LinkedBlockingQueueTest extends JSR166TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
-
     public static Test suite() {
         return new TestSuite(LinkedBlockingQueueTest.class);
     }
@@ -31,7 +27,7 @@
     private LinkedBlockingQueue populatedQueue(int n) {
         LinkedBlockingQueue q = new LinkedBlockingQueue(n);
         assertTrue(q.isEmpty());
-        for(int i = 0; i < n; i++)
+        for (int i = 0; i < n; i++)
             assertTrue(q.offer(new Integer(i)));
         assertFalse(q.isEmpty());
         assertEquals(0, q.remainingCapacity());
@@ -49,14 +45,13 @@
     }
 
     /**
-     * Constructor throws IAE if  capacity argument nonpositive
+     * Constructor throws IAE if capacity argument nonpositive
      */
     public void testConstructor2() {
         try {
             LinkedBlockingQueue q = new LinkedBlockingQueue(0);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -66,8 +61,7 @@
         try {
             LinkedBlockingQueue q = new LinkedBlockingQueue(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -78,8 +72,7 @@
             Integer[] ints = new Integer[SIZE];
             LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -92,23 +85,19 @@
                 ints[i] = new Integer(i);
             LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of collection used to initialize
      */
     public void testConstructor6() {
-        try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -151,7 +140,7 @@
             LinkedBlockingQueue q = new LinkedBlockingQueue(1);
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -162,7 +151,7 @@
             LinkedBlockingQueue q = new LinkedBlockingQueue(1);
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -185,8 +174,8 @@
             }
             assertEquals(0, q.remainingCapacity());
             q.add(new Integer(SIZE));
-        } catch (IllegalStateException success){
-        }
+            shouldThrow();
+        } catch (IllegalStateException success) {}
     }
 
     /**
@@ -197,8 +186,7 @@
             LinkedBlockingQueue q = new LinkedBlockingQueue(1);
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -209,8 +197,7 @@
             LinkedBlockingQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -222,8 +209,7 @@
             Integer[] ints = new Integer[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with any null elements throws NPE after
@@ -237,8 +223,7 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll throws ISE if not enough room
@@ -251,216 +236,167 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (IllegalStateException success) {}
+        } catch (IllegalStateException success) {}
     }
     /**
      * Queue contains all elements, in traversal order, of successful addAll
      */
     public void testAddAll5() {
-        try {
-            Integer[] empty = new Integer[0];
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
-            assertFalse(q.addAll(Arrays.asList(empty)));
-            assertTrue(q.addAll(Arrays.asList(ints)));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
      * put(null) throws NPE
      */
-     public void testPutNull() {
+     public void testPutNull() throws InterruptedException {
         try {
             LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
             q.put(null);
             shouldThrow();
-        }
-        catch (NullPointerException success){
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
      }
 
     /**
      * all elements successfully put are contained
      */
-     public void testPut() {
-         try {
-             LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
-             for (int i = 0; i < SIZE; ++i) {
-                 Integer I = new Integer(i);
-                 q.put(I);
-                 assertTrue(q.contains(I));
-             }
-             assertEquals(0, q.remainingCapacity());
-         }
-        catch (InterruptedException ie) {
-            unexpectedException();
+    public void testPut() throws InterruptedException {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer I = new Integer(i);
+            q.put(I);
+            assertTrue(q.contains(I));
         }
+        assertEquals(0, q.remainingCapacity());
     }
 
     /**
      * put blocks interruptibly if full
      */
-    public void testBlockingPut() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            q.put(new Integer(i));
-                            ++added;
-                        }
-                        q.put(new Integer(SIZE));
-                        threadShouldThrow();
-                    } catch (InterruptedException ie){
-                        threadAssertEquals(added, SIZE);
-                    }
-                }});
+    public void testBlockingPut() throws InterruptedException {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.put(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
         t.start();
-        try {
-           Thread.sleep(SHORT_DELAY_MS);
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
     }
 
     /**
      * put blocks waiting for take when full
      */
-    public void testPutWithTake() {
+    public void testPutWithTake() throws InterruptedException {
+        final int capacity = 2;
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        threadShouldThrow();
-                    } catch (InterruptedException e){
-                        threadAssertTrue(added >= 2);
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.take();
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity + 1; i++)
+                    q.put(i);
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(q.remainingCapacity(), 0);
+        assertEquals(0, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        assertEquals(q.remainingCapacity(), 0);
     }
 
     /**
      * timed offer times out if full and elements not taken
      */
-    public void testTimedOffer() {
+    public void testTimedOffer() throws InterruptedException {
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new Object());
-                        q.put(new Object());
-                        threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Object());
+                q.put(new Object());
+                assertFalse(q.offer(new Object(), SHORT_DELAY_MS, MILLISECONDS));
+                try {
+                    q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * take retrieves elements in FIFO order
      */
-    public void testTake() {
-        try {
-            LinkedBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.take()).intValue());
-            }
-        } catch (InterruptedException e){
-            unexpectedException();
+    public void testTake() throws InterruptedException {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
         }
     }
 
     /**
      * take blocks interruptibly when empty
      */
-    public void testTakeFromEmpty() {
+    public void testTakeFromEmpty() throws InterruptedException {
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){ }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }};
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * Take removes existing elements until empty, then blocks interruptibly
      */
-    public void testBlockingTake() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        LinkedBlockingQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            assertEquals(i, ((Integer)q.take()).intValue());
-                        }
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){
-                    }
-                }});
-        t.start();
-        try {
-           Thread.sleep(SHORT_DELAY_MS);
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
-    }
+    public void testBlockingTake() throws InterruptedException {
+        final LinkedBlockingQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
 
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
 
     /**
      * poll succeeds unless empty
@@ -468,7 +404,7 @@
     public void testPoll() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.poll()).intValue());
+            assertEquals(i, q.poll());
         }
         assertNull(q.poll());
     }
@@ -476,85 +412,69 @@
     /**
      * timed pool with zero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll0() {
-        try {
-            LinkedBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue());
-            }
-            assertNull(q.poll(0, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
+    public void testTimedPoll0() throws InterruptedException {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
         }
+        assertNull(q.poll(0, MILLISECONDS));
     }
 
     /**
      * timed pool with nonzero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll() {
-        try {
-            LinkedBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
-            }
-            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
+    public void testTimedPoll() throws InterruptedException {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
         }
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
     }
 
     /**
      * Interrupted timed poll throws InterruptedException instead of
      * returning timeout status
      */
-    public void testInterruptedTimedPoll() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        LinkedBlockingQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
-                        }
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch (InterruptedException success){
-                    }
-                }});
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                LinkedBlockingQueue q = populatedQueue(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                }
+                try {
+                    q.poll(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
         t.start();
-        try {
-           Thread.sleep(SHORT_DELAY_MS);
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  timed poll before a delayed offer fails; after offer succeeds;
      *  on interruption throws
      */
-    public void testTimedPollWithOffer() {
+    public void testTimedPollWithOffer() throws InterruptedException {
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success) { }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
     }
 
     /**
@@ -563,10 +483,10 @@
     public void testPeek() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.peek()).intValue());
-            q.poll();
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
             assertTrue(q.peek() == null ||
-                       i != ((Integer)q.peek()).intValue());
+                       !q.peek().equals(i));
         }
         assertNull(q.peek());
     }
@@ -577,14 +497,13 @@
     public void testElement() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.element()).intValue());
-            q.poll();
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
         }
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -593,13 +512,12 @@
     public void testRemove() {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.remove()).intValue());
+            assertEquals(i, q.remove());
         }
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-        }
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -620,18 +538,14 @@
     /**
      * An add following remove(x) succeeds
      */
-    public void testRemoveElementAndAdd() {
-        try {
-            LinkedBlockingQueue q = new LinkedBlockingQueue();
-            assertTrue(q.add(new Integer(1)));
-            assertTrue(q.add(new Integer(2)));
-            assertTrue(q.remove(new Integer(1)));
-            assertTrue(q.remove(new Integer(2)));
-            assertTrue(q.add(new Integer(3)));
-            assertTrue(q.take() != null);
-        } catch (Exception e){
-            unexpectedException();
-        }
+    public void testRemoveElementAndAdd() throws InterruptedException {
+        LinkedBlockingQueue q = new LinkedBlockingQueue();
+        assertTrue(q.add(new Integer(1)));
+        assertTrue(q.add(new Integer(2)));
+        assertTrue(q.remove(new Integer(1)));
+        assertTrue(q.remove(new Integer(2)));
+        assertTrue(q.add(new Integer(3)));
+        assertTrue(q.take() != null);
     }
 
     /**
@@ -714,67 +628,55 @@
     /**
      * toArray contains all elements
      */
-    public void testToArray() {
+    public void testToArray() throws InterruptedException {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         Object[] o = q.toArray();
-        try {
-        for(int i = 0; i < o.length; i++)
+        for (int i = 0; i < o.length; i++)
             assertEquals(o[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
     }
 
     /**
      * toArray(a) contains all elements
      */
-    public void testToArray2() {
+    public void testToArray2() throws InterruptedException {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         Integer[] ints = new Integer[SIZE];
         ints = (Integer[])q.toArray(ints);
-        try {
-            for(int i = 0; i < ints.length; i++)
-                assertEquals(ints[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.take());
     }
 
     /**
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
         try {
-            LinkedBlockingQueue q = populatedQueue(SIZE);
             Object o[] = q.toArray(null);
             shouldThrow();
-        } catch(NullPointerException success){}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * toArray with incompatible array type throws CCE
      */
     public void testToArray1_BadArg() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
         try {
-            LinkedBlockingQueue q = populatedQueue(SIZE);
-            Object o[] = q.toArray(new String[10] );
+            Object o[] = q.toArray(new String[10]);
             shouldThrow();
-        } catch(ArrayStoreException  success){}
+        } catch (ArrayStoreException success) {}
     }
 
 
     /**
      * iterator iterates through all elements
      */
-    public void testIterator() {
+    public void testIterator() throws InterruptedException {
         LinkedBlockingQueue q = populatedQueue(SIZE);
         Iterator it = q.iterator();
-        try {
-            while(it.hasNext()){
-                assertEquals(it.next(), q.take());
-            }
-        } catch (InterruptedException e){
-            unexpectedException();
+        while (it.hasNext()) {
+            assertEquals(it.next(), q.take());
         }
     }
 
@@ -792,8 +694,8 @@
         it.remove();
 
         it = q.iterator();
-        assertEquals(it.next(), one);
-        assertEquals(it.next(), three);
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
         assertFalse(it.hasNext());
     }
 
@@ -809,8 +711,7 @@
         assertEquals(0, q.remainingCapacity());
         int k = 0;
         for (Iterator it = q.iterator(); it.hasNext();) {
-            int i = ((Integer)(it.next())).intValue();
-            assertEquals(++k, i);
+            assertEquals(++k, it.next());
         }
         assertEquals(3, k);
     }
@@ -823,14 +724,9 @@
         q.add(one);
         q.add(two);
         q.add(three);
-        try {
-            for (Iterator it = q.iterator(); it.hasNext();) {
-                q.remove();
-                it.next();
-            }
-        }
-        catch (ConcurrentModificationException e) {
-            unexpectedException();
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
         }
         assertEquals(0, q.size());
     }
@@ -856,30 +752,18 @@
         q.add(one);
         q.add(two);
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertFalse(q.offer(three));
-                try {
-                    threadAssertTrue(q.offer(three, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertEquals(0, q.remainingCapacity());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(q.offer(three));
+                assertTrue(q.offer(three, MEDIUM_DELAY_MS, MILLISECONDS));
+                assertEquals(0, q.remainingCapacity());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    threadAssertEquals(one, q.take());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                assertSame(one, q.take());
+            }});
 
         joinPool(executor);
     }
@@ -890,30 +774,18 @@
     public void testPollInExecutor() {
         final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertNull(q.poll());
-                try {
-                    threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertTrue(q.isEmpty());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll());
+                assertSame(one, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(q.isEmpty());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    q.put(one);
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                q.put(one);
+            }});
 
         joinPool(executor);
     }
@@ -921,24 +793,20 @@
     /**
      * A deserialized serialized queue has same elements in same order
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         LinkedBlockingQueue q = populatedQueue(SIZE);
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            LinkedBlockingQueue r = (LinkedBlockingQueue)in.readObject();
-            assertEquals(q.size(), r.size());
-            while (!q.isEmpty())
-                assertEquals(q.remove(), r.remove());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        LinkedBlockingQueue r = (LinkedBlockingQueue)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
     }
 
     /**
@@ -949,8 +817,7 @@
         try {
             q.drainTo(null);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -961,8 +828,7 @@
         try {
             q.drainTo(q);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -992,29 +858,21 @@
     /**
      * drainTo empties full queue, unblocking a waiting put.
      */
-    public void testDrainToWithActivePut() {
+    public void testDrainToWithActivePut() throws InterruptedException {
         final LinkedBlockingQueue q = populatedQueue(SIZE);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new Integer(SIZE+1));
-                    } catch (InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            ArrayList l = new ArrayList();
-            q.drainTo(l);
-            assertTrue(l.size() >= SIZE);
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(l.get(i), new Integer(i));
-            t.join();
-            assertTrue(q.size() + l.size() >= SIZE);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(SIZE+1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
     }
 
     /**
@@ -1025,8 +883,7 @@
         try {
             q.drainTo(null, 0);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -1037,8 +894,7 @@
         try {
             q.drainTo(q, 0);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -1047,7 +903,7 @@
     public void testDrainToN() {
         LinkedBlockingQueue q = new LinkedBlockingQueue();
         for (int i = 0; i < SIZE + 2; ++i) {
-            for(int j = 0; j < SIZE; j++)
+            for (int j = 0; j < SIZE; j++)
                 assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java
index 3a20207..3017c52 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LinkedListTest.java
@@ -13,10 +13,6 @@
 import java.util.concurrent.*;
 
 public class LinkedListTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
-
     public static Test suite() {
         return new TestSuite(LinkedListTest.class);
     }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
index b39db2e..1052a24 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/LockSupportTest.java
@@ -2,21 +2,18 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.locks.*;
 
-public class LockSupportTest extends JSR166TestCase{
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
+public class LockSupportTest extends JSR166TestCase {
     public static Test suite() {
         return new TestSuite(LockSupportTest.class);
     }
@@ -24,145 +21,92 @@
     /**
      * park is released by unpark occurring after park
      */
-    public void testPark() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        LockSupport.park();
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            LockSupport.unpark(t);
-            t.join();
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testPark() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                LockSupport.park();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        LockSupport.unpark(t);
+        t.join();
     }
 
     /**
      * park is released by unpark occurring before park
      */
-    public void testPark2() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        Thread.sleep(SHORT_DELAY_MS);
-                        LockSupport.park();
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            LockSupport.unpark(t);
-            t.join();
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testPark2() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SHORT_DELAY_MS);
+                LockSupport.park();
+            }});
+
+        t.start();
+        LockSupport.unpark(t);
+        t.join();
     }
 
     /**
      * park is released by interrupt
      */
-    public void testPark3() {
-	Thread t = new Thread(new Runnable() {
-		public void run() {
-		    try {
-			LockSupport.park();
-		    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testPark3() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                LockSupport.park();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * park returns if interrupted before park
      */
-    public void testPark4() {
+    public void testPark4() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        LockSupport.park();
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.interrupt();
-            lock.unlock();
-            t.join();
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.lock();
+                LockSupport.park();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        lock.unlock();
+        t.join();
     }
 
     /**
      * parkNanos times out if not unparked
      */
-    public void testParkNanos() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        LockSupport.parkNanos(1000);
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testParkNanos() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                LockSupport.parkNanos(1000);
+            }});
+
+        t.start();
+        t.join();
     }
 
 
     /**
      * parkUntil times out if not unparked
      */
-    public void testParkUntil() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        long d = new Date().getTime() + 100;
-                        LockSupport.parkUntil(d);
-                    } catch(Exception e){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-        }
-        catch(Exception e) {
-            unexpectedException();
-        }
+    public void testParkUntil() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                long d = new Date().getTime() + 100;
+                LockSupport.parkUntil(d);
+            }});
+
+        t.start();
+        t.join();
     }
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java
index 3857e0f..f1dd88d 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityBlockingQueueTest.java
@@ -2,21 +2,19 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 
 public class PriorityBlockingQueueTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(PriorityBlockingQueueTest.class);
     }
@@ -24,13 +22,9 @@
     private static final int NOCAP = Integer.MAX_VALUE;
 
     /** Sample Comparator */
-    static class MyReverseComparator implements Comparator { 
+    static class MyReverseComparator implements Comparator {
         public int compare(Object x, Object y) {
-            int i = ((Integer)x).intValue();
-            int j = ((Integer)y).intValue();
-            if (i < j) return 1;
-            if (i > j) return -1;
-            return 0;
+            return ((Comparable)y).compareTo(x);
         }
     }
 
@@ -41,16 +35,16 @@
     private PriorityBlockingQueue populatedQueue(int n) {
         PriorityBlockingQueue q = new PriorityBlockingQueue(n);
         assertTrue(q.isEmpty());
-        for(int i = n-1; i >= 0; i-=2)
+        for (int i = n-1; i >= 0; i-=2)
             assertTrue(q.offer(new Integer(i)));
-        for(int i = (n & 1); i < n; i+=2)
+        for (int i = (n & 1); i < n; i+=2)
             assertTrue(q.offer(new Integer(i)));
         assertFalse(q.isEmpty());
         assertEquals(NOCAP, q.remainingCapacity());
         assertEquals(n, q.size());
         return q;
     }
- 
+
     /**
      * A new queue has unbounded capacity
      */
@@ -59,14 +53,13 @@
     }
 
     /**
-     * Constructor throws IAE if  capacity argument nonpositive
+     * Constructor throws IAE if capacity argument nonpositive
      */
     public void testConstructor2() {
         try {
             PriorityBlockingQueue q = new PriorityBlockingQueue(0);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -76,8 +69,7 @@
         try {
             PriorityBlockingQueue q = new PriorityBlockingQueue(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -88,8 +80,7 @@
             Integer[] ints = new Integer[SIZE];
             PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -102,41 +93,34 @@
                 ints[i] = new Integer(i);
             PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of collection used to initialize
      */
     public void testConstructor6() {
-        try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
      * The comparator used in constructor is used
      */
     public void testConstructor7() {
-        try {
-            MyReverseComparator cmp = new MyReverseComparator();
-            PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE, cmp);
-            assertEquals(cmp, q.comparator());
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            q.addAll(Arrays.asList(ints));
-            for (int i = SIZE-1; i >= 0; --i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        MyReverseComparator cmp = new MyReverseComparator();
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE, cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE-1; i >= 0; --i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -180,7 +164,7 @@
             PriorityBlockingQueue q = new PriorityBlockingQueue(1);
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -191,7 +175,7 @@
             PriorityBlockingQueue q = new PriorityBlockingQueue(1);
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -213,8 +197,7 @@
             q.offer(new Object());
             q.offer(new Object());
             shouldThrow();
-        }
-        catch(ClassCastException success) {}
+        } catch (ClassCastException success) {}
     }
 
     /**
@@ -236,8 +219,7 @@
             PriorityBlockingQueue q = new PriorityBlockingQueue(1);
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -248,8 +230,7 @@
             PriorityBlockingQueue q = populatedQueue(SIZE);
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -261,8 +242,7 @@
             Integer[] ints = new Integer[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with any null elements throws NPE after
@@ -276,26 +256,22 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of successful addAll
      */
     public void testAddAll5() {
-        try {
-            Integer[] empty = new Integer[0];
-            Integer[] ints = new Integer[SIZE];
-            for (int i = SIZE-1; i >= 0; --i)
-                ints[i] = new Integer(i);
-            PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
-            assertFalse(q.addAll(Arrays.asList(empty)));
-            assertTrue(q.addAll(Arrays.asList(ints)));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = SIZE-1; i >= 0; --i)
+            ints[i] = new Integer(i);
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -306,149 +282,107 @@
             PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
             q.put(null);
             shouldThrow();
-        } 
-        catch (NullPointerException success){
-        }   
+        } catch (NullPointerException success) {}
      }
 
     /**
      * all elements successfully put are contained
      */
      public void testPut() {
-         try {
-             PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
-             for (int i = 0; i < SIZE; ++i) {
-                 Integer I = new Integer(i);
-                 q.put(I);
-                 assertTrue(q.contains(I));
-             }
-             assertEquals(SIZE, q.size());
+         PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+         for (int i = 0; i < SIZE; ++i) {
+             Integer I = new Integer(i);
+             q.put(I);
+             assertTrue(q.contains(I));
          }
-         finally {
-        }
+         assertEquals(SIZE, q.size());
     }
 
     /**
      * put doesn't block waiting for take
      */
-    public void testPutWithTake() {
+    public void testPutWithTake() throws InterruptedException {
         final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        q.put(new Integer(0));
-                        ++added;
-                        q.put(new Integer(0));
-                        ++added;
-                        q.put(new Integer(0));
-                        ++added;
-                        q.put(new Integer(0));
-                        ++added;
-                        threadAssertTrue(added == 4);
-                    } finally {
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.take();
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        final int size = 4;
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                for (int i = 0; i < size; i++)
+                    q.put(new Integer(0));
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(q.size(), size);
+        q.take();
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timed offer does not time out
      */
-    public void testTimedOffer() {
+    public void testTimedOffer() throws InterruptedException {
         final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new Integer(0));
-                        q.put(new Integer(0));
-                        threadAssertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(q.offer(new Integer(0), LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } finally { }
-                }
-            });
-        
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new Integer(0));
+                q.put(new Integer(0));
+                assertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(q.offer(new Integer(0), LONG_DELAY_MS, MILLISECONDS));
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * take retrieves elements in priority order
      */
-    public void testTake() {
-        try {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.take()).intValue());
-            }
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTake() throws InterruptedException {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
     }
 
     /**
      * take blocks interruptibly when empty
      */
-    public void testTakeFromEmpty() {
+    public void testTakeFromEmpty() throws InterruptedException {
         final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){ }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * Take removes existing elements until empty, then blocks interruptibly
      */
-    public void testBlockingTake() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        PriorityBlockingQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(i, ((Integer)q.take()).intValue());
-                        }
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){
-                    }   
-                }});
+    public void testBlockingTake() throws InterruptedException {
+        final PriorityBlockingQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
@@ -458,7 +392,7 @@
     public void testPoll() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.poll()).intValue());
+            assertEquals(i, q.poll());
         }
         assertNull(q.poll());
     }
@@ -466,86 +400,70 @@
     /**
      * timed pool with zero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll0() {
-        try {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue());
-            }
-            assertNull(q.poll(0, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTimedPoll0() throws InterruptedException {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
     }
 
     /**
      * timed pool with nonzero timeout succeeds when non-empty, else times out
      */
-    public void testTimedPoll() {
-        try {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
-            for (int i = 0; i < SIZE; ++i) {
-                assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
-            }
-            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTimedPoll() throws InterruptedException {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
+        }
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
     }
 
     /**
      * Interrupted timed poll throws InterruptedException instead of
      * returning timeout status
      */
-    public void testInterruptedTimedPoll() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        PriorityBlockingQueue q = populatedQueue(SIZE);
-                        for (int i = 0; i < SIZE; ++i) {
-                            threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
-                        }
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch (InterruptedException success){
-                    }   
-                }});
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                PriorityBlockingQueue q = populatedQueue(SIZE);
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                }
+                try {
+                    q.poll(SMALL_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  timed poll before a delayed offer fails; after offer succeeds;
      *  on interruption throws
      */
-    public void testTimedPollWithOffer() {
+    public void testTimedPollWithOffer() throws InterruptedException {
         final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success) { }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
-    }  
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
 
 
     /**
@@ -554,10 +472,10 @@
     public void testPeek() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.peek()).intValue());
-            q.poll();
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
             assertTrue(q.peek() == null ||
-                       i != ((Integer)q.peek()).intValue());
+                       !q.peek().equals(i));
         }
         assertNull(q.peek());
     }
@@ -568,14 +486,13 @@
     public void testElement() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.element()).intValue());
-            q.poll();
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
         }
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -584,13 +501,12 @@
     public void testRemove() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.remove()).intValue());
+            assertEquals(i, q.remove());
         }
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-        }   
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -607,7 +523,7 @@
         }
         assertTrue(q.isEmpty());
     }
-        
+
     /**
      * contains(x) reports true when elements added but not yet removed
      */
@@ -687,56 +603,48 @@
     /**
      *  toArray contains all elements
      */
-    public void testToArray() {
+    public void testToArray() throws InterruptedException {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         Object[] o = q.toArray();
         Arrays.sort(o);
-        try {
-        for(int i = 0; i < o.length; i++)
+        for (int i = 0; i < o.length; i++)
             assertEquals(o[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
     }
 
     /**
      * toArray(a) contains all elements
      */
-    public void testToArray2() {
+    public void testToArray2() throws InterruptedException {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         Integer[] ints = new Integer[SIZE];
         ints = (Integer[])q.toArray(ints);
         Arrays.sort(ints);
-        try {
-            for(int i = 0; i < ints.length; i++)
-                assertEquals(ints[i], q.take());
-        } catch (InterruptedException e){
-            unexpectedException();
-        }    
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.take());
     }
 
     /**
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
             Object o[] = q.toArray(null);
             shouldThrow();
-        } catch(NullPointerException success){}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * toArray with incompatible array type throws CCE
      */
     public void testToArray1_BadArg() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
-            PriorityBlockingQueue q = populatedQueue(SIZE);
-            Object o[] = q.toArray(new String[10] );
+            Object o[] = q.toArray(new String[10]);
             shouldThrow();
-        } catch(ArrayStoreException  success){}
+        } catch (ArrayStoreException success) {}
     }
-    
+
     /**
      * iterator iterates through all elements
      */
@@ -744,7 +652,7 @@
         PriorityBlockingQueue q = populatedQueue(SIZE);
         int i = 0;
         Iterator it = q.iterator();
-        while(it.hasNext()) {
+        while (it.hasNext()) {
             assertTrue(q.contains(it.next()));
             ++i;
         }
@@ -780,7 +688,7 @@
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
     /**
      * offer transfers elements across Executor tasks
@@ -788,90 +696,72 @@
     public void testPollInExecutor() {
         final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertNull(q.poll());
-                try {
-                    threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertTrue(q.isEmpty());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll());
+                assertSame(one, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(q.isEmpty());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    q.put(new Integer(1));
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
-        
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                q.put(one);
+            }});
+
         joinPool(executor);
     }
 
     /**
-     * A deserialized serialized queue has same elements 
+     * A deserialized serialized queue has same elements
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         PriorityBlockingQueue q = populatedQueue(SIZE);
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            PriorityBlockingQueue r = (PriorityBlockingQueue)in.readObject();
-            assertEquals(q.size(), r.size());
-            while (!q.isEmpty()) 
-                assertEquals(q.remove(), r.remove());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        PriorityBlockingQueue r = (PriorityBlockingQueue)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
     }
 
     /**
      * drainTo(null) throws NPE
-     */ 
+     */
     public void testDrainToNull() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(null);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this) throws IAE
-     */ 
+     */
     public void testDrainToSelf() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(q);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c) empties queue into another collection c
-     */ 
+     */
     public void testDrainTo() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         ArrayList l = new ArrayList();
         q.drainTo(l);
         assertEquals(q.size(), 0);
         assertEquals(l.size(), SIZE);
-        for (int i = 0; i < SIZE; ++i) 
+        for (int i = 0; i < SIZE; ++i)
             assertEquals(l.get(i), new Integer(i));
         q.add(zero);
         q.add(one);
@@ -882,76 +772,69 @@
         q.drainTo(l);
         assertEquals(q.size(), 0);
         assertEquals(l.size(), 2);
-        for (int i = 0; i < 2; ++i) 
+        for (int i = 0; i < 2; ++i)
             assertEquals(l.get(i), new Integer(i));
     }
 
     /**
      * drainTo empties queue
-     */ 
-    public void testDrainToWithActivePut() {
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
         final PriorityBlockingQueue q = populatedQueue(SIZE);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    q.put(new Integer(SIZE+1));
-                }
-            });
-        try {
-            t.start();
-            ArrayList l = new ArrayList();
-            q.drainTo(l);
-            assertTrue(l.size() >= SIZE);
-            for (int i = 0; i < SIZE; ++i) 
-                assertEquals(l.get(i), new Integer(i));
-            t.join();
-            assertTrue(q.size() + l.size() >= SIZE);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new Integer(SIZE+1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
     }
 
     /**
      * drainTo(null, n) throws NPE
-     */ 
+     */
     public void testDrainToNullN() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(null, 0);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this, n) throws IAE
-     */ 
+     */
     public void testDrainToSelfN() {
         PriorityBlockingQueue q = populatedQueue(SIZE);
         try {
             q.drainTo(q, 0);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c, n) empties first max {n, size} elements of queue into c
-     */ 
+     */
     public void testDrainToN() {
         PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE*2);
         for (int i = 0; i < SIZE + 2; ++i) {
-            for(int j = 0; j < SIZE; j++)
+            for (int j = 0; j < SIZE; j++)
                 assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE)? i : SIZE;
             assertEquals(l.size(), k);
             assertEquals(q.size(), SIZE-k);
-            for (int j = 0; j < k; ++j) 
+            for (int j = 0; j < k; ++j)
                 assertEquals(l.get(j), new Integer(j));
             while (q.poll() != null) ;
         }
     }
 
-
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java
index 409e1ed..12ddef4 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/PriorityQueueTest.java
@@ -2,11 +2,11 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
@@ -14,20 +14,13 @@
 import java.io.*;
 
 public class PriorityQueueTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(PriorityQueueTest.class);
     }
 
-    static class MyReverseComparator implements Comparator { 
+    static class MyReverseComparator implements Comparator {
         public int compare(Object x, Object y) {
-            int i = ((Integer)x).intValue();
-            int j = ((Integer)y).intValue();
-            if (i < j) return 1;
-            if (i > j) return -1;
-            return 0;
+            return ((Comparable)y).compareTo(x);
         }
     }
 
@@ -38,15 +31,15 @@
     private PriorityQueue populatedQueue(int n) {
         PriorityQueue q = new PriorityQueue(n);
         assertTrue(q.isEmpty());
-        for(int i = n-1; i >= 0; i-=2)
+        for (int i = n-1; i >= 0; i-=2)
             assertTrue(q.offer(new Integer(i)));
-        for(int i = (n & 1); i < n; i+=2)
+        for (int i = (n & 1); i < n; i+=2)
             assertTrue(q.offer(new Integer(i)));
         assertFalse(q.isEmpty());
         assertEquals(n, q.size());
         return q;
     }
- 
+
     /**
      * A new queue has unbounded capacity
      */
@@ -55,14 +48,13 @@
     }
 
     /**
-     * Constructor throws IAE if  capacity argument nonpositive
+     * Constructor throws IAE if capacity argument nonpositive
      */
     public void testConstructor2() {
         try {
             PriorityQueue q = new PriorityQueue(0);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -72,8 +64,7 @@
         try {
             PriorityQueue q = new PriorityQueue((Collection)null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -84,8 +75,7 @@
             Integer[] ints = new Integer[SIZE];
             PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -98,41 +88,34 @@
                 ints[i] = new Integer(i);
             PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of collection used to initialize
      */
     public void testConstructor6() {
-        try {
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
      * The comparator used in constructor is used
      */
     public void testConstructor7() {
-        try {
-            MyReverseComparator cmp = new MyReverseComparator();
-            PriorityQueue q = new PriorityQueue(SIZE, cmp);
-            assertEquals(cmp, q.comparator());
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(i);
-            q.addAll(Arrays.asList(ints));
-            for (int i = SIZE-1; i >= 0; --i)
-                assertEquals(ints[i], q.poll());
-        }
-        finally {}
+        MyReverseComparator cmp = new MyReverseComparator();
+        PriorityQueue q = new PriorityQueue(SIZE, cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE-1; i >= 0; --i)
+            assertEquals(ints[i], q.poll());
     }
 
     /**
@@ -172,7 +155,7 @@
             PriorityQueue q = new PriorityQueue(1);
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -183,7 +166,7 @@
             PriorityQueue q = new PriorityQueue(1);
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -205,8 +188,7 @@
             q.offer(new Object());
             q.offer(new Object());
             shouldThrow();
-        }
-        catch(ClassCastException success) {}
+        } catch (ClassCastException success) {}
     }
 
     /**
@@ -228,8 +210,7 @@
             PriorityQueue q = new PriorityQueue(1);
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with null elements throws NPE
@@ -240,8 +221,7 @@
             Integer[] ints = new Integer[SIZE];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll of a collection with any null elements throws NPE after
@@ -255,26 +235,22 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
      * Queue contains all elements of successful addAll
      */
     public void testAddAll5() {
-        try {
-            Integer[] empty = new Integer[0];
-            Integer[] ints = new Integer[SIZE];
-            for (int i = 0; i < SIZE; ++i)
-                ints[i] = new Integer(SIZE-1-i);
-            PriorityQueue q = new PriorityQueue(SIZE);
-            assertFalse(q.addAll(Arrays.asList(empty)));
-            assertTrue(q.addAll(Arrays.asList(ints)));
-            for (int i = 0; i < SIZE; ++i)
-                assertEquals(new Integer(i), q.poll());
-        }
-        finally {}
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE-1-i);
+        PriorityQueue q = new PriorityQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.poll());
     }
 
     /**
@@ -283,7 +259,7 @@
     public void testPoll() {
         PriorityQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.poll()).intValue());
+            assertEquals(i, q.poll());
         }
         assertNull(q.poll());
     }
@@ -294,10 +270,10 @@
     public void testPeek() {
         PriorityQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.peek()).intValue());
-            q.poll();
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
             assertTrue(q.peek() == null ||
-                       i != ((Integer)q.peek()).intValue());
+                       !q.peek().equals(i));
         }
         assertNull(q.peek());
     }
@@ -308,14 +284,13 @@
     public void testElement() {
         PriorityQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.element()).intValue());
-            q.poll();
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
         }
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -324,13 +299,12 @@
     public void testRemove() {
         PriorityQueue q = populatedQueue(SIZE);
         for (int i = 0; i < SIZE; ++i) {
-            assertEquals(i, ((Integer)q.remove()).intValue());
+            assertEquals(i, q.remove());
         }
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-        }   
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -347,7 +321,7 @@
         }
         assertTrue(q.isEmpty());
     }
-        
+
     /**
      * contains(x) reports true when elements added but not yet removed
      */
@@ -430,7 +404,7 @@
         PriorityQueue q = populatedQueue(SIZE);
         Object[] o = q.toArray();
         Arrays.sort(o);
-        for(int i = 0; i < o.length; i++)
+        for (int i = 0; i < o.length; i++)
             assertEquals(o[i], q.poll());
     }
 
@@ -442,10 +416,10 @@
         Integer[] ints = new Integer[SIZE];
         ints = (Integer[])q.toArray(ints);
         Arrays.sort(ints);
-        for(int i = 0; i < ints.length; i++)
+        for (int i = 0; i < ints.length; i++)
             assertEquals(ints[i], q.poll());
     }
-    
+
     /**
      * iterator iterates through all elements
      */
@@ -453,7 +427,7 @@
         PriorityQueue q = populatedQueue(SIZE);
         int i = 0;
         Iterator it = q.iterator();
-        while(it.hasNext()) {
+        while (it.hasNext()) {
             assertTrue(q.contains(it.next()));
             ++i;
         }
@@ -489,27 +463,23 @@
         for (int i = 0; i < SIZE; ++i) {
             assertTrue(s.indexOf(String.valueOf(i)) >= 0);
         }
-    }        
+    }
 
     /**
-     * A deserialized serialized queue has same elements 
+     * A deserialized serialized queue has same elements
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         PriorityQueue q = populatedQueue(SIZE);
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            PriorityQueue r = (PriorityQueue)in.readObject();
-            assertEquals(q.size(), r.size());
-            while (!q.isEmpty()) 
-                assertEquals(q.remove(), r.remove());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        PriorityQueue r = (PriorityQueue)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
     }
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
index c50482d..d6b434e 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantLockTest.java
@@ -2,22 +2,20 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.locks.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.*;
 import java.io.*;
 
 public class ReentrantLockTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(ReentrantLockTest.class);
     }
@@ -25,13 +23,11 @@
     /**
      * A runnable calling lockInterruptibly
      */
-    class InterruptibleLockRunnable implements Runnable {
+    class InterruptibleLockRunnable extends CheckedRunnable {
         final ReentrantLock lock;
         InterruptibleLockRunnable(ReentrantLock l) { lock = l; }
-        public void run() {
-            try {
-                lock.lockInterruptibly();
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            lock.lockInterruptibly();
         }
     }
 
@@ -40,14 +36,11 @@
      * A runnable calling lockInterruptibly that expects to be
      * interrupted
      */
-    class InterruptedLockRunnable implements Runnable {
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
         final ReentrantLock lock;
         InterruptedLockRunnable(ReentrantLock l) { lock = l; }
-        public void run() {
-            try {
-                lock.lockInterruptibly();
-                threadShouldThrow();
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            lock.lockInterruptibly();
         }
     }
 
@@ -62,18 +55,15 @@
         public Collection<Thread> getWaitingThreads(Condition c) {
             return super.getWaitingThreads(c);
         }
-
-
     }
 
     /**
      * Constructor sets given fairness
      */
     public void testConstructor() {
-        ReentrantLock rl = new ReentrantLock();
-        assertFalse(rl.isFair());
-        ReentrantLock r2 = new ReentrantLock(true);
-        assertTrue(r2.isFair());
+        assertFalse(new ReentrantLock().isFair());
+        assertFalse(new ReentrantLock(false).isFair());
+        assertTrue(new ReentrantLock(true).isFair());
     }
 
     /**
@@ -84,6 +74,7 @@
         rl.lock();
         assertTrue(rl.isLocked());
         rl.unlock();
+        assertFalse(rl.isLocked());
     }
 
     /**
@@ -104,8 +95,7 @@
         try {
             rl.unlock();
             shouldThrow();
-
-        } catch(IllegalMonitorStateException success){}
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
@@ -122,88 +112,76 @@
     /**
      * hasQueuedThreads reports whether there are waiting threads
      */
-    public void testhasQueuedThreads() {
+    public void testhasQueuedThreads() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertFalse(lock.hasQueuedThreads());
-            lock.lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(lock.hasQueuedThreads());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertFalse(lock.hasQueuedThreads());
+        lock.lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(lock.hasQueuedThreads());
+        t1.join();
+        t2.join();
     }
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength() {
+    public void testGetQueueLength() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertEquals(0, lock.getQueueLength());
-            lock.lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(2, lock.getQueueLength());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(0, lock.getQueueLength());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertEquals(0, lock.getQueueLength());
+        lock.lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, lock.getQueueLength());
+        t1.join();
+        t2.join();
     }
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength_fair() {
+    public void testGetQueueLength_fair() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock(true);
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertEquals(0, lock.getQueueLength());
-            lock.lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(2, lock.getQueueLength());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(0, lock.getQueueLength());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertEquals(0, lock.getQueueLength());
+        lock.lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, lock.getQueueLength());
+        t1.join();
+        t2.join();
     }
 
     /**
@@ -214,143 +192,117 @@
         try {
             sync.hasQueuedThread(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * hasQueuedThread reports whether a thread is queued.
      */
-    public void testHasQueuedThread() {
+    public void testHasQueuedThread() throws InterruptedException {
         final ReentrantLock sync = new ReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(sync));
         Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
-        try {
-            assertFalse(sync.hasQueuedThread(t1));
-            assertFalse(sync.hasQueuedThread(t2));
-            sync.lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThread(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThread(t1));
-            assertTrue(sync.hasQueuedThread(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThread(t1));
-            assertTrue(sync.hasQueuedThread(t2));
-            sync.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThread(t1));
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThread(t2));
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertFalse(sync.hasQueuedThread(t1));
+        assertFalse(sync.hasQueuedThread(t2));
+        sync.lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThread(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThread(t1));
+        assertTrue(sync.hasQueuedThread(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThread(t1));
+        assertTrue(sync.hasQueuedThread(t2));
+        sync.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThread(t1));
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThread(t2));
+        t1.join();
+        t2.join();
     }
 
 
     /**
      * getQueuedThreads includes waiting threads
      */
-    public void testGetQueuedThreads() {
+    public void testGetQueuedThreads() throws InterruptedException {
         final PublicReentrantLock lock = new PublicReentrantLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            lock.lock();
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().contains(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().contains(t1));
-            assertTrue(lock.getQueuedThreads().contains(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(lock.getQueuedThreads().contains(t1));
-            assertTrue(lock.getQueuedThreads().contains(t2));
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        lock.lock();
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
     }
 
 
     /**
      * timed tryLock is interruptible.
      */
-    public void testInterruptedException2() {
+    public void testInterruptedException2() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
-        try {
-            t.start();
-            t.interrupt();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.tryLock(MEDIUM_DELAY_MS,MILLISECONDS);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
     /**
      * TryLock on a locked lock fails
      */
-    public void testTryLockWhenLocked() {
+    public void testTryLockWhenLocked() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertFalse(lock.tryLock());
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(lock.tryLock());
+            }});
+
+        t.start();
+        t.join();
+        lock.unlock();
     }
 
     /**
      * Timed tryLock on a locked lock times out
      */
-    public void testTryLock_Timeout() {
+    public void testTryLock_Timeout() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
-                    } catch (Exception ex) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(lock.tryLock(1, MILLISECONDS));
+            }});
+
+        t.start();
+        t.join();
+        lock.unlock();
     }
 
     /**
@@ -358,13 +310,13 @@
      */
     public void testGetHoldCount() {
         ReentrantLock lock = new ReentrantLock();
-        for(int i = 1; i <= SIZE; i++) {
+        for (int i = 1; i <= SIZE; i++) {
             lock.lock();
-            assertEquals(i,lock.getHoldCount());
+            assertEquals(i, lock.getHoldCount());
         }
-        for(int i = SIZE; i > 0; i--) {
+        for (int i = SIZE; i > 0; i--) {
             lock.unlock();
-            assertEquals(i-1,lock.getHoldCount());
+            assertEquals(i-1, lock.getHoldCount());
         }
     }
 
@@ -372,92 +324,67 @@
     /**
      * isLocked is true when locked and false when not
      */
-    public void testIsLocked() {
+    public void testIsLocked() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         assertTrue(lock.isLocked());
         lock.unlock();
         assertFalse(lock.isLocked());
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    lock.lock();
-                    try {
-                        Thread.sleep(SMALL_DELAY_MS);
-                    }
-                    catch(Exception e) {
-                        threadUnexpectedException();
-                    }
-                    lock.unlock();
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.isLocked());
-            t.join();
-            assertFalse(lock.isLocked());
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                Thread.sleep(SMALL_DELAY_MS);
+                lock.unlock();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.isLocked());
+        t.join();
+        assertFalse(lock.isLocked());
     }
 
 
     /**
      * lockInterruptibly is interruptible.
      */
-    public void testLockInterruptibly1() {
+    public void testLockInterruptibly1() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         lock.lock();
         Thread t = new Thread(new InterruptedLockRunnable(lock));
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.unlock();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.unlock();
+        t.join();
     }
 
     /**
      * lockInterruptibly succeeds when unlocked, else is interruptible
      */
-    public void testLockInterruptibly2() {
+    public void testLockInterruptibly2() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
-        try {
-            lock.lockInterruptibly();
-        } catch(Exception e) {
-            unexpectedException();
-        }
+        lock.lockInterruptibly();
         Thread t = new Thread(new InterruptedLockRunnable(lock));
-        try {
-            t.start();
-            t.interrupt();
-            assertTrue(lock.isLocked());
-            assertTrue(lock.isHeldByCurrentThread());
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        assertTrue(lock.isLocked());
+        assertTrue(lock.isHeldByCurrentThread());
+        t.join();
     }
 
     /**
      * Calling await without holding lock throws IllegalMonitorStateException
      */
-    public void testAwait_IllegalMonitor() {
+    public void testAwait_IllegalMonitor() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
         try {
             c.await();
             shouldThrow();
-        }
-        catch (IllegalMonitorStateException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
@@ -469,95 +396,64 @@
         try {
             c.signal();
             shouldThrow();
-        }
-        catch (IllegalMonitorStateException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
      * awaitNanos without a signal times out
      */
-    public void testAwaitNanos_Timeout() {
+    public void testAwaitNanos_Timeout() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        try {
-            lock.lock();
-            long t = c.awaitNanos(100);
-            assertTrue(t <= 0);
-            lock.unlock();
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.lock();
+        long t = c.awaitNanos(100);
+        assertTrue(t <= 0);
+        lock.unlock();
     }
 
     /**
      *  timed await without a signal times out
      */
-    public void testAwait_Timeout() {
+    public void testAwait_Timeout() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        try {
-            lock.lock();
-            c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            lock.unlock();
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.lock();
+        assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS));
+        lock.unlock();
     }
 
     /**
      * awaitUntil without a signal times out
      */
-    public void testAwaitUntil_Timeout() {
+    public void testAwaitUntil_Timeout() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        try {
-            lock.lock();
-            java.util.Date d = new java.util.Date();
-            c.awaitUntil(new java.util.Date(d.getTime() + 10));
-            lock.unlock();
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.lock();
+        java.util.Date d = new java.util.Date();
+        assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
+        lock.unlock();
     }
 
     /**
      * await returns when signalled
      */
-    public void testAwait() {
+    public void testAwait() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                c.await();
+                lock.unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            c.signal();
-            lock.unlock();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        c.signal();
+        lock.unlock();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
@@ -568,10 +464,7 @@
         try {
             lock.hasWaiters(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -582,10 +475,7 @@
         try {
             lock.getWaitQueueLength(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -597,10 +487,7 @@
         try {
             lock.getWaitingThreads(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -609,15 +496,12 @@
      */
     public void testHasWaitersIAE() {
         final ReentrantLock lock = new ReentrantLock();
-        final Condition c = (lock.newCondition());
+        final Condition c = lock.newCondition();
         final ReentrantLock lock2 = new ReentrantLock();
         try {
             lock2.hasWaiters(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -625,14 +509,11 @@
      */
     public void testHasWaitersIMSE() {
         final ReentrantLock lock = new ReentrantLock();
-        final Condition c = (lock.newCondition());
+        final Condition c = lock.newCondition();
         try {
             lock.hasWaiters(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -641,15 +522,12 @@
      */
     public void testGetWaitQueueLengthIAE() {
         final ReentrantLock lock = new ReentrantLock();
-        final Condition c = (lock.newCondition());
+        final Condition c = lock.newCondition();
         final ReentrantLock lock2 = new ReentrantLock();
         try {
             lock2.getWaitQueueLength(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -657,14 +535,11 @@
      */
     public void testGetWaitQueueLengthIMSE() {
         final ReentrantLock lock = new ReentrantLock();
-        final Condition c = (lock.newCondition());
+        final Condition c = lock.newCondition();
         try {
             lock.getWaitQueueLength(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -673,15 +548,12 @@
      */
     public void testGetWaitingThreadsIAE() {
         final PublicReentrantLock lock = new PublicReentrantLock();
-        final Condition c = (lock.newCondition());
+        final Condition c = lock.newCondition();
         final PublicReentrantLock lock2 = new PublicReentrantLock();
         try {
             lock2.getWaitingThreads(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -689,186 +561,137 @@
      */
     public void testGetWaitingThreadsIMSE() {
         final PublicReentrantLock lock = new PublicReentrantLock();
-        final Condition c = (lock.newCondition());
+        final Condition c = lock.newCondition();
         try {
             lock.getWaitingThreads(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
-
     /**
      * hasWaiters returns true when a thread is waiting, else false
      */
-    public void testHasWaiters() {
+    public void testHasWaiters() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        threadAssertFalse(lock.hasWaiters(c));
-                        threadAssertEquals(0, lock.getWaitQueueLength(c));
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                threadAssertFalse(lock.hasWaiters(c));
+                threadAssertEquals(0, lock.getWaitQueueLength(c));
+                c.await();
+                lock.unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            assertTrue(lock.hasWaiters(c));
-            assertEquals(1, lock.getWaitQueueLength(c));
-            c.signal();
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            assertFalse(lock.hasWaiters(c));
-            assertEquals(0, lock.getWaitQueueLength(c));
-            lock.unlock();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        assertTrue(lock.hasWaiters(c));
+        assertEquals(1, lock.getWaitQueueLength(c));
+        c.signal();
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        assertFalse(lock.hasWaiters(c));
+        assertEquals(0, lock.getWaitQueueLength(c));
+        lock.unlock();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * getWaitQueueLength returns number of waiting threads
      */
-    public void testGetWaitQueueLength() {
+    public void testGetWaitQueueLength() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        threadAssertFalse(lock.hasWaiters(c));
-                        threadAssertEquals(0, lock.getWaitQueueLength(c));
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                threadAssertFalse(lock.hasWaiters(c));
+                threadAssertEquals(0, lock.getWaitQueueLength(c));
+                c.await();
+                lock.unlock();
+            }});
 
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        threadAssertTrue(lock.hasWaiters(c));
-                        threadAssertEquals(1, lock.getWaitQueueLength(c));
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                threadAssertTrue(lock.hasWaiters(c));
+                threadAssertEquals(1, lock.getWaitQueueLength(c));
+                c.await();
+                lock.unlock();
+            }});
 
-        try {
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            assertTrue(lock.hasWaiters(c));
-            assertEquals(2, lock.getWaitQueueLength(c));
-            c.signalAll();
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            assertFalse(lock.hasWaiters(c));
-            assertEquals(0, lock.getWaitQueueLength(c));
-            lock.unlock();
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        assertTrue(lock.hasWaiters(c));
+        assertEquals(2, lock.getWaitQueueLength(c));
+        c.signalAll();
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        assertFalse(lock.hasWaiters(c));
+        assertEquals(0, lock.getWaitQueueLength(c));
+        lock.unlock();
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /**
      * getWaitingThreads returns only and all waiting threads
      */
-    public void testGetWaitingThreads() {
+    public void testGetWaitingThreads() throws InterruptedException {
         final PublicReentrantLock lock = new PublicReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
+                c.await();
+                lock.unlock();
+            }});
 
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
+                c.await();
+                lock.unlock();
+            }});
 
-        try {
-            lock.lock();
-            assertTrue(lock.getWaitingThreads(c).isEmpty());
-            lock.unlock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            assertTrue(lock.hasWaiters(c));
-            assertTrue(lock.getWaitingThreads(c).contains(t1));
-            assertTrue(lock.getWaitingThreads(c).contains(t2));
-            c.signalAll();
-            lock.unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            assertFalse(lock.hasWaiters(c));
-            assertTrue(lock.getWaitingThreads(c).isEmpty());
-            lock.unlock();
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.lock();
+        assertTrue(lock.getWaitingThreads(c).isEmpty());
+        lock.unlock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        assertTrue(lock.hasWaiters(c));
+        assertTrue(lock.getWaitingThreads(c).contains(t1));
+        assertTrue(lock.getWaitingThreads(c).contains(t2));
+        c.signalAll();
+        lock.unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        assertFalse(lock.hasWaiters(c));
+        assertTrue(lock.getWaitingThreads(c).isEmpty());
+        lock.unlock();
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /** A helper class for uninterruptible wait tests */
-    class UninterruptableThread extends Thread {
+    class UninterruptibleThread extends Thread {
         private ReentrantLock lock;
         private Condition c;
 
@@ -876,7 +699,7 @@
         public volatile boolean interrupted = false;
         public volatile boolean lockStarted = false;
 
-        public UninterruptableThread(ReentrantLock lock, Condition c) {
+        public UninterruptibleThread(ReentrantLock lock, Condition c) {
             this.lock = lock;
             this.c = c;
         }
@@ -897,256 +720,180 @@
     /**
      * awaitUninterruptibly doesn't abort on interrupt
      */
-    public void testAwaitUninterruptibly() {
+    public void testAwaitUninterruptibly() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        UninterruptableThread thread = new UninterruptableThread(lock, c);
+        UninterruptibleThread thread = new UninterruptibleThread(lock, c);
 
-        try {
-            thread.start();
+        thread.start();
 
-            while (!thread.lockStarted) {
-                Thread.sleep(100);
-            }
-
-            lock.lock();
-            try {
-                thread.interrupt();
-                thread.canAwake = true;
-                c.signal();
-            } finally {
-                lock.unlock();
-            }
-
-            thread.join();
-            assertTrue(thread.interrupted);
-            assertFalse(thread.isAlive());
-        } catch (Exception ex) {
-            unexpectedException();
+        while (!thread.lockStarted) {
+            Thread.sleep(100);
         }
+
+        lock.lock();
+        try {
+            thread.interrupt();
+            thread.canAwake = true;
+            c.signal();
+        } finally {
+            lock.unlock();
+        }
+
+        thread.join();
+        assertTrue(thread.interrupted);
+        assertFalse(thread.isAlive());
     }
 
     /**
      * await is interruptible
      */
-    public void testAwait_Interrupt() {
+    public void testAwait_Interrupt() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        c.await();
-                        lock.unlock();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                c.await();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * awaitNanos is interruptible
      */
-    public void testAwaitNanos_Interrupt() {
+    public void testAwaitNanos_Interrupt() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
-                        lock.unlock();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS));
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * awaitUntil is interruptible
      */
-    public void testAwaitUntil_Interrupt() {
+    public void testAwaitUntil_Interrupt() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        java.util.Date d = new java.util.Date();
-                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
-                        lock.unlock();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                java.util.Date d = new java.util.Date();
+                c.awaitUntil(new java.util.Date(d.getTime() + 10000));
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * signalAll wakes up all threads
      */
-    public void testSignalAll() {
+    public void testSignalAll() throws InterruptedException {
         final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                c.await();
+                lock.unlock();
+            }});
 
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.lock();
-                        c.await();
-                        lock.unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                c.await();
+                lock.unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            c.signalAll();
-            lock.unlock();
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        c.signalAll();
+        lock.unlock();
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /**
      * await after multiple reentrant locking preserves lock count
      */
-    public void testAwaitLockCount() {
-	final ReentrantLock lock = new ReentrantLock();
+    public void testAwaitLockCount() throws InterruptedException {
+        final ReentrantLock lock = new ReentrantLock();
         final Condition c = lock.newCondition();
-	Thread t1 = new Thread(new Runnable() {
-		public void run() {
-		    try {
-			lock.lock();
-                        threadAssertEquals(1, lock.getHoldCount());
-                        c.await();
-                        threadAssertEquals(1, lock.getHoldCount());
-                        lock.unlock();
-		    }
-		    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-		}
-	    });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                threadAssertEquals(1, lock.getHoldCount());
+                c.await();
+                threadAssertEquals(1, lock.getHoldCount());
+                lock.unlock();
+            }});
 
-	Thread t2 = new Thread(new Runnable() {
-		public void run() {
-		    try {
-			lock.lock();
-			lock.lock();
-                        threadAssertEquals(2, lock.getHoldCount());
-                        c.await();
-                        threadAssertEquals(2, lock.getHoldCount());
-                        lock.unlock();
-                        lock.unlock();
-		    }
-		    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-		}
-	    });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                lock.lock();
+                threadAssertEquals(2, lock.getHoldCount());
+                c.await();
+                threadAssertEquals(2, lock.getHoldCount());
+                lock.unlock();
+                lock.unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.lock();
-            c.signalAll();
-            lock.unlock();
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.lock();
+        c.signalAll();
+        lock.unlock();
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /**
      * A serialized lock deserializes as unlocked
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         ReentrantLock l = new ReentrantLock();
         l.lock();
         l.unlock();
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out =
+            new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            ReentrantLock r = (ReentrantLock) in.readObject();
-            r.lock();
-            r.unlock();
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin =
+            new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in =
+            new ObjectInputStream(new BufferedInputStream(bin));
+        ReentrantLock r = (ReentrantLock) in.readObject();
+        r.lock();
+        r.unlock();
     }
 
     /**
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java
index e38165a..eb20255 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ReentrantReadWriteLockTest.java
@@ -2,22 +2,20 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.locks.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 import java.util.*;
 
 public class ReentrantReadWriteLockTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());
-    }
     public static Test suite() {
         return new TestSuite(ReentrantReadWriteLockTest.class);
     }
@@ -25,13 +23,11 @@
     /**
      * A runnable calling lockInterruptibly
      */
-    class InterruptibleLockRunnable implements Runnable {
+    class InterruptibleLockRunnable extends CheckedRunnable {
         final ReentrantReadWriteLock lock;
         InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
-        public void run() {
-            try {
-                lock.writeLock().lockInterruptibly();
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            lock.writeLock().lockInterruptibly();
         }
     }
 
@@ -40,14 +36,11 @@
      * A runnable calling lockInterruptibly that expects to be
      * interrupted
      */
-    class InterruptedLockRunnable implements Runnable {
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
         final ReentrantReadWriteLock lock;
         InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
-        public void run() {
-            try {
-                lock.writeLock().lockInterruptibly();
-                threadShouldThrow();
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            lock.writeLock().lockInterruptibly();
         }
     }
 
@@ -76,6 +69,10 @@
         assertTrue(r2.isFair());
         assertFalse(r2.isWriteLocked());
         assertEquals(0, r2.getReadLockCount());
+        ReentrantReadWriteLock r3 = new ReentrantReadWriteLock(false);
+        assertFalse(r3.isFair());
+        assertFalse(r3.isWriteLocked());
+        assertEquals(0, r3.getReadLockCount());
     }
 
     /**
@@ -86,10 +83,12 @@
         rl.writeLock().lock();
         assertTrue(rl.isWriteLocked());
         assertTrue(rl.isWriteLockedByCurrentThread());
+        assertTrue(rl.writeLock().isHeldByCurrentThread());
         assertEquals(0, rl.getReadLockCount());
         rl.writeLock().unlock();
         assertFalse(rl.isWriteLocked());
         assertFalse(rl.isWriteLockedByCurrentThread());
+        assertFalse(rl.writeLock().isHeldByCurrentThread());
         assertEquals(0, rl.getReadLockCount());
         rl.readLock().lock();
         assertFalse(rl.isWriteLocked());
@@ -110,10 +109,12 @@
         rl.writeLock().lock();
         assertTrue(rl.isWriteLocked());
         assertTrue(rl.isWriteLockedByCurrentThread());
+        assertTrue(rl.writeLock().isHeldByCurrentThread());
         assertEquals(0, rl.getReadLockCount());
         rl.writeLock().unlock();
         assertFalse(rl.isWriteLocked());
         assertFalse(rl.isWriteLockedByCurrentThread());
+        assertFalse(rl.writeLock().isHeldByCurrentThread());
         assertEquals(0, rl.getReadLockCount());
         rl.readLock().lock();
         assertFalse(rl.isWriteLocked());
@@ -129,15 +130,45 @@
      * getWriteHoldCount returns number of recursive holds
      */
     public void testGetWriteHoldCount() {
-	ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-	for(int i = 1; i <= SIZE; i++) {
-	    lock.writeLock().lock();
-	    assertEquals(i,lock.getWriteHoldCount());
-	}
-	for(int i = SIZE; i > 0; i--) {
-	    lock.writeLock().unlock();
-	    assertEquals(i-1,lock.getWriteHoldCount());
-	}
+        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        for (int i = 1; i <= SIZE; i++) {
+            lock.writeLock().lock();
+            assertEquals(i,lock.getWriteHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.writeLock().unlock();
+            assertEquals(i-1,lock.getWriteHoldCount());
+        }
+    }
+
+    /**
+     * WriteLock.getHoldCount returns number of recursive holds
+     */
+    public void testGetHoldCount() {
+        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        for (int i = 1; i <= SIZE; i++) {
+            lock.writeLock().lock();
+            assertEquals(i,lock.writeLock().getHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.writeLock().unlock();
+            assertEquals(i-1,lock.writeLock().getHoldCount());
+        }
+    }
+
+    /**
+     * getReadHoldCount returns number of recursive holds
+     */
+    public void testGetReadHoldCount() {
+        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        for (int i = 1; i <= SIZE; i++) {
+            lock.readLock().lock();
+            assertEquals(i,lock.getReadHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.readLock().unlock();
+            assertEquals(i-1,lock.getReadHoldCount());
+        }
     }
 
 
@@ -149,245 +180,196 @@
         try {
             rl.writeLock().unlock();
             shouldThrow();
-        } catch(IllegalMonitorStateException success){}
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
     /**
      * write-lockInterruptibly is interruptible
      */
-    public void testWriteLockInterruptibly_Interrupted() {
+    public void testWriteLockInterruptibly_Interrupted() throws Exception {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lockInterruptibly();
-                        lock.writeLock().unlock();
-                        lock.writeLock().lockInterruptibly();
-                        lock.writeLock().unlock();
-                    } catch(InterruptedException success){}
-                }
-            });
-        try {
-            lock.writeLock().lock();
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().unlock();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lockInterruptibly();
+                lock.writeLock().unlock();
+                lock.writeLock().lockInterruptibly();
+                lock.writeLock().unlock();
+            }});
+
+        lock.writeLock().lock();
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().unlock();
+        t.join();
     }
 
     /**
      * timed write-tryLock is interruptible
      */
-    public void testWriteTryLock_Interrupted() {
+    public void testWriteTryLock_Interrupted() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
-                    } catch(InterruptedException success){}
-                }
-            });
-        try {
-            t.start();
-            t.interrupt();
-            lock.writeLock().unlock();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().tryLock(SMALL_DELAY_MS, MILLISECONDS);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        lock.writeLock().unlock();
+        t.join();
     }
 
     /**
      * read-lockInterruptibly is interruptible
      */
-    public void testReadLockInterruptibly_Interrupted() {
+    public void testReadLockInterruptibly_Interrupted() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.readLock().lockInterruptibly();
-                    } catch(InterruptedException success){}
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().unlock();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.readLock().lockInterruptibly();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().unlock();
+        t.join();
     }
 
     /**
      * timed read-tryLock is interruptible
      */
-    public void testReadTryLock_Interrupted() {
+    public void testReadTryLock_Interrupted() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
-        try {
-            t.start();
-            t.interrupt();
-            t.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
     /**
      * write-tryLock fails if locked
      */
-    public void testWriteTryLockWhenLocked() {
+    public void testWriteTryLockWhenLocked() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertFalse(lock.writeLock().tryLock());
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.writeLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(lock.writeLock().tryLock());
+            }});
+
+        t.start();
+        t.join();
+        lock.writeLock().unlock();
     }
 
     /**
      * read-tryLock fails if locked
      */
-    public void testReadTryLockWhenLocked() {
+    public void testReadTryLockWhenLocked() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertFalse(lock.readLock().tryLock());
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.writeLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(lock.readLock().tryLock());
+            }});
+
+        t.start();
+        t.join();
+        lock.writeLock().unlock();
     }
 
     /**
      * Multiple threads can hold a read lock when not write-locked
      */
-    public void testMultipleReadLocks() {
+    public void testMultipleReadLocks() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertTrue(lock.readLock().tryLock());
-                    lock.readLock().unlock();
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.readLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertTrue(lock.readLock().tryLock());
+                lock.readLock().unlock();
+            }});
+
+        t.start();
+        t.join();
+        lock.readLock().unlock();
     }
 
     /**
      * A writelock succeeds after reading threads unlock
      */
-    public void testWriteAfterMultipleReadLocks() {
+    public void testWriteAfterMultipleReadLocks() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.readLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.readLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
     /**
      * Readlocks succeed after a writing thread unlocks
      */
-    public void testReadAfterWriteLock() {
+    public void testReadAfterWriteLock() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
     /**
      * Read trylock succeeds if write locked by current thread
      */
     public void testReadHoldingWriteLock() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-	lock.writeLock().lock();
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        lock.writeLock().lock();
         assertTrue(lock.readLock().tryLock());
         lock.readLock().unlock();
         lock.writeLock().unlock();
@@ -397,78 +379,64 @@
      * Read lock succeeds if write locked by current thread even if
      * other threads are waiting for readlock
      */
-    public void testReadHoldingWriteLock2() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-	lock.writeLock().lock();
-	Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-		}
-	    });
-	Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-		}
-	    });
+    public void testReadHoldingWriteLock2() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        lock.writeLock().lock();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
     /**
      *  Read lock succeeds if write locked by current thread even if
      * other threads are waiting for writelock
      */
-    public void testReadHoldingWriteLock3() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-	lock.writeLock().lock();
-	Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
-	Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
+    public void testReadHoldingWriteLock3() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        lock.writeLock().lock();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
 
@@ -476,39 +444,32 @@
      *  Write lock succeeds if write locked by current thread even if
      * other threads are waiting for writelock
      */
-    public void testWriteHoldingWriteLock4() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-	lock.writeLock().lock();
-	Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
-	Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
+    public void testWriteHoldingWriteLock4() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        lock.writeLock().lock();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            lock.writeLock().lock();
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            lock.writeLock().unlock();
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        lock.writeLock().lock();
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        lock.writeLock().unlock();
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
 
@@ -516,8 +477,8 @@
      * Fair Read trylock succeeds if write locked by current thread
      */
     public void testReadHoldingWriteLockFair() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-	lock.writeLock().lock();
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        lock.writeLock().lock();
         assertTrue(lock.readLock().tryLock());
         lock.readLock().unlock();
         lock.writeLock().unlock();
@@ -527,39 +488,32 @@
      * Fair Read lock succeeds if write locked by current thread even if
      * other threads are waiting for readlock
      */
-    public void testReadHoldingWriteLockFair2() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-	lock.writeLock().lock();
-	Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-		}
-	    });
-	Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.readLock().lock();
-                    lock.readLock().unlock();
-		}
-	    });
+    public void testReadHoldingWriteLockFair2() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        lock.writeLock().lock();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
 
@@ -567,39 +521,32 @@
      * Fair Read lock succeeds if write locked by current thread even if
      * other threads are waiting for writelock
      */
-    public void testReadHoldingWriteLockFair3() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-	lock.writeLock().lock();
-	Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
-	Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
+    public void testReadHoldingWriteLockFair3() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        lock.writeLock().lock();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.readLock().lock();
-            lock.readLock().unlock();
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
 
@@ -607,64 +554,53 @@
      * Fair Write lock succeeds if write locked by current thread even if
      * other threads are waiting for writelock
      */
-    public void testWriteHoldingWriteLockFair4() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-	lock.writeLock().lock();
-	Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
-	Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    lock.writeLock().lock();
-                    lock.writeLock().unlock();
-		}
-	    });
+    public void testWriteHoldingWriteLockFair4() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        lock.writeLock().lock();
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.isWriteLockedByCurrentThread());
-            assertTrue(lock.getWriteHoldCount() == 1);
-            lock.writeLock().lock();
-            assertTrue(lock.getWriteHoldCount() == 2);
-            lock.writeLock().unlock();
-            lock.writeLock().lock();
-            lock.writeLock().unlock();
-            lock.writeLock().unlock();
-            t1.join(MEDIUM_DELAY_MS);
-            t2.join(MEDIUM_DELAY_MS);
-            assertTrue(!t1.isAlive());
-            assertTrue(!t2.isAlive());
-
-        } catch(Exception e){
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.isWriteLockedByCurrentThread());
+        assertTrue(lock.getWriteHoldCount() == 1);
+        lock.writeLock().lock();
+        assertTrue(lock.getWriteHoldCount() == 2);
+        lock.writeLock().unlock();
+        lock.writeLock().lock();
+        lock.writeLock().unlock();
+        lock.writeLock().unlock();
+        t1.join(MEDIUM_DELAY_MS);
+        t2.join(MEDIUM_DELAY_MS);
+        assertTrue(!t1.isAlive());
+        assertTrue(!t2.isAlive());
     }
 
 
     /**
      * Read tryLock succeeds if readlocked but not writelocked
      */
-    public void testTryLockWhenReadLocked() {
+    public void testTryLockWhenReadLocked() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertTrue(lock.readLock().tryLock());
-                    lock.readLock().unlock();
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.readLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertTrue(lock.readLock().tryLock());
+                lock.readLock().unlock();
+            }});
+
+        t.start();
+        t.join();
+        lock.readLock().unlock();
     }
 
 
@@ -672,43 +608,35 @@
     /**
      * write tryLock fails when readlocked
      */
-    public void testWriteTryLockWhenReadLocked() {
+    public void testWriteTryLockWhenReadLocked() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.readLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertFalse(lock.writeLock().tryLock());
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.readLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(lock.writeLock().tryLock());
+            }});
+
+        t.start();
+        t.join();
+        lock.readLock().unlock();
     }
 
 
     /**
      * Fair Read tryLock succeeds if readlocked but not writelocked
      */
-    public void testTryLockWhenReadLockedFair() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-	lock.readLock().lock();
-	Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertTrue(lock.readLock().tryLock());
-                    lock.readLock().unlock();
-		}
-	    });
-        try {
-            t.start();
-            t.join();
-            lock.readLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testTryLockWhenReadLockedFair() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        lock.readLock().lock();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertTrue(lock.readLock().tryLock());
+                lock.readLock().unlock();
+            }});
+
+        t.start();
+        t.join();
+        lock.readLock().unlock();
     }
 
 
@@ -716,21 +644,17 @@
     /**
      * Fair write tryLock fails when readlocked
      */
-    public void testWriteTryLockWhenReadLockedFair() {
-	final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
-	lock.readLock().lock();
-	Thread t = new Thread(new Runnable() {
-                public void run() {
-                    threadAssertFalse(lock.writeLock().tryLock());
-		}
-	    });
-        try {
-            t.start();
-            t.join();
-            lock.readLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testWriteTryLockWhenReadLockedFair() throws InterruptedException {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        lock.readLock().lock();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertFalse(lock.writeLock().tryLock());
+            }});
+
+        t.start();
+        t.join();
+        lock.readLock().unlock();
     }
 
 
@@ -738,130 +662,85 @@
     /**
      * write timed tryLock times out if locked
      */
-    public void testWriteTryLock_Timeout() {
+    public void testWriteTryLock_Timeout() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
-                    } catch (Exception ex) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.writeLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(lock.writeLock().tryLock(1, MILLISECONDS));
+            }});
+
+        t.start();
+        t.join();
+        assertTrue(lock.writeLock().isHeldByCurrentThread());
+        lock.writeLock().unlock();
     }
 
     /**
      * read timed tryLock times out if write-locked
      */
-    public void testReadTryLock_Timeout() {
+    public void testReadTryLock_Timeout() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         lock.writeLock().lock();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
-                    } catch (Exception ex) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            t.join();
-            lock.writeLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadAssertFalse(lock.readLock().tryLock(1, MILLISECONDS));
+            }});
+
+        t.start();
+        t.join();
+        assertTrue(lock.writeLock().isHeldByCurrentThread());
+        lock.writeLock().unlock();
     }
 
 
     /**
      * write lockInterruptibly succeeds if lock free else is interruptible
      */
-    public void testWriteLockInterruptibly() {
+    public void testWriteLockInterruptibly() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        try {
-            lock.writeLock().lockInterruptibly();
-        } catch(Exception e) {
-            unexpectedException();
-        }
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lockInterruptibly();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.join();
-            lock.writeLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        lock.writeLock().lockInterruptibly();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lockInterruptibly();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.join();
+        lock.writeLock().unlock();
     }
 
     /**
      *  read lockInterruptibly succeeds if lock free else is interruptible
      */
-    public void testReadLockInterruptibly() {
+    public void testReadLockInterruptibly() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        try {
-            lock.writeLock().lockInterruptibly();
-        } catch(Exception e) {
-            unexpectedException();
-        }
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.readLock().lockInterruptibly();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-            lock.writeLock().unlock();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        lock.writeLock().lockInterruptibly();
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.readLock().lockInterruptibly();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        lock.writeLock().unlock();
     }
 
     /**
      * Calling await without holding lock throws IllegalMonitorStateException
      */
-    public void testAwait_IllegalMonitor() {
+    public void testAwait_IllegalMonitor() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         try {
             c.await();
             shouldThrow();
-        }
-        catch (IllegalMonitorStateException success) {
-        }
-        catch (Exception ex) {
-            shouldThrow();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
@@ -873,94 +752,66 @@
         try {
             c.signal();
             shouldThrow();
-        }
-        catch (IllegalMonitorStateException success) {
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
     /**
      * awaitNanos without a signal times out
      */
-    public void testAwaitNanos_Timeout() {
+    public void testAwaitNanos_Timeout() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        try {
-            lock.writeLock().lock();
-            long t = c.awaitNanos(100);
-            assertTrue(t <= 0);
-            lock.writeLock().unlock();
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+
+        lock.writeLock().lock();
+        long t = c.awaitNanos(100);
+        assertTrue(t <= 0);
+        lock.writeLock().unlock();
     }
 
 
     /**
      *  timed await without a signal times out
      */
-    public void testAwait_Timeout() {
+    public void testAwait_Timeout() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        try {
-            lock.writeLock().lock();
-            lock.writeLock().unlock();
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.writeLock().lock();
+        assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS));
+        lock.writeLock().unlock();
     }
 
     /**
      * awaitUntil without a signal times out
      */
-    public void testAwaitUntil_Timeout() {
+    public void testAwaitUntil_Timeout() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        try {
-            lock.writeLock().lock();
-            java.util.Date d = new java.util.Date();
-            lock.writeLock().unlock();
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.writeLock().lock();
+        java.util.Date d = new java.util.Date();
+        assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
+        lock.writeLock().unlock();
     }
 
     /**
      * await returns when signalled
      */
-    public void testAwait() {
+    public void testAwait() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            c.signal();
-            lock.writeLock().unlock();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        c.signal();
+        lock.writeLock().unlock();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /** A helper class for uninterruptible wait tests */
@@ -993,230 +844,167 @@
     /**
      * awaitUninterruptibly doesn't abort on interrupt
      */
-    public void testAwaitUninterruptibly() {
+    public void testAwaitUninterruptibly() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
         UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
 
-        try {
-            thread.start();
+        thread.start();
 
-            while (!thread.lockStarted) {
-                Thread.sleep(100);
-            }
-
-            lock.writeLock().lock();
-            try {
-                thread.interrupt();
-                thread.canAwake = true;
-                c.signal();
-            } finally {
-                lock.writeLock().unlock();
-            }
-
-            thread.join();
-            assertTrue(thread.interrupted);
-            assertFalse(thread.isAlive());
-        } catch (Exception ex) {
-            unexpectedException();
+        while (!thread.lockStarted) {
+            Thread.sleep(100);
         }
+
+        lock.writeLock().lock();
+        try {
+            thread.interrupt();
+            thread.canAwake = true;
+            c.signal();
+        } finally {
+            lock.writeLock().unlock();
+        }
+
+        thread.join();
+        assertTrue(thread.interrupted);
+        assertFalse(thread.isAlive());
     }
 
     /**
      * await is interruptible
      */
-    public void testAwait_Interrupt() {
+    public void testAwait_Interrupt() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        c.await();
-                        lock.writeLock().unlock();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * awaitNanos is interruptible
      */
-    public void testAwaitNanos_Interrupt() {
+    public void testAwaitNanos_Interrupt() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
-                        lock.writeLock().unlock();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS));
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * awaitUntil is interruptible
      */
-    public void testAwaitUntil_Interrupt() {
+    public void testAwaitUntil_Interrupt() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        java.util.Date d = new java.util.Date();
-                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
-                        lock.writeLock().unlock();
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                java.util.Date d = new java.util.Date();
+                c.awaitUntil(new java.util.Date(d.getTime() + 10000));
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * signalAll wakes up all threads
      */
-    public void testSignalAll() {
+    public void testSignalAll() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            c.signalAll();
-            lock.writeLock().unlock();
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t1.start();
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        c.signalAll();
+        lock.writeLock().unlock();
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /**
      * A serialized lock deserializes as unlocked
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         ReentrantReadWriteLock l = new ReentrantReadWriteLock();
         l.readLock().lock();
         l.readLock().unlock();
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
-            r.readLock().lock();
-            r.readLock().unlock();
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
+        r.readLock().lock();
+        r.readLock().unlock();
     }
 
     /**
      * hasQueuedThreads reports whether there are waiting threads
      */
-    public void testhasQueuedThreads() {
+    public void testhasQueuedThreads() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertFalse(lock.hasQueuedThreads());
-            lock.writeLock().lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(lock.hasQueuedThreads());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertFalse(lock.hasQueuedThreads());
+        lock.writeLock().lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(lock.hasQueuedThreads());
+        t1.join();
+        t2.join();
     }
 
     /**
@@ -1227,104 +1015,91 @@
         try {
             sync.hasQueuedThread(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * hasQueuedThread reports whether a thread is queued.
      */
-    public void testHasQueuedThread() {
+    public void testHasQueuedThread() throws InterruptedException {
         final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(sync));
         Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
-        try {
-            assertFalse(sync.hasQueuedThread(t1));
-            assertFalse(sync.hasQueuedThread(t2));
-            sync.writeLock().lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThread(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(sync.hasQueuedThread(t1));
-            assertTrue(sync.hasQueuedThread(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThread(t1));
-            assertTrue(sync.hasQueuedThread(t2));
-            sync.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThread(t1));
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(sync.hasQueuedThread(t2));
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertFalse(sync.hasQueuedThread(t1));
+        assertFalse(sync.hasQueuedThread(t2));
+        sync.writeLock().lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThread(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(sync.hasQueuedThread(t1));
+        assertTrue(sync.hasQueuedThread(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThread(t1));
+        assertTrue(sync.hasQueuedThread(t2));
+        sync.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThread(t1));
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(sync.hasQueuedThread(t2));
+        t1.join();
+        t2.join();
     }
 
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength() {
+    public void testGetQueueLength() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertEquals(0, lock.getQueueLength());
-            lock.writeLock().lock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(2, lock.getQueueLength());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(0, lock.getQueueLength());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertEquals(0, lock.getQueueLength());
+        lock.writeLock().lock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, lock.getQueueLength());
+        t1.join();
+        t2.join();
     }
 
     /**
      * getQueuedThreads includes waiting threads
      */
-    public void testGetQueuedThreads() {
+    public void testGetQueuedThreads() throws InterruptedException {
         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            lock.writeLock().lock();
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().contains(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().contains(t1));
-            assertTrue(lock.getQueuedThreads().contains(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(lock.getQueuedThreads().contains(t1));
-            assertTrue(lock.getQueuedThreads().contains(t2));
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        lock.writeLock().lock();
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
     }
 
     /**
@@ -1335,10 +1110,7 @@
         try {
             lock.hasWaiters(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -1349,10 +1121,7 @@
         try {
             lock.getWaitQueueLength(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
 
@@ -1364,10 +1133,7 @@
         try {
             lock.getWaitingThreads(null);
             shouldThrow();
-        } catch (NullPointerException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -1375,15 +1141,12 @@
      */
     public void testHasWaitersIAE() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
+        final Condition c = lock.writeLock().newCondition();
         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
         try {
             lock2.hasWaiters(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -1391,14 +1154,11 @@
      */
     public void testHasWaitersIMSE() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
+        final Condition c = lock.writeLock().newCondition();
         try {
             lock.hasWaiters(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -1407,15 +1167,12 @@
      */
     public void testGetWaitQueueLengthIAE() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
+        final Condition c = lock.writeLock().newCondition();
         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
         try {
             lock2.getWaitQueueLength(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -1423,14 +1180,11 @@
      */
     public void testGetWaitQueueLengthIMSE() {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
+        final Condition c = lock.writeLock().newCondition();
         try {
             lock.getWaitQueueLength(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
@@ -1439,15 +1193,12 @@
      */
     public void testGetWaitingThreadsIAE() {
         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
+        final Condition c = lock.writeLock().newCondition();
         final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();
         try {
             lock2.getWaitingThreads(c);
             shouldThrow();
-        } catch (IllegalArgumentException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -1455,163 +1206,121 @@
      */
     public void testGetWaitingThreadsIMSE() {
         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
+        final Condition c = lock.writeLock().newCondition();
         try {
             lock.getWaitingThreads(c);
             shouldThrow();
-        } catch (IllegalMonitorStateException success) {
-        } catch (Exception ex) {
-            unexpectedException();
-        }
+        } catch (IllegalMonitorStateException success) {}
     }
 
 
     /**
      * hasWaiters returns true when a thread is waiting, else false
      */
-    public void testHasWaiters() {
+    public void testHasWaiters() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        threadAssertFalse(lock.hasWaiters(c));
-                        threadAssertEquals(0, lock.getWaitQueueLength(c));
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        final Condition c = lock.writeLock().newCondition();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                threadAssertFalse(lock.hasWaiters(c));
+                threadAssertEquals(0, lock.getWaitQueueLength(c));
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            assertTrue(lock.hasWaiters(c));
-            assertEquals(1, lock.getWaitQueueLength(c));
-            c.signal();
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            assertFalse(lock.hasWaiters(c));
-            assertEquals(0, lock.getWaitQueueLength(c));
-            lock.writeLock().unlock();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        assertTrue(lock.hasWaiters(c));
+        assertEquals(1, lock.getWaitQueueLength(c));
+        c.signal();
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        assertFalse(lock.hasWaiters(c));
+        assertEquals(0, lock.getWaitQueueLength(c));
+        lock.writeLock().unlock();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
     /**
      * getWaitQueueLength returns number of waiting threads
      */
-    public void testGetWaitQueueLength() {
+    public void testGetWaitQueueLength() throws InterruptedException {
         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        final Condition c = (lock.writeLock().newCondition());
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        threadAssertFalse(lock.hasWaiters(c));
-                        threadAssertEquals(0, lock.getWaitQueueLength(c));
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        final Condition c = lock.writeLock().newCondition();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                threadAssertFalse(lock.hasWaiters(c));
+                threadAssertEquals(0, lock.getWaitQueueLength(c));
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            assertTrue(lock.hasWaiters(c));
-            assertEquals(1, lock.getWaitQueueLength(c));
-            c.signal();
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            assertFalse(lock.hasWaiters(c));
-            assertEquals(0, lock.getWaitQueueLength(c));
-            lock.writeLock().unlock();
-            t.join(SHORT_DELAY_MS);
-            assertFalse(t.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        assertTrue(lock.hasWaiters(c));
+        assertEquals(1, lock.getWaitQueueLength(c));
+        c.signal();
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        assertFalse(lock.hasWaiters(c));
+        assertEquals(0, lock.getWaitQueueLength(c));
+        lock.writeLock().unlock();
+        t.join(SHORT_DELAY_MS);
+        assertFalse(t.isAlive());
     }
 
 
     /**
      * getWaitingThreads returns only and all waiting threads
      */
-    public void testGetWaitingThreads() {
+    public void testGetWaitingThreads() throws InterruptedException {
         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
         final Condition c = lock.writeLock().newCondition();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        lock.writeLock().lock();
-                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
-                        c.await();
-                        lock.writeLock().unlock();
-                    }
-                    catch(InterruptedException e) {
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
+                c.await();
+                lock.writeLock().unlock();
+            }});
 
-        try {
-            lock.writeLock().lock();
-            assertTrue(lock.getWaitingThreads(c).isEmpty());
-            lock.writeLock().unlock();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            assertTrue(lock.hasWaiters(c));
-            assertTrue(lock.getWaitingThreads(c).contains(t1));
-            assertTrue(lock.getWaitingThreads(c).contains(t2));
-            c.signalAll();
-            lock.writeLock().unlock();
-            Thread.sleep(SHORT_DELAY_MS);
-            lock.writeLock().lock();
-            assertFalse(lock.hasWaiters(c));
-            assertTrue(lock.getWaitingThreads(c).isEmpty());
-            lock.writeLock().unlock();
-            t1.join(SHORT_DELAY_MS);
-            t2.join(SHORT_DELAY_MS);
-            assertFalse(t1.isAlive());
-            assertFalse(t2.isAlive());
-        }
-        catch (Exception ex) {
-            unexpectedException();
-        }
+        lock.writeLock().lock();
+        assertTrue(lock.getWaitingThreads(c).isEmpty());
+        lock.writeLock().unlock();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        assertTrue(lock.hasWaiters(c));
+        assertTrue(lock.getWaitingThreads(c).contains(t1));
+        assertTrue(lock.getWaitingThreads(c).contains(t2));
+        c.signalAll();
+        lock.writeLock().unlock();
+        Thread.sleep(SHORT_DELAY_MS);
+        lock.writeLock().lock();
+        assertFalse(lock.hasWaiters(c));
+        assertTrue(lock.getWaitingThreads(c).isEmpty());
+        lock.writeLock().unlock();
+        t1.join(SHORT_DELAY_MS);
+        t2.join(SHORT_DELAY_MS);
+        assertFalse(t1.isAlive());
+        assertFalse(t2.isAlive());
     }
 
     /**
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorSubclassTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorSubclassTest.java
new file mode 100644
index 0000000..21f4ced
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorSubclassTest.java
@@ -0,0 +1,1060 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import junit.framework.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.atomic.*;
+
+public class ScheduledExecutorSubclassTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ScheduledExecutorSubclassTest.class);
+    }
+
+    static class CustomTask<V> implements RunnableScheduledFuture<V> {
+        RunnableScheduledFuture<V> task;
+        volatile boolean ran;
+        CustomTask(RunnableScheduledFuture<V> t) { task = t; }
+        public boolean isPeriodic() { return task.isPeriodic(); }
+        public void run() {
+            ran = true;
+            task.run();
+        }
+        public long getDelay(TimeUnit unit) { return task.getDelay(unit); }
+        public int compareTo(Delayed t) {
+            return task.compareTo(((CustomTask)t).task);
+        }
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return task.cancel(mayInterruptIfRunning);
+        }
+        public boolean isCancelled() { return task.isCancelled(); }
+        public boolean isDone() { return task.isDone(); }
+        public V get() throws InterruptedException,  ExecutionException {
+            V v = task.get();
+            assertTrue(ran);
+            return v;
+        }
+        public V get(long time, TimeUnit unit) throws InterruptedException,  ExecutionException, TimeoutException {
+            V v = task.get(time, unit);
+            assertTrue(ran);
+            return v;
+        }
+    }
+
+
+    public class CustomExecutor extends ScheduledThreadPoolExecutor {
+
+        protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) {
+            return new CustomTask<V>(task);
+        }
+
+        protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) {
+            return new CustomTask<V>(task);
+        }
+        CustomExecutor(int corePoolSize) { super(corePoolSize);}
+        CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) {
+            super(corePoolSize, handler);
+        }
+
+        CustomExecutor(int corePoolSize, ThreadFactory threadFactory) {
+            super(corePoolSize, threadFactory);
+        }
+        CustomExecutor(int corePoolSize, ThreadFactory threadFactory,
+                       RejectedExecutionHandler handler) {
+            super(corePoolSize, threadFactory, handler);
+        }
+
+    }
+
+
+    /**
+     * execute successfully executes a runnable
+     */
+    public void testExecute() throws InterruptedException {
+        TrackedShortRunnable runnable =new TrackedShortRunnable();
+        CustomExecutor p1 = new CustomExecutor(1);
+        p1.execute(runnable);
+        assertFalse(runnable.done);
+        Thread.sleep(SHORT_DELAY_MS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p1);
+    }
+
+
+    /**
+     * delayed schedule of callable successfully executes after delay
+     */
+    public void testSchedule1() throws Exception {
+        TrackedCallable callable = new TrackedCallable();
+        CustomExecutor p1 = new CustomExecutor(1);
+        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(callable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(callable.done);
+        assertEquals(Boolean.TRUE, f.get());
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p1);
+    }
+
+    /**
+     *  delayed schedule of runnable successfully executes after delay
+     */
+    public void testSchedule3() throws InterruptedException {
+        TrackedShortRunnable runnable = new TrackedShortRunnable();
+        CustomExecutor p1 = new CustomExecutor(1);
+        p1.schedule(runnable, SMALL_DELAY_MS, MILLISECONDS);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(runnable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p1);
+    }
+
+    /**
+     * scheduleAtFixedRate executes runnable after given initial delay
+     */
+    public void testSchedule4() throws InterruptedException {
+        TrackedShortRunnable runnable = new TrackedShortRunnable();
+        CustomExecutor p1 = new CustomExecutor(1);
+        ScheduledFuture h = p1.scheduleAtFixedRate(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(runnable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        h.cancel(true);
+        joinPool(p1);
+    }
+
+    static class RunnableCounter implements Runnable {
+        AtomicInteger count = new AtomicInteger(0);
+        public void run() { count.getAndIncrement(); }
+    }
+
+    /**
+     * scheduleWithFixedDelay executes runnable after given initial delay
+     */
+    public void testSchedule5() throws InterruptedException {
+        TrackedShortRunnable runnable = new TrackedShortRunnable();
+        CustomExecutor p1 = new CustomExecutor(1);
+        ScheduledFuture h = p1.scheduleWithFixedDelay(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(runnable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        h.cancel(true);
+        joinPool(p1);
+    }
+
+    /**
+     * scheduleAtFixedRate executes series of tasks at given rate
+     */
+    public void testFixedRateSequence() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        RunnableCounter counter = new RunnableCounter();
+        ScheduledFuture h =
+            p1.scheduleAtFixedRate(counter, 0, 1, MILLISECONDS);
+        Thread.sleep(SMALL_DELAY_MS);
+        h.cancel(true);
+        int c = counter.count.get();
+        // By time scaling conventions, we must have at least
+        // an execution per SHORT delay, but no more than one SHORT more
+        assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+        assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+        joinPool(p1);
+    }
+
+    /**
+     * scheduleWithFixedDelay executes series of tasks with given period
+     */
+    public void testFixedDelaySequence() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        RunnableCounter counter = new RunnableCounter();
+        ScheduledFuture h =
+            p1.scheduleWithFixedDelay(counter, 0, 1, MILLISECONDS);
+        Thread.sleep(SMALL_DELAY_MS);
+        h.cancel(true);
+        int c = counter.count.get();
+        assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+        assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+        joinPool(p1);
+    }
+
+
+    /**
+     *  execute (null) throws NPE
+     */
+    public void testExecuteNull() throws InterruptedException {
+        CustomExecutor se = new CustomExecutor(1);
+        try {
+            se.execute(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+        joinPool(se);
+    }
+
+    /**
+     * schedule (null) throws NPE
+     */
+    public void testScheduleNull() throws InterruptedException {
+        CustomExecutor se = new CustomExecutor(1);
+        try {
+            TrackedCallable callable = null;
+            Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+        joinPool(se);
+    }
+
+    /**
+     * execute throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule1_RejectedExecutionException() {
+        CustomExecutor se = new CustomExecutor(1);
+        try {
+            se.shutdown();
+            se.schedule(new NoOpRunnable(),
+                        MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (RejectedExecutionException success) {
+        } catch (SecurityException ok) {
+        }
+
+        joinPool(se);
+    }
+
+    /**
+     * schedule throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule2_RejectedExecutionException() {
+        CustomExecutor se = new CustomExecutor(1);
+        try {
+            se.shutdown();
+            se.schedule(new NoOpCallable(),
+                        MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (RejectedExecutionException success) {
+        } catch (SecurityException ok) {
+        }
+        joinPool(se);
+    }
+
+    /**
+     * schedule callable throws RejectedExecutionException if shutdown
+     */
+     public void testSchedule3_RejectedExecutionException() {
+         CustomExecutor se = new CustomExecutor(1);
+         try {
+             se.shutdown();
+             se.schedule(new NoOpCallable(),
+                         MEDIUM_DELAY_MS, MILLISECONDS);
+             shouldThrow();
+         } catch (RejectedExecutionException success) {
+         } catch (SecurityException ok) {
+         }
+         joinPool(se);
+    }
+
+    /**
+     *  scheduleAtFixedRate throws RejectedExecutionException if shutdown
+     */
+    public void testScheduleAtFixedRate1_RejectedExecutionException() {
+        CustomExecutor se = new CustomExecutor(1);
+        try {
+            se.shutdown();
+            se.scheduleAtFixedRate(new NoOpRunnable(),
+                                   MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (RejectedExecutionException success) {
+        } catch (SecurityException ok) {
+        }
+        joinPool(se);
+    }
+
+    /**
+     * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
+     */
+    public void testScheduleWithFixedDelay1_RejectedExecutionException() {
+        CustomExecutor se = new CustomExecutor(1);
+        try {
+            se.shutdown();
+            se.scheduleWithFixedDelay(new NoOpRunnable(),
+                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (RejectedExecutionException success) {
+        } catch (SecurityException ok) {
+        }
+        joinPool(se);
+    }
+
+    /**
+     *  getActiveCount increases but doesn't overestimate, when a
+     *  thread becomes active
+     */
+    public void testGetActiveCount() throws InterruptedException {
+        CustomExecutor p2 = new CustomExecutor(2);
+        assertEquals(0, p2.getActiveCount());
+        p2.execute(new SmallRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, p2.getActiveCount());
+        joinPool(p2);
+    }
+
+    /**
+     *    getCompletedTaskCount increases, but doesn't overestimate,
+     *   when tasks complete
+     */
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        CustomExecutor p2 = new CustomExecutor(2);
+        assertEquals(0, p2.getCompletedTaskCount());
+        p2.execute(new SmallRunnable());
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertEquals(1, p2.getCompletedTaskCount());
+        joinPool(p2);
+    }
+
+    /**
+     *  getCorePoolSize returns size given in constructor if not otherwise set
+     */
+    public void testGetCorePoolSize() {
+        CustomExecutor p1 = new CustomExecutor(1);
+        assertEquals(1, p1.getCorePoolSize());
+        joinPool(p1);
+    }
+
+    /**
+     *    getLargestPoolSize increases, but doesn't overestimate, when
+     *   multiple threads active
+     */
+    public void testGetLargestPoolSize() throws InterruptedException {
+        CustomExecutor p2 = new CustomExecutor(2);
+        assertEquals(0, p2.getLargestPoolSize());
+        p2.execute(new SmallRunnable());
+        p2.execute(new SmallRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, p2.getLargestPoolSize());
+        joinPool(p2);
+    }
+
+    /**
+     *   getPoolSize increases, but doesn't overestimate, when threads
+     *   become active
+     */
+    public void testGetPoolSize() {
+        CustomExecutor p1 = new CustomExecutor(1);
+        assertEquals(0, p1.getPoolSize());
+        p1.execute(new SmallRunnable());
+        assertEquals(1, p1.getPoolSize());
+        joinPool(p1);
+    }
+
+    /**
+     *    getTaskCount increases, but doesn't overestimate, when tasks
+     *    submitted
+     */
+    public void testGetTaskCount() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        assertEquals(0, p1.getTaskCount());
+        for (int i = 0; i < 5; i++)
+            p1.execute(new SmallRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(5, p1.getTaskCount());
+        joinPool(p1);
+    }
+
+    /**
+     * getThreadFactory returns factory in constructor if not set
+     */
+    public void testGetThreadFactory() {
+        ThreadFactory tf = new SimpleThreadFactory();
+        CustomExecutor p = new CustomExecutor(1, tf);
+        assertSame(tf, p.getThreadFactory());
+        joinPool(p);
+    }
+
+    /**
+     * setThreadFactory sets the thread factory returned by getThreadFactory
+     */
+    public void testSetThreadFactory() {
+        ThreadFactory tf = new SimpleThreadFactory();
+        CustomExecutor p = new CustomExecutor(1);
+        p.setThreadFactory(tf);
+        assertSame(tf, p.getThreadFactory());
+        joinPool(p);
+    }
+
+    /**
+     * setThreadFactory(null) throws NPE
+     */
+    public void testSetThreadFactoryNull() {
+        CustomExecutor p = new CustomExecutor(1);
+        try {
+            p.setThreadFactory(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(p);
+        }
+    }
+
+    /**
+     *   is isShutDown is false before shutdown, true after
+     */
+    public void testIsShutdown() {
+        CustomExecutor p1 = new CustomExecutor(1);
+        try {
+            assertFalse(p1.isShutdown());
+        }
+        finally {
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        assertTrue(p1.isShutdown());
+    }
+
+
+    /**
+     *  isTerminated is false before termination, true after
+     */
+    public void testIsTerminated() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        try {
+            p1.execute(new SmallRunnable());
+        } finally {
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
+    }
+
+    /**
+     *  isTerminating is not true when running or when terminated
+     */
+    public void testIsTerminating() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        assertFalse(p1.isTerminating());
+        try {
+            p1.execute(new SmallRunnable());
+            assertFalse(p1.isTerminating());
+        } finally {
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
+        assertFalse(p1.isTerminating());
+    }
+
+    /**
+     * getQueue returns the work queue, which contains queued tasks
+     */
+    public void testGetQueue() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, MILLISECONDS);
+        }
+        try {
+            Thread.sleep(SHORT_DELAY_MS);
+            BlockingQueue<Runnable> q = p1.getQueue();
+            assertTrue(q.contains(tasks[4]));
+            assertFalse(q.contains(tasks[0]));
+        } finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     * remove(task) removes queued task, and fails to remove active task
+     */
+    public void testRemove() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, MILLISECONDS);
+        }
+        try {
+            Thread.sleep(SHORT_DELAY_MS);
+            BlockingQueue<Runnable> q = p1.getQueue();
+            assertFalse(p1.remove((Runnable)tasks[0]));
+            assertTrue(q.contains((Runnable)tasks[4]));
+            assertTrue(q.contains((Runnable)tasks[3]));
+            assertTrue(p1.remove((Runnable)tasks[4]));
+            assertFalse(p1.remove((Runnable)tasks[4]));
+            assertFalse(q.contains((Runnable)tasks[4]));
+            assertTrue(q.contains((Runnable)tasks[3]));
+            assertTrue(p1.remove((Runnable)tasks[3]));
+            assertFalse(q.contains((Runnable)tasks[3]));
+        } finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     *  purge removes cancelled tasks from the queue
+     */
+    public void testPurge() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, MILLISECONDS);
+        }
+        try {
+            int max = 5;
+            if (tasks[4].cancel(true)) --max;
+            if (tasks[3].cancel(true)) --max;
+            // There must eventually be an interference-free point at
+            // which purge will not fail. (At worst, when queue is empty.)
+            int k;
+            for (k = 0; k < SMALL_DELAY_MS; ++k) {
+                p1.purge();
+                long count = p1.getTaskCount();
+                if (count >= 0 && count <= max)
+                    break;
+                Thread.sleep(1);
+            }
+            assertTrue(k < SMALL_DELAY_MS);
+        } finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     *  shutDownNow returns a list containing tasks that were not run
+     */
+    public void testShutDownNow() {
+        CustomExecutor p1 = new CustomExecutor(1);
+        for (int i = 0; i < 5; i++)
+            p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, MILLISECONDS);
+        List l;
+        try {
+            l = p1.shutdownNow();
+        } catch (SecurityException ok) {
+            return;
+        }
+        assertTrue(p1.isShutdown());
+        assertTrue(l.size() > 0 && l.size() <= 5);
+        joinPool(p1);
+    }
+
+    /**
+     * In default setting, shutdown cancels periodic but not delayed
+     * tasks at shutdown
+     */
+    public void testShutDown1() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        assertTrue(p1.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+        assertFalse(p1.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++)
+            tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, MILLISECONDS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        BlockingQueue q = p1.getQueue();
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            ScheduledFuture t = (ScheduledFuture)it.next();
+            assertFalse(t.isCancelled());
+        }
+        assertTrue(p1.isShutdown());
+        Thread.sleep(SMALL_DELAY_MS);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(tasks[i].isDone());
+            assertFalse(tasks[i].isCancelled());
+        }
+    }
+
+
+    /**
+     * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
+     * delayed tasks are cancelled at shutdown
+     */
+    public void testShutDown2() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        p1.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++)
+            tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, MILLISECONDS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p1.isShutdown());
+        BlockingQueue q = p1.getQueue();
+        assertTrue(q.isEmpty());
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(p1.isTerminated());
+    }
+
+
+    /**
+     * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
+     * periodic tasks are not cancelled at shutdown
+     */
+    public void testShutDown3() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+        ScheduledFuture task =
+            p1.scheduleAtFixedRate(new NoOpRunnable(), 5, 5, MILLISECONDS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p1.isShutdown());
+        BlockingQueue q = p1.getQueue();
+        assertTrue(q.isEmpty());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(p1.isTerminated());
+    }
+
+    /**
+     * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
+     * periodic tasks are cancelled at shutdown
+     */
+    public void testShutDown4() throws InterruptedException {
+        CustomExecutor p1 = new CustomExecutor(1);
+        try {
+            p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
+            ScheduledFuture task =
+                p1.scheduleAtFixedRate(new NoOpRunnable(), 1, 1, MILLISECONDS);
+            assertFalse(task.isCancelled());
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
+            assertFalse(task.isCancelled());
+            assertFalse(p1.isTerminated());
+            assertTrue(p1.isShutdown());
+            Thread.sleep(SHORT_DELAY_MS);
+            assertFalse(task.isCancelled());
+            assertTrue(task.cancel(true));
+            assertTrue(task.isDone());
+            Thread.sleep(SHORT_DELAY_MS);
+            assertTrue(p1.isTerminated());
+        }
+        finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     * completed submit of callable returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            Future<String> future = e.submit(new StringTask());
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * completed submit of runnable returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            Future<?> future = e.submit(new NoOpRunnable());
+            future.get();
+            assertTrue(future.isDone());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * completed submit of (runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            e.invokeAny(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            e.invokeAny(new ArrayList<Callable<String>>());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
+        try {
+            e.invokeAny(l);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            latch.countDown();
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testInvokeAny4() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        try {
+            e.invokeAny(l);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task
+     */
+    public void testInvokeAny5() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            e.invokeAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
+        try {
+            e.invokeAll(l);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * get of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures = e.invokeAll(l);
+        assertEquals(1, futures.size());
+        try {
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks
+     */
+    public void testInvokeAll5() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(,,null) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        try {
+            e.invokeAny(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
+        try {
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            latch.countDown();
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        try {
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(,,null) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        try {
+            e.invokeAll(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
+        try {
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures =
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+        assertEquals(1, futures.size());
+        try {
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(c) cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        ExecutorService e = new CustomExecutor(2);
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+            assertEquals(3, futures.size());
+            Iterator<Future<String>> it = futures.iterator();
+            Future<String> f1 = it.next();
+            Future<String> f2 = it.next();
+            Future<String> f3 = it.next();
+            assertTrue(f1.isDone());
+            assertTrue(f2.isDone());
+            assertTrue(f3.isDone());
+            assertFalse(f1.isCancelled());
+            assertTrue(f2.isCancelled());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java
index da5704e..ff1796e 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ScheduledExecutorTest.java
@@ -2,21 +2,19 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.concurrent.atomic.*;
 
 public class ScheduledExecutorTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(ScheduledExecutorTest.class);
     }
@@ -25,86 +23,62 @@
     /**
      * execute successfully executes a runnable
      */
-    public void testExecute() {
-        try {
-            TrackedShortRunnable runnable =new TrackedShortRunnable();
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            p1.execute(runnable);
-            assertFalse(runnable.done);
-            Thread.sleep(SHORT_DELAY_MS);
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            try {
-                Thread.sleep(MEDIUM_DELAY_MS);
-            } catch(InterruptedException e){
-                unexpectedException();
-            }
-            assertTrue(runnable.done);
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            joinPool(p1);
-        }
-        catch(Exception e){
-            unexpectedException();
-        }
-        
+    public void testExecute() throws InterruptedException {
+        TrackedShortRunnable runnable =new TrackedShortRunnable();
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        p1.execute(runnable);
+        assertFalse(runnable.done);
+        Thread.sleep(SHORT_DELAY_MS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p1);
     }
 
 
     /**
      * delayed schedule of callable successfully executes after delay
      */
-    public void testSchedule1() {
-        try {
-            TrackedCallable callable = new TrackedCallable();
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertFalse(callable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(callable.done);
-            assertEquals(Boolean.TRUE, f.get());
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            joinPool(p1);
-        } catch(RejectedExecutionException e){}
-        catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+    public void testSchedule1() throws Exception {
+        TrackedCallable callable = new TrackedCallable();
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(callable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(callable.done);
+        assertEquals(Boolean.TRUE, f.get());
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p1);
     }
 
     /**
      *  delayed schedule of runnable successfully executes after delay
      */
-    public void testSchedule3() {
-        try {
-            TrackedShortRunnable runnable = new TrackedShortRunnable();
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            p1.schedule(runnable, SMALL_DELAY_MS, TimeUnit.MILLISECONDS);
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(runnable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(runnable.done);
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            joinPool(p1);
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testSchedule3() throws InterruptedException {
+        TrackedShortRunnable runnable = new TrackedShortRunnable();
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        p1.schedule(runnable, SMALL_DELAY_MS, MILLISECONDS);
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(runnable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p1);
     }
-    
+
     /**
      * scheduleAtFixedRate executes runnable after given initial delay
      */
-    public void testSchedule4() {
-        try {
-            TrackedShortRunnable runnable = new TrackedShortRunnable();
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            ScheduledFuture h = p1.scheduleAtFixedRate(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertFalse(runnable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(runnable.done);
-            h.cancel(true);
-            joinPool(p1);
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testSchedule4() throws InterruptedException {
+        TrackedShortRunnable runnable = new TrackedShortRunnable();
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        ScheduledFuture h = p1.scheduleAtFixedRate(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(runnable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        h.cancel(true);
+        joinPool(p1);
     }
 
     static class RunnableCounter implements Runnable {
@@ -115,126 +89,107 @@
     /**
      * scheduleWithFixedDelay executes runnable after given initial delay
      */
-    public void testSchedule5() {
-        try {
-            TrackedShortRunnable runnable = new TrackedShortRunnable();
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            ScheduledFuture h = p1.scheduleWithFixedDelay(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertFalse(runnable.done);
-            Thread.sleep(MEDIUM_DELAY_MS);
-            assertTrue(runnable.done);
-            h.cancel(true);
-            joinPool(p1);
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testSchedule5() throws InterruptedException {
+        TrackedShortRunnable runnable = new TrackedShortRunnable();
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        ScheduledFuture h = p1.scheduleWithFixedDelay(runnable, SHORT_DELAY_MS, SHORT_DELAY_MS, MILLISECONDS);
+        assertFalse(runnable.done);
+        Thread.sleep(MEDIUM_DELAY_MS);
+        assertTrue(runnable.done);
+        h.cancel(true);
+        joinPool(p1);
     }
-    
+
     /**
      * scheduleAtFixedRate executes series of tasks at given rate
      */
-    public void testFixedRateSequence() {
-        try {
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            RunnableCounter counter = new RunnableCounter();
-            ScheduledFuture h = 
-                p1.scheduleAtFixedRate(counter, 0, 1, TimeUnit.MILLISECONDS);
-            Thread.sleep(SMALL_DELAY_MS);
-            h.cancel(true);
-            int c = counter.count.get();
-            // By time scaling conventions, we must have at least
-            // an execution per SHORT delay, but no more than one SHORT more
-            assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
-            assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
-            joinPool(p1);
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testFixedRateSequence() throws InterruptedException {
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        RunnableCounter counter = new RunnableCounter();
+        ScheduledFuture h =
+            p1.scheduleAtFixedRate(counter, 0, 1, MILLISECONDS);
+        Thread.sleep(SMALL_DELAY_MS);
+        h.cancel(true);
+        int c = counter.count.get();
+        // By time scaling conventions, we must have at least
+        // an execution per SHORT delay, but no more than one SHORT more
+        assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+        assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+        joinPool(p1);
     }
 
     /**
      * scheduleWithFixedDelay executes series of tasks with given period
      */
-    public void testFixedDelaySequence() {
-        try {
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            RunnableCounter counter = new RunnableCounter();
-            ScheduledFuture h = 
-                p1.scheduleWithFixedDelay(counter, 0, 1, TimeUnit.MILLISECONDS);
-            Thread.sleep(SMALL_DELAY_MS);
-            h.cancel(true);
-            int c = counter.count.get();
-            assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
-            assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
-            joinPool(p1);
-        } catch(Exception e){
-            unexpectedException();
-        }
+    public void testFixedDelaySequence() throws InterruptedException {
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        RunnableCounter counter = new RunnableCounter();
+        ScheduledFuture h =
+            p1.scheduleWithFixedDelay(counter, 0, 1, MILLISECONDS);
+        Thread.sleep(SMALL_DELAY_MS);
+        h.cancel(true);
+        int c = counter.count.get();
+        assertTrue(c >= SMALL_DELAY_MS / SHORT_DELAY_MS);
+        assertTrue(c <= SMALL_DELAY_MS + SHORT_DELAY_MS);
+        joinPool(p1);
     }
 
 
     /**
      *  execute (null) throws NPE
      */
-    public void testExecuteNull() {
+    public void testExecuteNull() throws InterruptedException {
         ScheduledThreadPoolExecutor se = null;
         try {
             se = new ScheduledThreadPoolExecutor(1);
             se.execute(null);
             shouldThrow();
-        } catch(NullPointerException success){}
-        catch(Exception e){
-            unexpectedException();
-        }
-        
+        } catch (NullPointerException success) {}
+
         joinPool(se);
     }
 
     /**
      * schedule (null) throws NPE
      */
-    public void testScheduleNull() {
+    public void testScheduleNull() throws InterruptedException {
         ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
         try {
             TrackedCallable callable = null;
-            Future f = se.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
+            Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(NullPointerException success){}
-        catch(Exception e){
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
         joinPool(se);
     }
-   
+
     /**
      * execute throws RejectedExecutionException if shutdown
      */
-    public void testSchedule1_RejectedExecutionException() {
+    public void testSchedule1_RejectedExecutionException() throws InterruptedException {
         ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
         try {
             se.shutdown();
             se.schedule(new NoOpRunnable(),
-                        MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+                        MEDIUM_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(RejectedExecutionException success){
+        } catch (RejectedExecutionException success) {
         } catch (SecurityException ok) {
         }
-        
-        joinPool(se);
 
+        joinPool(se);
     }
 
     /**
      * schedule throws RejectedExecutionException if shutdown
      */
-    public void testSchedule2_RejectedExecutionException() {
+    public void testSchedule2_RejectedExecutionException() throws InterruptedException {
         ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
         try {
             se.shutdown();
             se.schedule(new NoOpCallable(),
-                        MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+                        MEDIUM_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(RejectedExecutionException success){
+        } catch (RejectedExecutionException success) {
         } catch (SecurityException ok) {
         }
         joinPool(se);
@@ -243,14 +198,14 @@
     /**
      * schedule callable throws RejectedExecutionException if shutdown
      */
-     public void testSchedule3_RejectedExecutionException() {
+     public void testSchedule3_RejectedExecutionException() throws InterruptedException {
          ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
          try {
             se.shutdown();
             se.schedule(new NoOpCallable(),
-                        MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+                        MEDIUM_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(RejectedExecutionException success){
+        } catch (RejectedExecutionException success) {
         } catch (SecurityException ok) {
         }
          joinPool(se);
@@ -259,32 +214,32 @@
     /**
      *  scheduleAtFixedRate throws RejectedExecutionException if shutdown
      */
-    public void testScheduleAtFixedRate1_RejectedExecutionException() {
+    public void testScheduleAtFixedRate1_RejectedExecutionException() throws InterruptedException {
         ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
         try {
             se.shutdown();
             se.scheduleAtFixedRate(new NoOpRunnable(),
-                                   MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+                                   MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(RejectedExecutionException success){
+        } catch (RejectedExecutionException success) {
         } catch (SecurityException ok) {
-        } 
+        }
         joinPool(se);
     }
-    
+
     /**
      * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
      */
-    public void testScheduleWithFixedDelay1_RejectedExecutionException() {
+    public void testScheduleWithFixedDelay1_RejectedExecutionException() throws InterruptedException {
         ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(1);
         try {
             se.shutdown();
             se.scheduleWithFixedDelay(new NoOpRunnable(),
-                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
             shouldThrow();
-        } catch(RejectedExecutionException success){
+        } catch (RejectedExecutionException success) {
         } catch (SecurityException ok) {
-        } 
+        }
         joinPool(se);
     }
 
@@ -292,107 +247,91 @@
      *  getActiveCount increases but doesn't overestimate, when a
      *  thread becomes active
      */
-    public void testGetActiveCount() {
+    public void testGetActiveCount() throws InterruptedException {
         ScheduledThreadPoolExecutor p2 = new ScheduledThreadPoolExecutor(2);
         assertEquals(0, p2.getActiveCount());
         p2.execute(new SmallRunnable());
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
         assertEquals(1, p2.getActiveCount());
         joinPool(p2);
     }
-    
+
     /**
      *    getCompletedTaskCount increases, but doesn't overestimate,
      *   when tasks complete
      */
-    public void testGetCompletedTaskCount() {
+    public void testGetCompletedTaskCount() throws InterruptedException {
         ScheduledThreadPoolExecutor p2 = new ScheduledThreadPoolExecutor(2);
         assertEquals(0, p2.getCompletedTaskCount());
         p2.execute(new SmallRunnable());
-        try {
-            Thread.sleep(MEDIUM_DELAY_MS);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread.sleep(MEDIUM_DELAY_MS);
         assertEquals(1, p2.getCompletedTaskCount());
         joinPool(p2);
     }
-    
+
     /**
-     *  getCorePoolSize returns size given in constructor if not otherwise set 
+     *  getCorePoolSize returns size given in constructor if not otherwise set
      */
-    public void testGetCorePoolSize() {
+    public void testGetCorePoolSize() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         assertEquals(1, p1.getCorePoolSize());
         joinPool(p1);
     }
-    
+
     /**
      *    getLargestPoolSize increases, but doesn't overestimate, when
      *   multiple threads active
      */
-    public void testGetLargestPoolSize() {
+    public void testGetLargestPoolSize() throws InterruptedException {
         ScheduledThreadPoolExecutor p2 = new ScheduledThreadPoolExecutor(2);
         assertEquals(0, p2.getLargestPoolSize());
         p2.execute(new SmallRunnable());
         p2.execute(new SmallRunnable());
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
         assertEquals(2, p2.getLargestPoolSize());
         joinPool(p2);
     }
-    
+
     /**
      *   getPoolSize increases, but doesn't overestimate, when threads
      *   become active
      */
-    public void testGetPoolSize() {
+    public void testGetPoolSize() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         assertEquals(0, p1.getPoolSize());
         p1.execute(new SmallRunnable());
         assertEquals(1, p1.getPoolSize());
         joinPool(p1);
     }
-    
+
     /**
      *    getTaskCount increases, but doesn't overestimate, when tasks
      *    submitted
      */
-    public void testGetTaskCount() {
+    public void testGetTaskCount() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         assertEquals(0, p1.getTaskCount());
-        for(int i = 0; i < 5; i++)
+        for (int i = 0; i < 5; i++)
             p1.execute(new SmallRunnable());
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
         assertEquals(5, p1.getTaskCount());
         joinPool(p1);
     }
 
-    /** 
+    /**
      * getThreadFactory returns factory in constructor if not set
      */
-    public void testGetThreadFactory() {
+    public void testGetThreadFactory() throws InterruptedException {
         ThreadFactory tf = new SimpleThreadFactory();
         ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1, tf);
         assertSame(tf, p.getThreadFactory());
         joinPool(p);
     }
 
-    /** 
+    /**
      * setThreadFactory sets the thread factory returned by getThreadFactory
      */
-    public void testSetThreadFactory() {
+    public void testSetThreadFactory() throws InterruptedException {
         ThreadFactory tf = new SimpleThreadFactory();
         ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
         p.setThreadFactory(tf);
@@ -400,10 +339,10 @@
         joinPool(p);
     }
 
-    /** 
+    /**
      * setThreadFactory(null) throws NPE
      */
-    public void testSetThreadFactoryNull() {
+    public void testSetThreadFactoryNull() throws InterruptedException {
         ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
         try {
             p.setThreadFactory(null);
@@ -413,78 +352,69 @@
             joinPool(p);
         }
     }
-    
+
     /**
      *   is isShutDown is false before shutdown, true after
      */
     public void testIsShutdown() {
-        
+
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         try {
             assertFalse(p1.isShutdown());
         }
         finally {
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
         }
         assertTrue(p1.isShutdown());
     }
 
-        
+
     /**
      *   isTerminated is false before termination, true after
      */
-    public void testIsTerminated() {
+    public void testIsTerminated() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         try {
             p1.execute(new SmallRunnable());
         } finally {
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
         }
-        try {
-            assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-            assertTrue(p1.isTerminated());
-        } catch(Exception e){
-            unexpectedException();
-        }        
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
     }
 
     /**
      *  isTerminating is not true when running or when terminated
      */
-    public void testIsTerminating() {
+    public void testIsTerminating() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         assertFalse(p1.isTerminating());
         try {
             p1.execute(new SmallRunnable());
             assertFalse(p1.isTerminating());
         } finally {
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
         }
-        try {
-            assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-            assertTrue(p1.isTerminated());
-            assertFalse(p1.isTerminating());
-        } catch(Exception e){
-            unexpectedException();
-        }        
+
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
+        assertFalse(p1.isTerminating());
     }
 
     /**
      * getQueue returns the work queue, which contains queued tasks
      */
-    public void testGetQueue() {
+    public void testGetQueue() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for(int i = 0; i < 5; i++){
-            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, TimeUnit.MILLISECONDS);
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, MILLISECONDS);
         }
         try {
             Thread.sleep(SHORT_DELAY_MS);
             BlockingQueue<Runnable> q = p1.getQueue();
             assertTrue(q.contains(tasks[4]));
             assertFalse(q.contains(tasks[0]));
-        } catch(Exception e) {
-            unexpectedException();
         } finally {
             joinPool(p1);
         }
@@ -493,11 +423,11 @@
     /**
      * remove(task) removes queued task, and fails to remove active task
      */
-    public void testRemove() {
+    public void testRemove() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for(int i = 0; i < 5; i++){
-            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, TimeUnit.MILLISECONDS);
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), 1, MILLISECONDS);
         }
         try {
             Thread.sleep(SHORT_DELAY_MS);
@@ -511,8 +441,6 @@
             assertTrue(q.contains((Runnable)tasks[3]));
             assertTrue(p1.remove((Runnable)tasks[3]));
             assertFalse(q.contains((Runnable)tasks[3]));
-        } catch(Exception e) {
-            unexpectedException();
         } finally {
             joinPool(p1);
         }
@@ -521,11 +449,11 @@
     /**
      *  purge removes cancelled tasks from the queue
      */
-    public void testPurge() {
+    public void testPurge() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         ScheduledFuture[] tasks = new ScheduledFuture[5];
-        for(int i = 0; i < 5; i++){
-            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, MILLISECONDS);
         }
         try {
             int max = 5;
@@ -542,8 +470,6 @@
                 Thread.sleep(1);
             }
             assertTrue(k < SMALL_DELAY_MS);
-        } catch(Exception e) {
-            unexpectedException();
         } finally {
             joinPool(p1);
         }
@@ -552,14 +478,14 @@
     /**
      *  shutDownNow returns a list containing tasks that were not run
      */
-    public void testShutDownNow() {
+    public void testShutDownNow() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-        for(int i = 0; i < 5; i++)
-            p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
+        for (int i = 0; i < 5; i++)
+            p1.schedule(new SmallPossiblyInterruptedRunnable(), SHORT_DELAY_MS, MILLISECONDS);
         List l;
         try {
             l = p1.shutdownNow();
-        } catch (SecurityException ok) { 
+        } catch (SecurityException ok) {
             return;
         }
         assertTrue(p1.isShutdown());
@@ -571,31 +497,25 @@
      * In default setting, shutdown cancels periodic but not delayed
      * tasks at shutdown
      */
-    public void testShutDown1() {
-        try {
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            assertTrue(p1.getExecuteExistingDelayedTasksAfterShutdownPolicy());
-            assertFalse(p1.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+    public void testShutDown1() throws InterruptedException {
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        assertTrue(p1.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+        assertFalse(p1.getContinueExistingPeriodicTasksAfterShutdownPolicy());
 
-            ScheduledFuture[] tasks = new ScheduledFuture[5];
-            for(int i = 0; i < 5; i++)
-                tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            BlockingQueue q = p1.getQueue();
-            for (Iterator it = q.iterator(); it.hasNext();) {
-                ScheduledFuture t = (ScheduledFuture)it.next();
-                assertFalse(t.isCancelled());
-            }
-            assertTrue(p1.isShutdown());
-            Thread.sleep(SMALL_DELAY_MS);
-            for (int i = 0; i < 5; ++i) {
-                assertTrue(tasks[i].isDone());
-                assertFalse(tasks[i].isCancelled());
-            }
-            
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++)
+            tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, MILLISECONDS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        BlockingQueue q = p1.getQueue();
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            ScheduledFuture t = (ScheduledFuture)it.next();
+            assertFalse(t.isCancelled());
         }
-        catch(Exception ex) {
-            unexpectedException();
+        assertTrue(p1.isShutdown());
+        Thread.sleep(SMALL_DELAY_MS);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(tasks[i].isDone());
+            assertFalse(tasks[i].isCancelled());
         }
     }
 
@@ -604,23 +524,18 @@
      * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
      * delayed tasks are cancelled at shutdown
      */
-    public void testShutDown2() {
-        try {
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            p1.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
-            ScheduledFuture[] tasks = new ScheduledFuture[5];
-            for(int i = 0; i < 5; i++)
-                tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            assertTrue(p1.isShutdown());
-            BlockingQueue q = p1.getQueue();
-            assertTrue(q.isEmpty());
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(p1.isTerminated());
-        }
-        catch(Exception ex) {
-            unexpectedException();
-        }
+    public void testShutDown2() throws InterruptedException {
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        p1.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
+        ScheduledFuture[] tasks = new ScheduledFuture[5];
+        for (int i = 0; i < 5; i++)
+            tasks[i] = p1.schedule(new NoOpRunnable(), SHORT_DELAY_MS, MILLISECONDS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p1.isShutdown());
+        BlockingQueue q = p1.getQueue();
+        assertTrue(q.isEmpty());
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(p1.isTerminated());
     }
 
 
@@ -628,36 +543,31 @@
      * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
      * periodic tasks are not cancelled at shutdown
      */
-    public void testShutDown3() {
-        try {
-            ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
-            p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
-            ScheduledFuture task =
-                p1.scheduleAtFixedRate(new NoOpRunnable(), 5, 5, TimeUnit.MILLISECONDS);
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
-            assertTrue(p1.isShutdown());
-            BlockingQueue q = p1.getQueue();
-            assertTrue(q.isEmpty());
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(p1.isTerminated());
-        }
-        catch(Exception ex) {
-            unexpectedException();
-        }
+    public void testShutDown3() throws InterruptedException {
+        ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
+        p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
+        ScheduledFuture task =
+            p1.scheduleAtFixedRate(new NoOpRunnable(), 5, 5, MILLISECONDS);
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p1.isShutdown());
+        BlockingQueue q = p1.getQueue();
+        assertTrue(q.isEmpty());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(p1.isTerminated());
     }
 
     /**
      * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
      * periodic tasks are cancelled at shutdown
      */
-    public void testShutDown4() {
+    public void testShutDown4() throws InterruptedException {
         ScheduledThreadPoolExecutor p1 = new ScheduledThreadPoolExecutor(1);
         try {
             p1.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
             ScheduledFuture task =
-                p1.scheduleAtFixedRate(new NoOpRunnable(), 1, 1, TimeUnit.MILLISECONDS);
+                p1.scheduleAtFixedRate(new NoOpRunnable(), 1, 1, MILLISECONDS);
             assertFalse(task.isCancelled());
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
             assertFalse(task.isCancelled());
             assertFalse(p1.isTerminated());
             assertTrue(p1.isShutdown());
@@ -668,10 +578,7 @@
             Thread.sleep(SHORT_DELAY_MS);
             assertTrue(p1.isTerminated());
         }
-        catch(Exception ex) {
-            unexpectedException();
-        }
-        finally { 
+        finally {
             joinPool(p1);
         }
     }
@@ -679,18 +586,12 @@
     /**
      * completed submit of callable returns result
      */
-    public void testSubmitCallable() {
+    public void testSubmitCallable() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             Future<String> future = e.submit(new StringTask());
             String result = future.get();
             assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -699,18 +600,12 @@
     /**
      * completed submit of runnable returns successfully
      */
-    public void testSubmitRunnable() {
+    public void testSubmitRunnable() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             Future<?> future = e.submit(new NoOpRunnable());
             future.get();
             assertTrue(future.isDone());
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -719,18 +614,12 @@
     /**
      * completed submit of (runnable, result) returns result
      */
-    public void testSubmitRunnable2() {
+    public void testSubmitRunnable2() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             String result = future.get();
             assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -739,13 +628,12 @@
     /**
      * invokeAny(null) throws NPE
      */
-    public void testInvokeAny1() {
+    public void testInvokeAny1() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             e.invokeAny(null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -754,13 +642,12 @@
     /**
      * invokeAny(empty collection) throws IAE
      */
-    public void testInvokeAny2() {
+    public void testInvokeAny2() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             e.invokeAny(new ArrayList<Callable<String>>());
+            shouldThrow();
         } catch (IllegalArgumentException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -769,17 +656,18 @@
     /**
      * invokeAny(c) throws NPE if c has null elements
      */
-    public void testInvokeAny3() {
+    public void testInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
             e.invokeAny(l);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
+            latch.countDown();
             joinPool(e);
         }
     }
@@ -787,15 +675,15 @@
     /**
      * invokeAny(c) throws ExecutionException if no task completes
      */
-    public void testInvokeAny4() {
+    public void testInvokeAny4() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
             e.invokeAny(l);
+            shouldThrow();
         } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -804,17 +692,14 @@
     /**
      * invokeAny(c) returns result of some task
      */
-    public void testInvokeAny5() {
+    public void testInvokeAny5() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -823,13 +708,12 @@
     /**
      * invokeAll(null) throws NPE
      */
-    public void testInvokeAll1() {
+    public void testInvokeAll1() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             e.invokeAll(null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -838,13 +722,11 @@
     /**
      * invokeAll(empty collection) returns empty collection
      */
-    public void testInvokeAll2() {
+    public void testInvokeAll2() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -853,16 +735,15 @@
     /**
      * invokeAll(c) throws NPE if c has null elements
      */
-    public void testInvokeAll3() {
+    public void testInvokeAll3() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
             e.invokeAll(l);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -871,18 +752,17 @@
     /**
      * get of invokeAll(c) throws exception on failed task
      */
-    public void testInvokeAll4() {
+    public void testInvokeAll4() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures = e.invokeAll(l);
+        assertEquals(1, futures.size());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
-            List<Future<String>> result = e.invokeAll(l);
-            assertEquals(1, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                it.next().get();
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -891,19 +771,16 @@
     /**
      * invokeAll(c) returns results of all completed tasks
      */
-    public void testInvokeAll5() {
+    public void testInvokeAll5() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l);
-            assertEquals(2, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                assertSame(TEST_STRING, it.next().get());
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
         } finally {
             joinPool(e);
         }
@@ -912,13 +789,12 @@
     /**
      * timed invokeAny(null) throws NPE
      */
-    public void testTimedInvokeAny1() {
+    public void testTimedInvokeAny1() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -927,15 +803,14 @@
     /**
      * timed invokeAny(,,null) throws NPE
      */
-    public void testTimedInvokeAnyNullTimeUnit() {
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
             e.invokeAny(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -944,13 +819,12 @@
     /**
      * timed invokeAny(empty collection) throws IAE
      */
-    public void testTimedInvokeAny2() {
+    public void testTimedInvokeAny2() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (IllegalArgumentException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -959,18 +833,18 @@
     /**
      * timed invokeAny(c) throws NPE if c has null elements
      */
-    public void testTimedInvokeAny3() {
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
-            e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            ex.printStackTrace();
-            unexpectedException();
         } finally {
+            latch.countDown();
             joinPool(e);
         }
     }
@@ -978,15 +852,15 @@
     /**
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
-    public void testTimedInvokeAny4() {
+    public void testTimedInvokeAny4() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
-            e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -995,17 +869,14 @@
     /**
      * timed invokeAny(c) returns result of some task
      */
-    public void testTimedInvokeAny5() {
+    public void testTimedInvokeAny5() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1014,13 +885,12 @@
     /**
      * timed invokeAll(null) throws NPE
      */
-    public void testTimedInvokeAll1() {
+    public void testTimedInvokeAll1() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1029,15 +899,14 @@
     /**
      * timed invokeAll(,,null) throws NPE
      */
-    public void testTimedInvokeAllNullTimeUnit() {
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
             e.invokeAll(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1046,13 +915,11 @@
     /**
      * timed invokeAll(empty collection) returns empty collection
      */
-    public void testTimedInvokeAll2() {
+    public void testTimedInvokeAll2() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1061,16 +928,15 @@
     /**
      * timed invokeAll(c) throws NPE if c has null elements
      */
-    public void testTimedInvokeAll3() {
+    public void testTimedInvokeAll3() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
-            e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1079,18 +945,18 @@
     /**
      * get of element of invokeAll(c) throws exception on failed task
      */
-    public void testTimedInvokeAll4() {
+    public void testTimedInvokeAll4() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures =
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+        assertEquals(1, futures.size());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
-            List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(1, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                it.next().get();
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -1099,19 +965,17 @@
     /**
      * timed invokeAll(c) returns results of all completed tasks
      */
-    public void testTimedInvokeAll5() {
+    public void testTimedInvokeAll5() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(2, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                assertSame(TEST_STRING, it.next().get());
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
         } finally {
             joinPool(e);
         }
@@ -1120,16 +984,17 @@
     /**
      * timed invokeAll(c) cancels tasks not completed by timeout
      */
-    public void testTimedInvokeAll6() {
+    public void testTimedInvokeAll6() throws Exception {
         ExecutorService e = new ScheduledThreadPoolExecutor(2);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(3, result.size());
-            Iterator<Future<String>> it = result.iterator(); 
+            List<Future<String>> futures =
+                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+            assertEquals(3, futures.size());
+            Iterator<Future<String>> it = futures.iterator();
             Future<String> f1 = it.next();
             Future<String> f2 = it.next();
             Future<String> f3 = it.next();
@@ -1138,8 +1003,6 @@
             assertTrue(f3.isDone());
             assertFalse(f1.isCancelled());
             assertTrue(f2.isCancelled());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java
index 4019812..c27893c 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/SemaphoreTest.java
@@ -2,21 +2,19 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 
 public class SemaphoreTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(SemaphoreTest.class);
     }
@@ -26,10 +24,10 @@
      */
     static class PublicSemaphore extends Semaphore {
         PublicSemaphore(int p, boolean f) { super(p, f); }
-        public Collection<Thread> getQueuedThreads() { 
-            return super.getQueuedThreads(); 
+        public Collection<Thread> getQueuedThreads() {
+            return super.getQueuedThreads();
         }
-        public void reducePermits(int p) { 
+        public void reducePermits(int p) {
             super.reducePermits(p);
         }
     }
@@ -37,29 +35,26 @@
     /**
      * A runnable calling acquire
      */
-    class InterruptibleLockRunnable implements Runnable {
+    class InterruptibleLockRunnable extends CheckedRunnable {
         final Semaphore lock;
         InterruptibleLockRunnable(Semaphore l) { lock = l; }
-        public void run() {
+        public void realRun() {
             try {
                 lock.acquire();
-            } catch(InterruptedException success){}
+            }
+            catch (InterruptedException ignored) {}
         }
     }
 
 
     /**
-     * A runnable calling acquire that expects to be
-     * interrupted
+     * A runnable calling acquire that expects to be interrupted
      */
-    class InterruptedLockRunnable implements Runnable {
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
         final Semaphore lock;
         InterruptedLockRunnable(Semaphore l) { lock = l; }
-        public void run() {
-            try {
-                lock.acquire();
-                threadShouldThrow();
-            } catch(InterruptedException success){}
+        public void realRun() throws InterruptedException {
+            lock.acquire();
         }
     }
 
@@ -67,30 +62,24 @@
      * Zero, negative, and positive initial values are allowed in constructor
      */
     public void testConstructor() {
-        Semaphore s0 = new Semaphore(0, false);
-        assertEquals(0, s0.availablePermits());
-        assertFalse(s0.isFair());
-        Semaphore s1 = new Semaphore(-1, false);
-        assertEquals(-1, s1.availablePermits());
-        assertFalse(s1.isFair());
-        Semaphore s2 = new Semaphore(-1, false);
-        assertEquals(-1, s2.availablePermits());
-        assertFalse(s2.isFair());
+        for (int permits : new int[] { -1, 0, 1 }) {
+            for (boolean fair : new boolean[] { false, true }) {
+                Semaphore s = new Semaphore(permits, fair);
+                assertEquals(permits, s.availablePermits());
+                assertEquals(fair, s.isFair());
+            }
+        }
     }
 
     /**
      * Constructor without fairness argument behaves as nonfair
      */
     public void testConstructor2() {
-        Semaphore s0 = new Semaphore(0);
-        assertEquals(0, s0.availablePermits());
-        assertFalse(s0.isFair());
-        Semaphore s1 = new Semaphore(-1);
-        assertEquals(-1, s1.availablePermits());
-        assertFalse(s1.isFair());
-        Semaphore s2 = new Semaphore(-1);
-        assertEquals(-1, s2.availablePermits());
-        assertFalse(s2.isFair());
+        for (int permits : new int[] { -1, 0, 1 }) {
+            Semaphore s = new Semaphore(permits);
+            assertEquals(permits, s.availablePermits());
+            assertFalse(s.isFair());
+        }
     }
 
     /**
@@ -108,296 +97,245 @@
     /**
      * Acquire and release of semaphore succeed if initially available
      */
-    public void testAcquireReleaseInSameThread() {
+    public void testAcquireReleaseInSameThread()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, false);
-        try {
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            assertEquals(1, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * Uninterruptible acquire and release of semaphore succeed if
      * initially available
      */
-    public void testAcquireUninterruptiblyReleaseInSameThread() {
+    public void testAcquireUninterruptiblyReleaseInSameThread()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, false);
-        try {
-            s.acquireUninterruptibly();
-            s.release();
-            s.acquireUninterruptibly();
-            s.release();
-            s.acquireUninterruptibly();
-            s.release();
-            s.acquireUninterruptibly();
-            s.release();
-            s.acquireUninterruptibly();
-            s.release();
-            assertEquals(1, s.availablePermits());
-        } finally {
-        }
+        s.acquireUninterruptibly();
+        s.release();
+        s.acquireUninterruptibly();
+        s.release();
+        s.acquireUninterruptibly();
+        s.release();
+        s.acquireUninterruptibly();
+        s.release();
+        s.acquireUninterruptibly();
+        s.release();
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * Timed Acquire and release of semaphore succeed if
      * initially available
      */
-    public void testTimedAcquireReleaseInSameThread() {
+    public void testTimedAcquireReleaseInSameThread()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, false);
-        try {
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertEquals(1, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * A release in one thread enables an acquire in another thread
      */
-    public void testAcquireReleaseInDifferentThreads() {
+    public void testAcquireReleaseInDifferentThreads()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire();
-                        s.release();
-                        s.release();
-                        s.acquire();
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            s.release();
-            s.release();
-            s.acquire();
-            s.acquire();
-            s.release();
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire();
+                s.release();
+                s.release();
+                s.acquire();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        s.release();
+        s.release();
+        s.acquire();
+        s.acquire();
+        s.release();
+        t.join();
     }
 
     /**
      * A release in one thread enables an uninterruptible acquire in another thread
      */
-    public void testUninterruptibleAcquireReleaseInDifferentThreads() {
+    public void testUninterruptibleAcquireReleaseInDifferentThreads()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    s.acquireUninterruptibly();
-                    s.release();
-                    s.release();
-                    s.acquireUninterruptibly();
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            s.release();
-            s.release();
-            s.acquireUninterruptibly();
-            s.acquireUninterruptibly();
-            s.release();
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquireUninterruptibly();
+                s.release();
+                s.release();
+                s.acquireUninterruptibly();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        s.release();
+        s.release();
+        s.acquireUninterruptibly();
+        s.acquireUninterruptibly();
+        s.release();
+        t.join();
     }
 
 
     /**
      *  A release in one thread enables a timed acquire in another thread
      */
-    public void testTimedAcquireReleaseInDifferentThreads() {
+    public void testTimedAcquireReleaseInDifferentThreads()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(1, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.release();
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        s.release();
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.release();
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+                s.release();
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+            }});
 
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            s.release();
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        t.start();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        s.release();
+        t.join();
     }
 
     /**
      * A waiting acquire blocks interruptibly
      */
-    public void testAcquire_InterruptedException() {
+    public void testAcquire_InterruptedException()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire();
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire();
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
-    
+
     /**
      *  A waiting timed acquire blocks interruptibly
      */
-    public void testTryAcquire_InterruptedException() {
+    public void testTryAcquire_InterruptedException()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, false);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.tryAcquire(MEDIUM_DELAY_MS, MILLISECONDS);
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * hasQueuedThreads reports whether there are waiting threads
      */
-    public void testHasQueuedThreads() { 
+    public void testHasQueuedThreads() throws InterruptedException {
         final Semaphore lock = new Semaphore(1, false);
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertFalse(lock.hasQueuedThreads());
-            lock.acquireUninterruptibly();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.hasQueuedThreads());
-            lock.release();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(lock.hasQueuedThreads());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertFalse(lock.hasQueuedThreads());
+        lock.acquireUninterruptibly();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.hasQueuedThreads());
+        lock.release();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(lock.hasQueuedThreads());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength() { 
+    public void testGetQueueLength() throws InterruptedException {
         final Semaphore lock = new Semaphore(1, false);
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertEquals(0, lock.getQueueLength());
-            lock.acquireUninterruptibly();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(2, lock.getQueueLength());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            lock.release();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(0, lock.getQueueLength());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertEquals(0, lock.getQueueLength());
+        lock.acquireUninterruptibly();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        lock.release();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, lock.getQueueLength());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * getQueuedThreads includes waiting threads
      */
-    public void testGetQueuedThreads() { 
+    public void testGetQueuedThreads() throws InterruptedException {
         final PublicSemaphore lock = new PublicSemaphore(1, false);
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            lock.acquireUninterruptibly();
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().contains(t1));
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().contains(t1));
-            assertTrue(lock.getQueuedThreads().contains(t2));
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertFalse(lock.getQueuedThreads().contains(t1));
-            assertTrue(lock.getQueuedThreads().contains(t2));
-            lock.release();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertTrue(lock.getQueuedThreads().isEmpty());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        lock.acquireUninterruptibly();
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertFalse(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        lock.release();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.join();
+        t2.join();
+    }
 
     /**
      * drainPermits reports and removes given number of permits
@@ -428,26 +366,22 @@
     /**
      * a deserialized serialized semaphore has same number of permits
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         Semaphore l = new Semaphore(3, false);
-        try {
-            l.acquire();
-            l.release();
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        l.acquire();
+        l.release();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            Semaphore r = (Semaphore) in.readObject();
-            assertEquals(3, r.availablePermits());
-            assertFalse(r.isFair());
-            r.acquire();
-            r.release();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        Semaphore r = (Semaphore) in.readObject();
+        assertEquals(3, r.availablePermits());
+        assertFalse(r.isFair());
+        r.acquire();
+        r.release();
     }
 
 
@@ -490,45 +424,39 @@
     /**
      * Acquire and release of semaphore succeed if initially available
      */
-    public void testAcquireReleaseInSameThread_fair() {
+    public void testAcquireReleaseInSameThread_fair()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, true);
-        try {
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            s.acquire();
-            s.release();
-            assertEquals(1, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        s.acquire();
+        s.release();
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * Acquire(n) and release(n) of semaphore succeed if initially available
      */
-    public void testAcquireReleaseNInSameThread_fair() {
+    public void testAcquireReleaseNInSameThread_fair()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, true);
-        try {
-            s.release(1);
-            s.acquire(1);
-            s.release(2);
-            s.acquire(2);
-            s.release(3);
-            s.acquire(3);
-            s.release(4);
-            s.acquire(4);
-            s.release(5);
-            s.acquire(5);
-            assertEquals(1, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        s.release(1);
+        s.acquire(1);
+        s.release(2);
+        s.acquire(2);
+        s.release(3);
+        s.acquire(3);
+        s.release(4);
+        s.acquire(4);
+        s.release(5);
+        s.acquire(5);
+        assertEquals(1, s.availablePermits());
     }
 
     /**
@@ -536,369 +464,287 @@
      */
     public void testAcquireUninterruptiblyReleaseNInSameThread_fair() {
         Semaphore s = new Semaphore(1, true);
-        try {
-            s.release(1);
-            s.acquireUninterruptibly(1);
-            s.release(2);
-            s.acquireUninterruptibly(2);
-            s.release(3);
-            s.acquireUninterruptibly(3);
-            s.release(4);
-            s.acquireUninterruptibly(4);
-            s.release(5);
-            s.acquireUninterruptibly(5);
-            assertEquals(1, s.availablePermits());
-        } finally {
-        }
+        s.release(1);
+        s.acquireUninterruptibly(1);
+        s.release(2);
+        s.acquireUninterruptibly(2);
+        s.release(3);
+        s.acquireUninterruptibly(3);
+        s.release(4);
+        s.acquireUninterruptibly(4);
+        s.release(5);
+        s.acquireUninterruptibly(5);
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * release(n) in one thread enables timed acquire(n) in another thread
      */
-    public void testTimedAcquireReleaseNInSameThread_fair() {
+    public void testTimedAcquireReleaseNInSameThread_fair()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, true);
-        try {
-            s.release(1);
-            assertTrue(s.tryAcquire(1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release(2);
-            assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release(3);
-            assertTrue(s.tryAcquire(3, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release(4);
-            assertTrue(s.tryAcquire(4, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release(5);
-            assertTrue(s.tryAcquire(5, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            assertEquals(1, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        s.release(1);
+        assertTrue(s.tryAcquire(1, SHORT_DELAY_MS, MILLISECONDS));
+        s.release(2);
+        assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, MILLISECONDS));
+        s.release(3);
+        assertTrue(s.tryAcquire(3, SHORT_DELAY_MS, MILLISECONDS));
+        s.release(4);
+        assertTrue(s.tryAcquire(4, SHORT_DELAY_MS, MILLISECONDS));
+        s.release(5);
+        assertTrue(s.tryAcquire(5, SHORT_DELAY_MS, MILLISECONDS));
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * release in one thread enables timed acquire in another thread
      */
-    public void testTimedAcquireReleaseInSameThread_fair() {
+    public void testTimedAcquireReleaseInSameThread_fair()
+        throws InterruptedException {
         Semaphore s = new Semaphore(1, true);
-        try {
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release();
-            assertEquals(1, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+        s.release();
+        assertEquals(1, s.availablePermits());
     }
 
     /**
      * A release in one thread enables an acquire in another thread
      */
-    public void testAcquireReleaseInDifferentThreads_fair() {
+    public void testAcquireReleaseInDifferentThreads_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire();
-                        s.acquire();
-                        s.acquire();
-                        s.acquire();
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            s.release();
-            s.release();
-            s.release();
-            s.release();
-            s.release();
-            s.release();
-            t.join();
-            assertEquals(2, s.availablePermits());
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire();
+                s.acquire();
+                s.acquire();
+                s.acquire();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        s.release();
+        s.release();
+        s.release();
+        s.release();
+        s.release();
+        s.release();
+        t.join();
+        assertEquals(2, s.availablePermits());
     }
 
     /**
      * release(n) in one thread enables acquire(n) in another thread
      */
-    public void testAcquireReleaseNInDifferentThreads_fair() {
+    public void testAcquireReleaseNInDifferentThreads_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire();
-                        s.release(2);
-                        s.acquire();
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            s.release(2);
-            s.acquire(2);
-            s.release(1);
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire();
+                s.release(2);
+                s.acquire();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        s.release(2);
+        s.acquire(2);
+        s.release(1);
+        t.join();
     }
 
     /**
      * release(n) in one thread enables acquire(n) in another thread
      */
-    public void testAcquireReleaseNInDifferentThreads_fair2() {
+    public void testAcquireReleaseNInDifferentThreads_fair2()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire(2);
-                        s.acquire(2);
-                        s.release(4);
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            s.release(6);
-            s.acquire(2);
-            s.acquire(2);
-            s.release(2);
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire(2);
+                s.acquire(2);
+                s.release(4);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        s.release(6);
+        s.acquire(2);
+        s.acquire(2);
+        s.release(2);
+        t.join();
     }
 
 
-
-
-
     /**
      * release in one thread enables timed acquire in another thread
      */
-    public void testTimedAcquireReleaseInDifferentThreads_fair() {
+    public void testTimedAcquireReleaseInDifferentThreads_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(1, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(s.tryAcquire(SHORT_DELAY_MS, MILLISECONDS));
+            }});
 
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
         t.start();
-        try {
-            s.release();
-            s.release();
-            s.release();
-            s.release();
-            s.release();
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        s.release();
+        s.release();
+        s.release();
+        s.release();
+        s.release();
+        t.join();
     }
 
     /**
      * release(n) in one thread enables timed acquire(n) in another thread
      */
-    public void testTimedAcquireReleaseNInDifferentThreads_fair() {
+    public void testTimedAcquireReleaseNInDifferentThreads_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(2, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        s.release(2);
-                        threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        s.release(2);
-                    } catch(InterruptedException ie){
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, MILLISECONDS));
+                s.release(2);
+                assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, MILLISECONDS));
+                s.release(2);
+            }});
+
         t.start();
-        try {
-            assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release(2);
-            assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            s.release(2);
-            t.join();
-        } catch( InterruptedException e){
-            unexpectedException();
-        }
+        assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, MILLISECONDS));
+        s.release(2);
+        assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, MILLISECONDS));
+        s.release(2);
+        t.join();
     }
 
     /**
      * A waiting acquire blocks interruptibly
      */
-    public void testAcquire_InterruptedException_fair() {
+    public void testAcquire_InterruptedException_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire();
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire();
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * A waiting acquire(n) blocks interruptibly
      */
-    public void testAcquireN_InterruptedException_fair() {
+    public void testAcquireN_InterruptedException_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(2, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.acquire(3);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){}
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.acquire(3);
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
-    
+
     /**
      *  A waiting tryAcquire blocks interruptibly
      */
-    public void testTryAcquire_InterruptedException_fair() {
+    public void testTryAcquire_InterruptedException_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(0, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.tryAcquire(MEDIUM_DELAY_MS, MILLISECONDS);
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  A waiting tryAcquire(n) blocks interruptibly
      */
-    public void testTryAcquireN_InterruptedException_fair() {
+    public void testTryAcquireN_InterruptedException_fair()
+        throws InterruptedException {
         final Semaphore s = new Semaphore(1, true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        s.tryAcquire(4, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch(InterruptedException success){
-                    }
-                }
-            });
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                s.tryAcquire(4, MEDIUM_DELAY_MS, MILLISECONDS);
+            }});
+
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(InterruptedException e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * getQueueLength reports number of waiting threads
      */
-    public void testGetQueueLength_fair() { 
+    public void testGetQueueLength_fair() throws InterruptedException {
         final Semaphore lock = new Semaphore(1, true);
         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
-        try {
-            assertEquals(0, lock.getQueueLength());
-            lock.acquireUninterruptibly();
-            t1.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            t2.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(2, lock.getQueueLength());
-            t1.interrupt();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, lock.getQueueLength());
-            lock.release();
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(0, lock.getQueueLength());
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
-    } 
+        assertEquals(0, lock.getQueueLength());
+        lock.acquireUninterruptibly();
+        t1.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, lock.getQueueLength());
+        lock.release();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, lock.getQueueLength());
+        t1.join();
+        t2.join();
+    }
 
 
     /**
      * a deserialized serialized semaphore has same number of permits
      */
-    public void testSerialization_fair() {
+    public void testSerialization_fair() throws Exception {
         Semaphore l = new Semaphore(3, true);
 
-        try {
-            l.acquire();
-            l.release();
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(l);
-            out.close();
+        l.acquire();
+        l.release();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(l);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            Semaphore r = (Semaphore) in.readObject();
-            assertEquals(3, r.availablePermits());
-            assertTrue(r.isFair());
-            r.acquire();
-            r.release();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        Semaphore r = (Semaphore) in.readObject();
+        assertEquals(3, r.availablePermits());
+        assertTrue(r.isFair());
+        r.acquire();
+        r.release();
     }
 
     /**
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java
index debce5d..9393c5c 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/SynchronousQueueTest.java
@@ -2,23 +2,19 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.*;
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.io.*;
 
 public class SynchronousQueueTest extends JSR166TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
-
     public static Test suite() {
         return new TestSuite(SynchronousQueueTest.class);
     }
@@ -53,7 +49,7 @@
             SynchronousQueue q = new SynchronousQueue();
             q.offer(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -64,7 +60,7 @@
             SynchronousQueue q = new SynchronousQueue();
             q.add(null);
             shouldThrow();
-        } catch (NullPointerException success) { }   
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -84,8 +80,7 @@
             assertEquals(0, q.remainingCapacity());
             q.add(one);
             shouldThrow();
-        } catch (IllegalStateException success){
-        }   
+        } catch (IllegalStateException success) {}
     }
 
     /**
@@ -96,8 +91,7 @@
             SynchronousQueue q = new SynchronousQueue();
             q.addAll(null);
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
 
     /**
@@ -108,8 +102,7 @@
             SynchronousQueue q = new SynchronousQueue();
             q.addAll(q);
             shouldThrow();
-        }
-        catch (IllegalArgumentException success) {}
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
@@ -121,8 +114,7 @@
             Integer[] ints = new Integer[1];
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (NullPointerException success) {}
+        } catch (NullPointerException success) {}
     }
     /**
      * addAll throws ISE if no active taker
@@ -135,243 +127,171 @@
                 ints[i] = new Integer(i);
             q.addAll(Arrays.asList(ints));
             shouldThrow();
-        }
-        catch (IllegalStateException success) {}
+        } catch (IllegalStateException success) {}
     }
 
     /**
      * put(null) throws NPE
      */
-    public void testPutNull() {
+    public void testPutNull() throws InterruptedException {
         try {
             SynchronousQueue q = new SynchronousQueue();
             q.put(null);
             shouldThrow();
-        } 
-        catch (NullPointerException success){
-        }   
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        } catch (NullPointerException success) {}
      }
 
     /**
      * put blocks interruptibly if no active taker
      */
-    public void testBlockingPut() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        SynchronousQueue q = new SynchronousQueue();
-                        q.put(zero);
-                        threadShouldThrow();
-                    } catch (InterruptedException ie){
-                    }   
-                }});
+    public void testBlockingPut() throws InterruptedException {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                SynchronousQueue q = new SynchronousQueue();
+                q.put(zero);
+            }});
+
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
-     * put blocks waiting for take 
+     * put blocks waiting for take
      */
-    public void testPutWithTake() {
+    public void testPutWithTake() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        q.put(new Object());
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                int added = 0;
+                try {
+                    while (true) {
+                        q.put(added);
                         ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        threadShouldThrow();
-                    } catch (InterruptedException e){
-                        assertTrue(added >= 1);
                     }
+                } catch (InterruptedException success) {
+                    assertTrue(added == 1);
                 }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.take();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timed offer times out if elements not taken
      */
-    public void testTimedOffer() {
+    public void testTimedOffer() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(q.offer(new Object(), SHORT_DELAY_MS, MILLISECONDS));
+                q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+            }});
 
-                        threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success){}
-                }
-            });
-        
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
     /**
      * take blocks interruptibly when empty
      */
-    public void testTakeFromEmpty() {
+    public void testTakeFromEmpty() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){ }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
     /**
      * put blocks interruptibly if no active taker
      */
-    public void testFairBlockingPut() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        SynchronousQueue q = new SynchronousQueue(true);
-                        q.put(zero);
-                        threadShouldThrow();
-                    } catch (InterruptedException ie){
-                    }   
-                }});
+    public void testFairBlockingPut() throws InterruptedException {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                SynchronousQueue q = new SynchronousQueue(true);
+                q.put(zero);
+            }});
+
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
-     * put blocks waiting for take 
+     * put blocks waiting for take
      */
-    public void testFairPutWithTake() {
+    public void testFairPutWithTake() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue(true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    int added = 0;
-                    try {
-                        q.put(new Object());
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                int added = 0;
+                try {
+                    while (true) {
+                        q.put(added);
                         ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        q.put(new Object());
-                        ++added;
-                        threadShouldThrow();
-                    } catch (InterruptedException e){
-                        assertTrue(added >= 1);
                     }
+                } catch (InterruptedException success) {
+                    assertTrue(added == 1);
                 }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.take();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(0, q.take());
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      * timed offer times out if elements not taken
      */
-    public void testFairTimedOffer() {
+    public void testFairTimedOffer() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue(true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(q.offer(new Object(), SHORT_DELAY_MS, MILLISECONDS));
+                q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+            }});
 
-                        threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success){}
-                }
-            });
-        
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
 
     /**
      * take blocks interruptibly when empty
      */
-    public void testFairTakeFromEmpty() {
+    public void testFairTakeFromEmpty() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue(true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.take();
-                        threadShouldThrow();
-                    } catch (InterruptedException success){ }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.take();
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
@@ -385,128 +305,98 @@
     /**
      * timed pool with zero timeout times out if no active taker
      */
-    public void testTimedPoll0() {
-        try {
-            SynchronousQueue q = new SynchronousQueue();
-            assertNull(q.poll(0, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTimedPoll0() throws InterruptedException {
+        SynchronousQueue q = new SynchronousQueue();
+        assertNull(q.poll(0, MILLISECONDS));
     }
 
     /**
      * timed pool with nonzero timeout times out if no active taker
      */
-    public void testTimedPoll() {
-        try {
-            SynchronousQueue q = new SynchronousQueue();
-            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-        } catch (InterruptedException e){
-            unexpectedException();
-        }   
+    public void testTimedPoll() throws InterruptedException {
+        SynchronousQueue q = new SynchronousQueue();
+        assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
     }
 
     /**
      * Interrupted timed poll throws InterruptedException instead of
      * returning timeout status
      */
-    public void testInterruptedTimedPoll() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        SynchronousQueue q = new SynchronousQueue();
-                        assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch (InterruptedException success){
-                    }   
-                }});
-        t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
-    }
-
-    /**
-     *  timed poll before a delayed offer fails; after offer succeeds;
-     *  on interruption throws
-     */
-    public void testTimedPollWithOffer() {
+    public void testInterruptedTimedPoll() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success) { }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
-    }  
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.poll(SMALL_DELAY_MS, MILLISECONDS);
+            }});
 
-    /**
-     * Interrupted timed poll throws InterruptedException instead of
-     * returning timeout status
-     */
-    public void testFairInterruptedTimedPoll() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        SynchronousQueue q = new SynchronousQueue(true);
-                        assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                    } catch (InterruptedException success){
-                    }   
-                }});
         t.start();
-        try { 
-           Thread.sleep(SHORT_DELAY_MS); 
-           t.interrupt();
-           t.join();
-        }
-        catch (InterruptedException ie) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
      *  timed poll before a delayed offer fails; after offer succeeds;
      *  on interruption throws
      */
-    public void testFairTimedPollWithOffer() {
+    public void testTimedPollWithOffer() throws InterruptedException {
+        final SynchronousQueue q = new SynchronousQueue();
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testFairInterruptedTimedPoll() throws InterruptedException {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                SynchronousQueue q = new SynchronousQueue(true);
+                q.poll(SMALL_DELAY_MS, MILLISECONDS);
+            }});
+
+        t.start();
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+    }
+
+    /**
+     *  timed poll before a delayed offer fails; after offer succeeds;
+     *  on interruption throws
+     */
+    public void testFairTimedPollWithOffer() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue(true);
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
-                        threadShouldThrow();
-                    } catch (InterruptedException success) { }                
-                }
-            });
-        try {
-            t.start();
-            Thread.sleep(SMALL_DELAY_MS);
-            assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
-            t.interrupt();
-            t.join();
-        } catch (Exception e){
-            unexpectedException();
-        }
-    }  
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    threadShouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        t.start();
+        Thread.sleep(SMALL_DELAY_MS);
+        assertTrue(q.offer(zero, SHORT_DELAY_MS, MILLISECONDS));
+        t.interrupt();
+        t.join();
+    }
 
 
     /**
@@ -525,8 +415,7 @@
         try {
             q.element();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -537,8 +426,7 @@
         try {
             q.remove();
             shouldThrow();
-        } catch (NoSuchElementException success){
-        }   
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -549,7 +437,7 @@
         assertFalse(q.remove(zero));
         assertTrue(q.isEmpty());
     }
-        
+
     /**
      * contains returns false
      */
@@ -618,16 +506,16 @@
         Integer[] ints = new Integer[1];
         assertNull(ints[0]);
     }
-    
+
     /**
      * toArray(null) throws NPE
      */
     public void testToArray_BadArg() {
+        SynchronousQueue q = new SynchronousQueue();
         try {
-            SynchronousQueue q = new SynchronousQueue();
             Object o[] = q.toArray(null);
             shouldThrow();
-        } catch(NullPointerException success){}
+        } catch (NullPointerException success) {}
     }
 
 
@@ -641,8 +529,7 @@
         try {
             Object x = it.next();
             shouldThrow();
-        }
-        catch (NoSuchElementException success) {}
+        } catch (NoSuchElementException success) {}
     }
 
     /**
@@ -654,8 +541,9 @@
         try {
             it.remove();
             shouldThrow();
+        } catch (IllegalStateException success) {
+        } catch (UnsupportedOperationException success) { // android-added
         }
-        catch (IllegalStateException success) {}
     }
 
     /**
@@ -665,7 +553,7 @@
         SynchronousQueue q = new SynchronousQueue();
         String s = q.toString();
         assertNotNull(s);
-    }        
+    }
 
 
     /**
@@ -674,35 +562,21 @@
     public void testOfferInExecutor() {
         final SynchronousQueue q = new SynchronousQueue();
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        final Integer one = new Integer(1);
 
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertFalse(q.offer(one));
-                try {
-                    threadAssertTrue(q.offer(one, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertEquals(0, q.remainingCapacity());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(q.offer(one));
+                assertTrue(q.offer(one, MEDIUM_DELAY_MS, MILLISECONDS));
+                assertEquals(0, q.remainingCapacity());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    threadAssertEquals(one, q.take());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
-        
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SMALL_DELAY_MS);
+                assertSame(one, q.take());
+            }});
+
         joinPool(executor);
-
     }
 
     /**
@@ -711,84 +585,65 @@
     public void testPollInExecutor() {
         final SynchronousQueue q = new SynchronousQueue();
         ExecutorService executor = Executors.newFixedThreadPool(2);
-        executor.execute(new Runnable() {
-            public void run() {
-                threadAssertNull(q.poll());
-                try {
-                    threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
-                    threadAssertTrue(q.isEmpty());
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertNull(q.poll());
+                assertSame(one, q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
+                assertTrue(q.isEmpty());
+            }});
 
-        executor.execute(new Runnable() {
-            public void run() {
-                try {
-                    Thread.sleep(SMALL_DELAY_MS);
-                    q.put(new Integer(1));
-                }
-                catch (InterruptedException e) {
-                    threadUnexpectedException();
-                }
-            }
-        });
-        
+        executor.execute(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(SHORT_DELAY_MS);
+                q.put(one);
+            }});
+
         joinPool(executor);
     }
 
     /**
      * a deserialized serialized queue is usable
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         SynchronousQueue q = new SynchronousQueue();
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            SynchronousQueue r = (SynchronousQueue)in.readObject();
-            assertEquals(q.size(), r.size());
-            while (!q.isEmpty()) 
-                assertEquals(q.remove(), r.remove());
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        SynchronousQueue r = (SynchronousQueue)in.readObject();
+        assertEquals(q.size(), r.size());
+        while (!q.isEmpty())
+            assertEquals(q.remove(), r.remove());
     }
 
     /**
      * drainTo(null) throws NPE
-     */ 
+     */
     public void testDrainToNull() {
         SynchronousQueue q = new SynchronousQueue();
         try {
             q.drainTo(null);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this) throws IAE
-     */ 
+     */
     public void testDrainToSelf() {
         SynchronousQueue q = new SynchronousQueue();
         try {
             q.drainTo(q);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c) of empty queue doesn't transfer elements
-     */ 
+     */
     public void testDrainTo() {
         SynchronousQueue q = new SynchronousQueue();
         ArrayList l = new ArrayList();
@@ -799,98 +654,74 @@
 
     /**
      * drainTo empties queue, unblocking a waiting put.
-     */ 
-    public void testDrainToWithActivePut() {
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue();
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(new Integer(1));
-                    } catch (InterruptedException ie){ 
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        try {
-            t.start();
-            ArrayList l = new ArrayList();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.drainTo(l);
-            assertTrue(l.size() <= 1);
-            if (l.size() > 0)
-                assertEquals(l.get(0), new Integer(1));
-            t.join();
-            assertTrue(l.size() <= 1);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        Thread.sleep(SHORT_DELAY_MS);
+        q.drainTo(l);
+        assertTrue(l.size() <= 1);
+        if (l.size() > 0)
+            assertEquals(l.get(0), new Integer(1));
+        t.join();
+        assertTrue(l.size() <= 1);
     }
 
     /**
      * drainTo(null, n) throws NPE
-     */ 
+     */
     public void testDrainToNullN() {
         SynchronousQueue q = new SynchronousQueue();
         try {
             q.drainTo(null, 0);
             shouldThrow();
-        } catch(NullPointerException success) {
-        }
+        } catch (NullPointerException success) {}
     }
 
     /**
      * drainTo(this, n) throws IAE
-     */ 
+     */
     public void testDrainToSelfN() {
         SynchronousQueue q = new SynchronousQueue();
         try {
             q.drainTo(q, 0);
             shouldThrow();
-        } catch(IllegalArgumentException success) {
-        }
+        } catch (IllegalArgumentException success) {}
     }
 
     /**
      * drainTo(c, n) empties up to n elements of queue into c
-     */ 
-    public void testDrainToN() {
+     */
+    public void testDrainToN() throws InterruptedException {
         final SynchronousQueue q = new SynchronousQueue();
-        Thread t1 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(one);
-                    } catch (InterruptedException ie){ 
-                        threadUnexpectedException();
-                    }
-                }
-            });
-        Thread t2 = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        q.put(two);
-                    } catch (InterruptedException ie){ 
-                        threadUnexpectedException();
-                    }
-                }
-            });
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(one);
+            }});
 
-        try {
-            t1.start();
-            t2.start();
-            ArrayList l = new ArrayList();
-            Thread.sleep(SHORT_DELAY_MS);
-            q.drainTo(l, 1);
-            assertTrue(l.size() == 1);
-            q.drainTo(l, 1);
-            assertTrue(l.size() == 2);
-            assertTrue(l.contains(one));
-            assertTrue(l.contains(two));
-            t1.join();
-            t2.join();
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(two);
+            }});
+
+        t1.start();
+        t2.start();
+        ArrayList l = new ArrayList();
+        Thread.sleep(SHORT_DELAY_MS);
+        q.drainTo(l, 1);
+        assertTrue(l.size() == 1);
+        q.drainTo(l, 1);
+        assertTrue(l.size() == 2);
+        assertTrue(l.contains(one));
+        assertTrue(l.contains(two));
+        t1.join();
+        t2.join();
     }
 
-
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java
index 4433cb1..e906186 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/SystemTest.java
@@ -2,26 +2,22 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 
 public class SystemTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());   
-    }
-    
     public static Test suite() {
         return new TestSuite(SystemTest.class);
     }
 
-    /** 
+    /**
      * Worst case rounding for millisecs; set for 60 cycle millis clock.
-     * This value might need to be changed os JVMs with coarser
+     * This value might need to be changed on JVMs with coarser
      *  System.currentTimeMillis clocks.
      */
     static final long MILLIS_ROUND = 17;
@@ -31,24 +27,19 @@
      * possible rounding).
      * This shows only that nano timing not (much) worse than milli.
      */
-    public void testNanoTime1() {
-        try {
-            long m1 = System.currentTimeMillis();
-            Thread.sleep(1);
-            long n1 = System.nanoTime();
-            Thread.sleep(SHORT_DELAY_MS);
-            long n2 = System.nanoTime();
-            Thread.sleep(1);
-            long m2 = System.currentTimeMillis();
-            long millis = m2 - m1;
-            long nanos = n2 - n1;
-            assertTrue(nanos >= 0);
-            long nanosAsMillis = nanos / 1000000;
-            assertTrue(nanosAsMillis <= millis + MILLIS_ROUND);
-        }
-        catch(InterruptedException ie) {
-            unexpectedException();
-        }
+    public void testNanoTime1() throws InterruptedException {
+        long m1 = System.currentTimeMillis();
+        Thread.sleep(1);
+        long n1 = System.nanoTime();
+        Thread.sleep(SHORT_DELAY_MS);
+        long n2 = System.nanoTime();
+        Thread.sleep(1);
+        long m2 = System.currentTimeMillis();
+        long millis = m2 - m1;
+        long nanos = n2 - n1;
+        assertTrue(nanos >= 0);
+        long nanosAsMillis = nanos / 1000000;
+        assertTrue(nanosAsMillis <= millis + MILLIS_ROUND);
     }
 
     /**
@@ -56,26 +47,20 @@
      * for rounding.
      * This shows only that nano timing not (much) worse than milli.
      */
-    public void testNanoTime2() {
-        try {
-            long n1 = System.nanoTime();
-            Thread.sleep(1);
-            long m1 = System.currentTimeMillis();
-            Thread.sleep(SHORT_DELAY_MS);
-            long m2 = System.currentTimeMillis();
-            Thread.sleep(1);
-            long n2 = System.nanoTime();
-            long millis = m2 - m1;
-            long nanos = n2 - n1;
-            
-            assertTrue(nanos >= 0);
-            long nanosAsMillis = nanos / 1000000;
-            assertTrue(millis <= nanosAsMillis + MILLIS_ROUND);
-        }
-        catch(InterruptedException ie) {
-            unexpectedException();
-        }
+    public void testNanoTime2() throws InterruptedException {
+        long n1 = System.nanoTime();
+        Thread.sleep(1);
+        long m1 = System.currentTimeMillis();
+        Thread.sleep(SHORT_DELAY_MS);
+        long m2 = System.currentTimeMillis();
+        Thread.sleep(1);
+        long n2 = System.nanoTime();
+        long millis = m2 - m1;
+        long nanos = n2 - n1;
+
+        assertTrue(nanos >= 0);
+        long nanosAsMillis = nanos / 1000000;
+        assertTrue(millis <= nanosAsMillis + MILLIS_ROUND);
     }
 
 }
-
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java
index 0c2256a..d54bce0 100644
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadLocalTest.java
@@ -2,20 +2,16 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.Semaphore;
 
 public class ThreadLocalTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());        
-    }
-    
     public static Test suite() {
         return new TestSuite(ThreadLocalTest.class);
     }
@@ -31,7 +27,7 @@
             protected Integer initialValue() {
                 return zero;
             }
-            
+
             protected Integer childValue(Integer parentValue) {
                 return new Integer(parentValue.intValue() + 1);
             }
@@ -41,11 +37,11 @@
      * remove causes next access to return initial value
      */
     public void testRemove() {
-        assertEquals(tl.get(), one);
+        assertSame(tl.get(), one);
         tl.set(two);
-        assertEquals(tl.get(), two);
+        assertSame(tl.get(), two);
         tl.remove();
-        assertEquals(tl.get(), one);
+        assertSame(tl.get(), one);
     }
 
     /**
@@ -53,11 +49,11 @@
      * initial value
      */
     public void testRemoveITL() {
-        assertEquals(itl.get(), zero);
+        assertSame(itl.get(), zero);
         itl.set(two);
-        assertEquals(itl.get(), two);
+        assertSame(itl.get(), two);
         itl.remove();
-        assertEquals(itl.get(), zero);
+        assertSame(itl.get(), zero);
     }
 
     private class ITLThread extends Thread {
@@ -70,18 +66,18 @@
                 child.start();
             }
             Thread.currentThread().yield();
-            
+
             int threadId = itl.get().intValue();
             for (int j = 0; j < threadId; j++) {
                 x[threadId]++;
                 Thread.currentThread().yield();
             }
-            
+
             if (child != null) { // Wait for child (if any)
                 try {
                     child.join();
-                } catch(InterruptedException e) {
-                    threadUnexpectedException();
+                } catch (InterruptedException e) {
+                    threadUnexpectedException(e);
                 }
             }
         }
@@ -90,19 +86,14 @@
     /**
      * InheritableThreadLocal propagates generic values.
      */
-    public void testGenericITL() {
+    public void testGenericITL() throws InterruptedException {
         final int threadCount = 10;
         final int x[] = new int[threadCount];
         Thread progenitor = new ITLThread(x);
-        try {
-            progenitor.start();
-            progenitor.join();
-            for(int i = 0; i < threadCount; i++) {
-                assertEquals(i, x[i]);
-            }
-        } catch(InterruptedException e) {
-            unexpectedException();
+        progenitor.start();
+        progenitor.join();
+        for (int i = 0; i < threadCount; i++) {
+            assertEquals(i, x[i]);
         }
     }
 }
-
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorSubclassTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorSubclassTest.java
new file mode 100644
index 0000000..911a35f
--- /dev/null
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorSubclassTest.java
@@ -0,0 +1,1578 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package tests.api.java.util.concurrent; // android-added
+
+import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.*;
+
+import junit.framework.*;
+import java.util.*;
+
+public class ThreadPoolExecutorSubclassTest extends JSR166TestCase {
+    public static Test suite() {
+        return new TestSuite(ThreadPoolExecutorSubclassTest.class);
+    }
+
+    static class CustomTask<V> implements RunnableFuture<V> {
+        final Callable<V> callable;
+        final ReentrantLock lock = new ReentrantLock();
+        final Condition cond = lock.newCondition();
+        boolean done;
+        boolean cancelled;
+        V result;
+        Thread thread;
+        Exception exception;
+        CustomTask(Callable<V> c) {
+            if (c == null) throw new NullPointerException();
+            callable = c;
+        }
+        CustomTask(final Runnable r, final V res) {
+            if (r == null) throw new NullPointerException();
+            callable = new Callable<V>() {
+            public V call() throws Exception { r.run(); return res; }};
+        }
+        public boolean isDone() {
+            lock.lock(); try { return done; } finally { lock.unlock() ; }
+        }
+        public boolean isCancelled() {
+            lock.lock(); try { return cancelled; } finally { lock.unlock() ; }
+        }
+        public boolean cancel(boolean mayInterrupt) {
+            lock.lock();
+            try {
+                if (!done) {
+                    cancelled = true;
+                    done = true;
+                    if (mayInterrupt && thread != null)
+                        thread.interrupt();
+                    return true;
+                }
+                return false;
+            }
+            finally { lock.unlock() ; }
+        }
+        public void run() {
+            boolean runme;
+            lock.lock();
+            try {
+                runme = !done;
+                if (!runme)
+                    thread = Thread.currentThread();
+            }
+            finally { lock.unlock() ; }
+            if (!runme) return;
+            V v = null;
+            Exception e = null;
+            try {
+                v = callable.call();
+            }
+            catch (Exception ex) {
+                e = ex;
+            }
+            lock.lock();
+            try {
+                result = v;
+                exception = e;
+                done = true;
+                thread = null;
+                cond.signalAll();
+            }
+            finally { lock.unlock(); }
+        }
+        public V get() throws InterruptedException, ExecutionException {
+            lock.lock();
+            try {
+                while (!done)
+                    cond.await();
+                if (exception != null)
+                    throw new ExecutionException(exception);
+                return result;
+            }
+            finally { lock.unlock(); }
+        }
+        public V get(long timeout, TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+            long nanos = unit.toNanos(timeout);
+            lock.lock();
+            try {
+                for (;;) {
+                    if (done) break;
+                    if (nanos < 0)
+                        throw new TimeoutException();
+                    nanos = cond.awaitNanos(nanos);
+                }
+                if (exception != null)
+                    throw new ExecutionException(exception);
+                return result;
+            }
+            finally { lock.unlock(); }
+        }
+    }
+
+
+    static class CustomTPE extends ThreadPoolExecutor {
+        protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
+            return new CustomTask<V>(c);
+        }
+        protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
+            return new CustomTask<V>(r, v);
+        }
+
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue) {
+            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+                  workQueue);
+        }
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue,
+                  ThreadFactory threadFactory) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+             threadFactory);
+        }
+
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue,
+                  RejectedExecutionHandler handler) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+              handler);
+        }
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue,
+                  ThreadFactory threadFactory,
+                  RejectedExecutionHandler handler) {
+            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+              workQueue, threadFactory, handler);
+        }
+
+        volatile boolean beforeCalled = false;
+        volatile boolean afterCalled = false;
+        volatile boolean terminatedCalled = false;
+        public CustomTPE() {
+            super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
+        }
+        protected void beforeExecute(Thread t, Runnable r) {
+            beforeCalled = true;
+        }
+        protected void afterExecute(Runnable r, Throwable t) {
+            afterCalled = true;
+        }
+        protected void terminated() {
+            terminatedCalled = true;
+        }
+
+    }
+
+    static class FailingThreadFactory implements ThreadFactory {
+        int calls = 0;
+        public Thread newThread(Runnable r) {
+            if (++calls > 1) return null;
+            return new Thread(r);
+        }
+    }
+
+
+    /**
+     *  execute successfully executes a runnable
+     */
+    public void testExecute() throws InterruptedException {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            p1.execute(new ShortRunnable());
+            Thread.sleep(SMALL_DELAY_MS);
+        } finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     *  getActiveCount increases but doesn't overestimate, when a
+     *  thread becomes active
+     */
+    public void testGetActiveCount() throws InterruptedException {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p2.getActiveCount());
+        p2.execute(new MediumRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, p2.getActiveCount());
+        joinPool(p2);
+    }
+
+    /**
+     *  prestartCoreThread starts a thread if under corePoolSize, else doesn't
+     */
+    public void testPrestartCoreThread() {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p2.getPoolSize());
+        assertTrue(p2.prestartCoreThread());
+        assertEquals(1, p2.getPoolSize());
+        assertTrue(p2.prestartCoreThread());
+        assertEquals(2, p2.getPoolSize());
+        assertFalse(p2.prestartCoreThread());
+        assertEquals(2, p2.getPoolSize());
+        joinPool(p2);
+    }
+
+    /**
+     *  prestartAllCoreThreads starts all corePoolSize threads
+     */
+    public void testPrestartAllCoreThreads() {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p2.getPoolSize());
+        p2.prestartAllCoreThreads();
+        assertEquals(2, p2.getPoolSize());
+        p2.prestartAllCoreThreads();
+        assertEquals(2, p2.getPoolSize());
+        joinPool(p2);
+    }
+
+    /**
+     *   getCompletedTaskCount increases, but doesn't overestimate,
+     *   when tasks complete
+     */
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p2.getCompletedTaskCount());
+        p2.execute(new ShortRunnable());
+        Thread.sleep(SMALL_DELAY_MS);
+        assertEquals(1, p2.getCompletedTaskCount());
+        try { p2.shutdown(); } catch (SecurityException ok) { return; }
+        joinPool(p2);
+    }
+
+    /**
+     *   getCorePoolSize returns size given in constructor if not otherwise set
+     */
+    public void testGetCorePoolSize() {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(1, p1.getCorePoolSize());
+        joinPool(p1);
+    }
+
+    /**
+     *   getKeepAliveTime returns value given in constructor if not otherwise set
+     */
+    public void testGetKeepAliveTime() {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(1, p2.getKeepAliveTime(TimeUnit.SECONDS));
+        joinPool(p2);
+    }
+
+
+    /**
+     * getThreadFactory returns factory in constructor if not set
+     */
+    public void testGetThreadFactory() {
+        ThreadFactory tf = new SimpleThreadFactory();
+        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), tf, new NoOpREHandler());
+        assertSame(tf, p.getThreadFactory());
+        joinPool(p);
+    }
+
+    /**
+     * setThreadFactory sets the thread factory returned by getThreadFactory
+     */
+    public void testSetThreadFactory() {
+        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadFactory tf = new SimpleThreadFactory();
+        p.setThreadFactory(tf);
+        assertSame(tf, p.getThreadFactory());
+        joinPool(p);
+    }
+
+
+    /**
+     * setThreadFactory(null) throws NPE
+     */
+    public void testSetThreadFactoryNull() {
+        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            p.setThreadFactory(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(p);
+        }
+    }
+
+    /**
+     * getRejectedExecutionHandler returns handler in constructor if not set
+     */
+    public void testGetRejectedExecutionHandler() {
+        RejectedExecutionHandler h = new NoOpREHandler();
+        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h);
+        assertSame(h, p.getRejectedExecutionHandler());
+        joinPool(p);
+    }
+
+    /**
+     * setRejectedExecutionHandler sets the handler returned by
+     * getRejectedExecutionHandler
+     */
+    public void testSetRejectedExecutionHandler() {
+        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        RejectedExecutionHandler h = new NoOpREHandler();
+        p.setRejectedExecutionHandler(h);
+        assertSame(h, p.getRejectedExecutionHandler());
+        joinPool(p);
+    }
+
+
+    /**
+     * setRejectedExecutionHandler(null) throws NPE
+     */
+    public void testSetRejectedExecutionHandlerNull() {
+        ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            p.setRejectedExecutionHandler(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(p);
+        }
+    }
+
+
+    /**
+     *   getLargestPoolSize increases, but doesn't overestimate, when
+     *   multiple threads active
+     */
+    public void testGetLargestPoolSize() throws InterruptedException {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p2.getLargestPoolSize());
+        p2.execute(new MediumRunnable());
+        p2.execute(new MediumRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, p2.getLargestPoolSize());
+        joinPool(p2);
+    }
+
+    /**
+     *   getMaximumPoolSize returns value given in constructor if not
+     *   otherwise set
+     */
+    public void testGetMaximumPoolSize() {
+        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(2, p2.getMaximumPoolSize());
+        joinPool(p2);
+    }
+
+    /**
+     *   getPoolSize increases, but doesn't overestimate, when threads
+     *   become active
+     */
+    public void testGetPoolSize() {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p1.getPoolSize());
+        p1.execute(new MediumRunnable());
+        assertEquals(1, p1.getPoolSize());
+        joinPool(p1);
+    }
+
+    /**
+     *  getTaskCount increases, but doesn't overestimate, when tasks submitted
+     */
+    public void testGetTaskCount() throws InterruptedException {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p1.getTaskCount());
+        p1.execute(new MediumRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, p1.getTaskCount());
+        joinPool(p1);
+    }
+
+    /**
+     *   isShutDown is false before shutdown, true after
+     */
+    public void testIsShutdown() {
+
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertFalse(p1.isShutdown());
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p1.isShutdown());
+        joinPool(p1);
+    }
+
+
+    /**
+     *  isTerminated is false before termination, true after
+     */
+    public void testIsTerminated() throws InterruptedException {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertFalse(p1.isTerminated());
+        try {
+            p1.execute(new MediumRunnable());
+        } finally {
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
+    }
+
+    /**
+     *  isTerminating is not true when running or when terminated
+     */
+    public void testIsTerminating() throws InterruptedException {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertFalse(p1.isTerminating());
+        try {
+            p1.execute(new SmallRunnable());
+            assertFalse(p1.isTerminating());
+        } finally {
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
+        assertFalse(p1.isTerminating());
+    }
+
+    /**
+     * getQueue returns the work queue, which contains queued tasks
+     */
+    public void testGetQueue() throws InterruptedException {
+        BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, q);
+        FutureTask[] tasks = new FutureTask[5];
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
+            p1.execute(tasks[i]);
+        }
+        try {
+            Thread.sleep(SHORT_DELAY_MS);
+            BlockingQueue<Runnable> wq = p1.getQueue();
+            assertSame(q, wq);
+            assertFalse(wq.contains(tasks[0]));
+            assertTrue(wq.contains(tasks[4]));
+            for (int i = 1; i < 5; ++i)
+                tasks[i].cancel(true);
+            p1.shutdownNow();
+        } finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     * remove(task) removes queued task, and fails to remove active task
+     */
+    public void testRemove() throws InterruptedException {
+        BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, q);
+        FutureTask[] tasks = new FutureTask[5];
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
+            p1.execute(tasks[i]);
+        }
+        try {
+            Thread.sleep(SHORT_DELAY_MS);
+            assertFalse(p1.remove(tasks[0]));
+            assertTrue(q.contains(tasks[4]));
+            assertTrue(q.contains(tasks[3]));
+            assertTrue(p1.remove(tasks[4]));
+            assertFalse(p1.remove(tasks[4]));
+            assertFalse(q.contains(tasks[4]));
+            assertTrue(q.contains(tasks[3]));
+            assertTrue(p1.remove(tasks[3]));
+            assertFalse(q.contains(tasks[3]));
+        } finally {
+            joinPool(p1);
+        }
+    }
+
+    /**
+     *   purge removes cancelled tasks from the queue
+     */
+    public void testPurge() {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        FutureTask[] tasks = new FutureTask[5];
+        for (int i = 0; i < 5; i++) {
+            tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
+            p1.execute(tasks[i]);
+        }
+        tasks[4].cancel(true);
+        tasks[3].cancel(true);
+        p1.purge();
+        long count = p1.getTaskCount();
+        assertTrue(count >= 2 && count < 5);
+        joinPool(p1);
+    }
+
+    /**
+     *  shutDownNow returns a list containing tasks that were not run
+     */
+    public void testShutDownNow() {
+        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List l;
+        try {
+            for (int i = 0; i < 5; i++)
+                p1.execute(new MediumPossiblyInterruptedRunnable());
+        }
+        finally {
+            try {
+                l = p1.shutdownNow();
+            } catch (SecurityException ok) { return; }
+        }
+        assertTrue(p1.isShutdown());
+        assertTrue(l.size() <= 4);
+    }
+
+    // Exception Tests
+
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor1() {
+        try {
+            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor2() {
+        try {
+            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor3() {
+        try {
+            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor4() {
+        try {
+            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor5() {
+        try {
+            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException() {
+        try {
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor6() {
+        try {
+            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor7() {
+        try {
+            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor8() {
+        try {
+            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor9() {
+        try {
+            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor10() {
+        try {
+            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException2() {
+        try {
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if threadFactory is set to null
+     */
+    public void testConstructorNullPointerException3() {
+        try {
+            ThreadFactory f = null;
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor11() {
+        try {
+            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor12() {
+        try {
+            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor13() {
+        try {
+            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor14() {
+        try {
+            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor15() {
+        try {
+            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException4() {
+        try {
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if handler is set to null
+     */
+    public void testConstructorNullPointerException5() {
+        try {
+            RejectedExecutionHandler r = null;
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor16() {
+        try {
+            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor17() {
+        try {
+            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor18() {
+        try {
+            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor19() {
+        try {
+            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor20() {
+        try {
+            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException6() {
+        try {
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if handler is set to null
+     */
+    public void testConstructorNullPointerException7() {
+        try {
+            RejectedExecutionHandler r = null;
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if ThreadFactory is set top null
+     */
+    public void testConstructorNullPointerException8() {
+        try {
+            ThreadFactory f = null;
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f,new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+
+    /**
+     *  execute throws RejectedExecutionException
+     *  if saturated.
+     */
+    public void testSaturatedExecute() {
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
+        try {
+
+            for (int i = 0; i < 5; ++i) {
+                p.execute(new MediumRunnable());
+            }
+            shouldThrow();
+        } catch (RejectedExecutionException success) {}
+        joinPool(p);
+    }
+
+    /**
+     *  executor using CallerRunsPolicy runs task if saturated.
+     */
+    public void testSaturatedExecute2() {
+        RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        try {
+
+            TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+            for (int i = 0; i < 5; ++i) {
+                tasks[i] = new TrackedNoOpRunnable();
+            }
+            TrackedLongRunnable mr = new TrackedLongRunnable();
+            p.execute(mr);
+            for (int i = 0; i < 5; ++i) {
+                p.execute(tasks[i]);
+            }
+            for (int i = 1; i < 5; ++i) {
+                assertTrue(tasks[i].done);
+            }
+            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+        } finally {
+            joinPool(p);
+        }
+    }
+
+    /**
+     *  executor using DiscardPolicy drops task if saturated.
+     */
+    public void testSaturatedExecute3() {
+        RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        try {
+
+            TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+            for (int i = 0; i < 5; ++i) {
+                tasks[i] = new TrackedNoOpRunnable();
+            }
+            p.execute(new TrackedLongRunnable());
+            for (int i = 0; i < 5; ++i) {
+                p.execute(tasks[i]);
+            }
+            for (int i = 0; i < 5; ++i) {
+                assertFalse(tasks[i].done);
+            }
+            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+        } finally {
+            joinPool(p);
+        }
+    }
+
+    /**
+     *  executor using DiscardOldestPolicy drops oldest task if saturated.
+     */
+    public void testSaturatedExecute4() {
+        RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        try {
+            p.execute(new TrackedLongRunnable());
+            TrackedLongRunnable r2 = new TrackedLongRunnable();
+            p.execute(r2);
+            assertTrue(p.getQueue().contains(r2));
+            TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
+            p.execute(r3);
+            assertFalse(p.getQueue().contains(r2));
+            assertTrue(p.getQueue().contains(r3));
+            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
+        } finally {
+            joinPool(p);
+        }
+    }
+
+    /**
+     *  execute throws RejectedExecutionException if shutdown
+     */
+    public void testRejectedExecutionExceptionOnShutdown() {
+        ThreadPoolExecutor tpe =
+            new CustomTPE(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
+        try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        try {
+            tpe.execute(new NoOpRunnable());
+            shouldThrow();
+        } catch (RejectedExecutionException success) {}
+
+        joinPool(tpe);
+    }
+
+    /**
+     *  execute using CallerRunsPolicy drops task on shutdown
+     */
+    public void testCallerRunsOnShutdown() {
+        RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        } finally {
+            joinPool(p);
+        }
+    }
+
+    /**
+     *  execute using DiscardPolicy drops task on shutdown
+     */
+    public void testDiscardOnShutdown() {
+        RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        } finally {
+            joinPool(p);
+        }
+    }
+
+
+    /**
+     *  execute using DiscardOldestPolicy drops task on shutdown
+     */
+    public void testDiscardOldestOnShutdown() {
+        RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
+        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        } finally {
+            joinPool(p);
+        }
+    }
+
+
+    /**
+     *  execute (null) throws NPE
+     */
+    public void testExecuteNull() {
+        ThreadPoolExecutor tpe = null;
+        try {
+            tpe = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+            tpe.execute(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+
+        joinPool(tpe);
+    }
+
+    /**
+     *  setCorePoolSize of negative value throws IllegalArgumentException
+     */
+    public void testCorePoolSizeIllegalArgumentException() {
+        ThreadPoolExecutor tpe =
+            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+        try {
+            tpe.setCorePoolSize(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        joinPool(tpe);
+    }
+
+    /**
+     *  setMaximumPoolSize(int) throws IllegalArgumentException if
+     *  given a value less the core pool size
+     */
+    public void testMaximumPoolSizeIllegalArgumentException() {
+        ThreadPoolExecutor tpe =
+            new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+        try {
+            tpe.setMaximumPoolSize(1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        joinPool(tpe);
+    }
+
+    /**
+     *  setMaximumPoolSize throws IllegalArgumentException
+     *  if given a negative value
+     */
+    public void testMaximumPoolSizeIllegalArgumentException2() {
+        ThreadPoolExecutor tpe =
+            new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+        try {
+            tpe.setMaximumPoolSize(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        joinPool(tpe);
+    }
+
+
+    /**
+     *  setKeepAliveTime  throws IllegalArgumentException
+     *  when given a negative value
+     */
+    public void testKeepAliveTimeIllegalArgumentException() {
+        ThreadPoolExecutor tpe =
+            new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+
+        try {
+            tpe.setKeepAliveTime(-1,MILLISECONDS);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        }
+        joinPool(tpe);
+    }
+
+    /**
+     * terminated() is called on termination
+     */
+    public void testTerminated() {
+        CustomTPE tpe = new CustomTPE();
+        try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(tpe.terminatedCalled);
+        joinPool(tpe);
+    }
+
+    /**
+     * beforeExecute and afterExecute are called when executing task
+     */
+    public void testBeforeAfter() throws InterruptedException {
+        CustomTPE tpe = new CustomTPE();
+        try {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            tpe.execute(r);
+            Thread.sleep(SHORT_DELAY_MS);
+            assertTrue(r.done);
+            assertTrue(tpe.beforeCalled);
+            assertTrue(tpe.afterCalled);
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
+        } finally {
+            joinPool(tpe);
+        }
+    }
+
+    /**
+     * completed submit of callable returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            Future<String> future = e.submit(new StringTask());
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * completed submit of runnable returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            Future<?> future = e.submit(new NoOpRunnable());
+            future.get();
+            assertTrue(future.isDone());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * completed submit of (runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            e.invokeAny(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            e.invokeAny(new ArrayList<Callable<String>>());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
+        try {
+            e.invokeAny(l);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            latch.countDown();
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testInvokeAny4() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        try {
+            e.invokeAny(l);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task
+     */
+    public void testInvokeAny5() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            e.invokeAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
+        try {
+            e.invokeAll(l);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures = e.invokeAll(l);
+        assertEquals(1, futures.size());
+        try {
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks
+     */
+    public void testInvokeAll5() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(,,null) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        try {
+            e.invokeAny(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
+        try {
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            latch.countDown();
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        try {
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(,,null) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        try {
+            e.invokeAll(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
+        try {
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures =
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+        assertEquals(1, futures.size());
+        try {
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * timed invokeAll(c) cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        try {
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
+            l.add(new StringTask());
+            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+            assertEquals(3, futures.size());
+            Iterator<Future<String>> it = futures.iterator();
+            Future<String> f1 = it.next();
+            Future<String> f2 = it.next();
+            Future<String> f3 = it.next();
+            assertTrue(f1.isDone());
+            assertTrue(f2.isDone());
+            assertTrue(f3.isDone());
+            assertFalse(f1.isCancelled());
+            assertTrue(f2.isCancelled());
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * Execution continues if there is at least one thread even if
+     * thread factory fails to create more
+     */
+    public void testFailingThreadFactory() throws InterruptedException {
+        ExecutorService e = new CustomTPE(100, 100, LONG_DELAY_MS, MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new FailingThreadFactory());
+        try {
+            for (int k = 0; k < 100; ++k) {
+                e.execute(new NoOpRunnable());
+            }
+            Thread.sleep(LONG_DELAY_MS);
+        } finally {
+            joinPool(e);
+        }
+    }
+
+    /**
+     * allowsCoreThreadTimeOut is by default false.
+     */
+    public void testAllowsCoreThreadTimeOut() {
+        ThreadPoolExecutor tpe = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertFalse(tpe.allowsCoreThreadTimeOut());
+        joinPool(tpe);
+    }
+
+    /**
+     * allowCoreThreadTimeOut(true) causes idle threads to time out
+     */
+    public void testAllowCoreThreadTimeOut_true() throws InterruptedException {
+        ThreadPoolExecutor tpe = new CustomTPE(2, 10, 10, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        tpe.allowCoreThreadTimeOut(true);
+        tpe.execute(new NoOpRunnable());
+        try {
+            Thread.sleep(MEDIUM_DELAY_MS);
+            assertEquals(0, tpe.getPoolSize());
+        } finally {
+            joinPool(tpe);
+        }
+    }
+
+    /**
+     * allowCoreThreadTimeOut(false) causes idle threads not to time out
+     */
+    public void testAllowCoreThreadTimeOut_false() throws InterruptedException {
+        ThreadPoolExecutor tpe = new CustomTPE(2, 10, 10, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        tpe.allowCoreThreadTimeOut(false);
+        tpe.execute(new NoOpRunnable());
+        try {
+            Thread.sleep(MEDIUM_DELAY_MS);
+            assertTrue(tpe.getPoolSize() >= 1);
+        } finally {
+            joinPool(tpe);
+        }
+    }
+
+}
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java
index 4f7cc46..9b7fcac 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadPoolExecutorTest.java
@@ -2,31 +2,29 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import java.util.concurrent.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import java.util.concurrent.atomic.*;
 import junit.framework.*;
 import java.util.*;
 
 public class ThreadPoolExecutorTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run (suite());        
-    }
     public static Test suite() {
         return new TestSuite(ThreadPoolExecutorTest.class);
     }
-    
+
     static class ExtendedTPE extends ThreadPoolExecutor {
         volatile boolean beforeCalled = false;
         volatile boolean afterCalled = false;
         volatile boolean terminatedCalled = false;
         public ExtendedTPE() {
-            super(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
+            super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
         }
         protected void beforeExecute(Thread t, Runnable r) {
             beforeCalled = true;
@@ -39,50 +37,37 @@
         }
     }
 
-    static class FailingThreadFactory implements ThreadFactory{
+    static class FailingThreadFactory implements ThreadFactory {
         int calls = 0;
-        public Thread newThread(Runnable r){
+        public Thread newThread(Runnable r) {
             if (++calls > 1) return null;
             return new Thread(r);
-        }   
+        }
     }
-    
+
 
     /**
      *  execute successfully executes a runnable
      */
-    public void testExecute() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testExecute() throws InterruptedException {
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            p1.execute(new Runnable() {
-                    public void run() {
-                        try {
-                            Thread.sleep(SHORT_DELAY_MS);
-                        } catch(InterruptedException e){
-                            threadUnexpectedException();
-                        }
-                    }
-                });
+            p1.execute(new ShortRunnable());
             Thread.sleep(SMALL_DELAY_MS);
-        } catch(InterruptedException e){
-            unexpectedException();
-        } 
-        joinPool(p1);
+        } finally {
+            joinPool(p1);
+        }
     }
 
     /**
      *  getActiveCount increases but doesn't overestimate, when a
      *  thread becomes active
      */
-    public void testGetActiveCount() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testGetActiveCount() throws InterruptedException {
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(0, p2.getActiveCount());
         p2.execute(new MediumRunnable());
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
         assertEquals(1, p2.getActiveCount());
         joinPool(p2);
     }
@@ -91,7 +76,7 @@
      *  prestartCoreThread starts a thread if under corePoolSize, else doesn't
      */
     public void testPrestartCoreThread() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(0, p2.getPoolSize());
         assertTrue(p2.prestartCoreThread());
         assertEquals(1, p2.getPoolSize());
@@ -106,7 +91,7 @@
      *  prestartAllCoreThreads starts all corePoolSize threads
      */
     public void testPrestartAllCoreThreads() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(0, p2.getPoolSize());
         p2.prestartAllCoreThreads();
         assertEquals(2, p2.getPoolSize());
@@ -114,59 +99,55 @@
         assertEquals(2, p2.getPoolSize());
         joinPool(p2);
     }
-    
+
     /**
      *   getCompletedTaskCount increases, but doesn't overestimate,
      *   when tasks complete
      */
-    public void testGetCompletedTaskCount() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(0, p2.getCompletedTaskCount());
         p2.execute(new ShortRunnable());
-        try {
-            Thread.sleep(SMALL_DELAY_MS);
-        } catch(Exception e){
-            unexpectedException();
-        }
+        Thread.sleep(SMALL_DELAY_MS);
         assertEquals(1, p2.getCompletedTaskCount());
-        try { p2.shutdown(); } catch(SecurityException ok) { return; }
+        try { p2.shutdown(); } catch (SecurityException ok) { return; }
         joinPool(p2);
     }
-    
+
     /**
      *   getCorePoolSize returns size given in constructor if not otherwise set
      */
     public void testGetCorePoolSize() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(1, p1.getCorePoolSize());
         joinPool(p1);
     }
-    
+
     /**
      *   getKeepAliveTime returns value given in constructor if not otherwise set
      */
     public void testGetKeepAliveTime() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(1, p2.getKeepAliveTime(TimeUnit.SECONDS));
         joinPool(p2);
     }
 
 
-    /** 
+    /**
      * getThreadFactory returns factory in constructor if not set
      */
     public void testGetThreadFactory() {
         ThreadFactory tf = new SimpleThreadFactory();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), tf, new NoOpREHandler());
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), tf, new NoOpREHandler());
         assertSame(tf, p.getThreadFactory());
         joinPool(p);
     }
 
-    /** 
+    /**
      * setThreadFactory sets the thread factory returned by getThreadFactory
      */
     public void testSetThreadFactory() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         ThreadFactory tf = new SimpleThreadFactory();
         p.setThreadFactory(tf);
         assertSame(tf, p.getThreadFactory());
@@ -174,11 +155,11 @@
     }
 
 
-    /** 
+    /**
      * setThreadFactory(null) throws NPE
      */
     public void testSetThreadFactoryNull() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             p.setThreadFactory(null);
             shouldThrow();
@@ -188,22 +169,22 @@
         }
     }
 
-    /** 
+    /**
      * getRejectedExecutionHandler returns handler in constructor if not set
      */
     public void testGetRejectedExecutionHandler() {
         RejectedExecutionHandler h = new NoOpREHandler();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h);
         assertSame(h, p.getRejectedExecutionHandler());
         joinPool(p);
     }
 
-    /** 
+    /**
      * setRejectedExecutionHandler sets the handler returned by
      * getRejectedExecutionHandler
      */
     public void testSetRejectedExecutionHandler() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         RejectedExecutionHandler h = new NoOpREHandler();
         p.setRejectedExecutionHandler(h);
         assertSame(h, p.getRejectedExecutionHandler());
@@ -211,11 +192,11 @@
     }
 
 
-    /** 
+    /**
      * setRejectedExecutionHandler(null) throws NPE
      */
     public void testSetRejectedExecutionHandlerNull() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             p.setRejectedExecutionHandler(null);
             shouldThrow();
@@ -225,124 +206,108 @@
         }
     }
 
-    
+
     /**
      *   getLargestPoolSize increases, but doesn't overestimate, when
      *   multiple threads active
      */
-    public void testGetLargestPoolSize() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            assertEquals(0, p2.getLargestPoolSize());
-            p2.execute(new MediumRunnable());
-            p2.execute(new MediumRunnable());
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(2, p2.getLargestPoolSize());
-        } catch(Exception e){
-            unexpectedException();
-        } 
+    public void testGetLargestPoolSize() throws InterruptedException {
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p2.getLargestPoolSize());
+        p2.execute(new MediumRunnable());
+        p2.execute(new MediumRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(2, p2.getLargestPoolSize());
         joinPool(p2);
     }
-    
+
     /**
      *   getMaximumPoolSize returns value given in constructor if not
      *   otherwise set
      */
     public void testGetMaximumPoolSize() {
-        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p2 = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(2, p2.getMaximumPoolSize());
         joinPool(p2);
     }
-    
+
     /**
      *   getPoolSize increases, but doesn't overestimate, when threads
      *   become active
      */
     public void testGetPoolSize() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertEquals(0, p1.getPoolSize());
         p1.execute(new MediumRunnable());
         assertEquals(1, p1.getPoolSize());
         joinPool(p1);
     }
-    
+
     /**
      *  getTaskCount increases, but doesn't overestimate, when tasks submitted
      */
-    public void testGetTaskCount() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
-        try {
-            assertEquals(0, p1.getTaskCount());
-            p1.execute(new MediumRunnable());
-            Thread.sleep(SHORT_DELAY_MS);
-            assertEquals(1, p1.getTaskCount());
-        } catch(Exception e){
-            unexpectedException();
-        } 
+    public void testGetTaskCount() throws InterruptedException {
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertEquals(0, p1.getTaskCount());
+        p1.execute(new MediumRunnable());
+        Thread.sleep(SHORT_DELAY_MS);
+        assertEquals(1, p1.getTaskCount());
         joinPool(p1);
     }
-    
+
     /**
      *   isShutDown is false before shutdown, true after
      */
     public void testIsShutdown() {
-        
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertFalse(p1.isShutdown());
-        try { p1.shutdown(); } catch(SecurityException ok) { return; }
+        try { p1.shutdown(); } catch (SecurityException ok) { return; }
         assertTrue(p1.isShutdown());
         joinPool(p1);
     }
 
-        
+
     /**
      *  isTerminated is false before termination, true after
      */
-    public void testIsTerminated() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testIsTerminated() throws InterruptedException {
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertFalse(p1.isTerminated());
         try {
             p1.execute(new MediumRunnable());
         } finally {
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
         }
-        try {
-            assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-            assertTrue(p1.isTerminated());
-        } catch(Exception e){
-            unexpectedException();
-        }        
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
     }
 
     /**
      *  isTerminating is not true when running or when terminated
      */
-    public void testIsTerminating() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testIsTerminating() throws InterruptedException {
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         assertFalse(p1.isTerminating());
         try {
             p1.execute(new SmallRunnable());
             assertFalse(p1.isTerminating());
         } finally {
-            try { p1.shutdown(); } catch(SecurityException ok) { return; }
+            try { p1.shutdown(); } catch (SecurityException ok) { return; }
         }
-        try {
-            assertTrue(p1.awaitTermination(LONG_DELAY_MS, TimeUnit.MILLISECONDS));
-            assertTrue(p1.isTerminated());
-            assertFalse(p1.isTerminating());
-        } catch(Exception e){
-            unexpectedException();
-        }        
+        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p1.isTerminated());
+        assertFalse(p1.isTerminating());
     }
 
     /**
      * getQueue returns the work queue, which contains queued tasks
      */
-    public void testGetQueue() {
+    public void testGetQueue() throws InterruptedException {
         BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, q);
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, q);
         FutureTask[] tasks = new FutureTask[5];
-        for(int i = 0; i < 5; i++){
+        for (int i = 0; i < 5; i++) {
             tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
             p1.execute(tasks[i]);
         }
@@ -355,8 +320,6 @@
             for (int i = 1; i < 5; ++i)
                 tasks[i].cancel(true);
             p1.shutdownNow();
-        } catch(Exception e) {
-            unexpectedException();
         } finally {
             joinPool(p1);
         }
@@ -365,11 +328,11 @@
     /**
      * remove(task) removes queued task, and fails to remove active task
      */
-    public void testRemove() {
+    public void testRemove() throws InterruptedException {
         BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, q);
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, q);
         FutureTask[] tasks = new FutureTask[5];
-        for(int i = 0; i < 5; i++){
+        for (int i = 0; i < 5; i++) {
             tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
             p1.execute(tasks[i]);
         }
@@ -384,8 +347,6 @@
             assertTrue(q.contains(tasks[3]));
             assertTrue(p1.remove(tasks[3]));
             assertFalse(q.contains(tasks[3]));
-        } catch(Exception e) {
-            unexpectedException();
         } finally {
             joinPool(p1);
         }
@@ -395,9 +356,9 @@
      *   purge removes cancelled tasks from the queue
      */
     public void testPurge() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         FutureTask[] tasks = new FutureTask[5];
-        for(int i = 0; i < 5; i++){
+        for (int i = 0; i < 5; i++) {
             tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
             p1.execute(tasks[i]);
         }
@@ -413,355 +374,334 @@
      *  shutDownNow returns a list containing tasks that were not run
      */
     public void testShutDownNow() {
-        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        ThreadPoolExecutor p1 = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         List l;
         try {
-            for(int i = 0; i < 5; i++)
+            for (int i = 0; i < 5; i++)
                 p1.execute(new MediumPossiblyInterruptedRunnable());
         }
         finally {
             try {
                 l = p1.shutdownNow();
             } catch (SecurityException ok) { return; }
-            
         }
         assertTrue(p1.isShutdown());
         assertTrue(l.size() <= 4);
     }
 
     // Exception Tests
-    
 
-    /** 
-     * Constructor throws if corePoolSize argument is less than zero 
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
      */
     public void testConstructor1() {
         try {
-            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
-    
-    /** 
-     * Constructor throws if maximumPoolSize is less than zero 
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
      */
     public void testConstructor2() {
         try {
-            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
-    
-    /** 
-     * Constructor throws if maximumPoolSize is equal to zero 
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
      */
     public void testConstructor3() {
         try {
-            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if keepAliveTime is less than zero 
+    /**
+     * Constructor throws if keepAliveTime is less than zero
      */
     public void testConstructor4() {
         try {
-            new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new ThreadPoolExecutor(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if corePoolSize is greater than the maximumPoolSize 
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
      */
     public void testConstructor5() {
         try {
-            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
-        
-    /** 
-     * Constructor throws if workQueue is set to null 
+
+    /**
+     * Constructor throws if workQueue is set to null
      */
     public void testConstructorNullPointerException() {
         try {
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null);
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,null);
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
-    
 
-    
-    /** 
-     * Constructor throws if corePoolSize argument is less than zero 
+
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
      */
     public void testConstructor6() {
         try {
-            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
             shouldThrow();
-        } catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
-    
-    /** 
-     * Constructor throws if maximumPoolSize is less than zero 
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
      */
     public void testConstructor7() {
         try {
-            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if maximumPoolSize is equal to zero 
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
      */
     public void testConstructor8() {
         try {
-            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if keepAliveTime is less than zero 
+    /**
+     * Constructor throws if keepAliveTime is less than zero
      */
     public void testConstructor9() {
         try {
-            new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new ThreadPoolExecutor(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if corePoolSize is greater than the maximumPoolSize 
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
      */
     public void testConstructor10() {
         try {
-            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
+            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if workQueue is set to null 
+    /**
+     * Constructor throws if workQueue is set to null
      */
     public void testConstructorNullPointerException2() {
         try {
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null,new SimpleThreadFactory());
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory());
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
 
-    /** 
-     * Constructor throws if threadFactory is set to null 
+    /**
+     * Constructor throws if threadFactory is set to null
      */
     public void testConstructorNullPointerException3() {
         try {
             ThreadFactory f = null;
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f);
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f);
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
- 
-    
-    /** 
-     * Constructor throws if corePoolSize argument is less than zero 
+
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
      */
     public void testConstructor11() {
         try {
-            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if maximumPoolSize is less than zero 
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
      */
     public void testConstructor12() {
         try {
-            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if maximumPoolSize is equal to zero 
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
      */
     public void testConstructor13() {
         try {
-            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if keepAliveTime is less than zero 
+    /**
+     * Constructor throws if keepAliveTime is less than zero
      */
     public void testConstructor14() {
         try {
-            new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new ThreadPoolExecutor(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if corePoolSize is greater than the maximumPoolSize 
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
      */
     public void testConstructor15() {
         try {
-            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
+            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if workQueue is set to null 
+    /**
+     * Constructor throws if workQueue is set to null
      */
     public void testConstructorNullPointerException4() {
         try {
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null,new NoOpREHandler());
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,null,new NoOpREHandler());
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
 
-    /** 
-     * Constructor throws if handler is set to null 
+    /**
+     * Constructor throws if handler is set to null
      */
     public void testConstructorNullPointerException5() {
         try {
             RejectedExecutionHandler r = null;
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r);
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r);
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
 
-    
-    /** 
-     * Constructor throws if corePoolSize argument is less than zero 
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
      */
     public void testConstructor16() {
         try {
-            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new ThreadPoolExecutor(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if maximumPoolSize is less than zero 
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
      */
     public void testConstructor17() {
         try {
-            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new ThreadPoolExecutor(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if maximumPoolSize is equal to zero 
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
      */
     public void testConstructor18() {
         try {
-            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new ThreadPoolExecutor(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if keepAliveTime is less than zero 
+    /**
+     * Constructor throws if keepAliveTime is less than zero
      */
     public void testConstructor19() {
         try {
-            new ThreadPoolExecutor(1,2,-1L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new ThreadPoolExecutor(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if corePoolSize is greater than the maximumPoolSize 
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
      */
     public void testConstructor20() {
         try {
-            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
+            new ThreadPoolExecutor(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (IllegalArgumentException success){}
+        } catch (IllegalArgumentException success) {}
     }
 
-    /** 
-     * Constructor throws if workQueue is set to null 
+    /**
+     * Constructor throws if workQueue is set to null
      */
     public void testConstructorNullPointerException6() {
         try {
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler());
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler());
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
 
-    /** 
-     * Constructor throws if handler is set to null 
+    /**
+     * Constructor throws if handler is set to null
      */
     public void testConstructorNullPointerException7() {
         try {
             RejectedExecutionHandler r = null;
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r);
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r);
             shouldThrow();
-        }
-        catch (NullPointerException success){}  
+        } catch (NullPointerException success) {}
     }
 
-    /** 
-     * Constructor throws if ThreadFactory is set top null 
+    /**
+     * Constructor throws if ThreadFactory is set top null
      */
     public void testConstructorNullPointerException8() {
         try {
             ThreadFactory f = null;
-            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f,new NoOpREHandler());
+            new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f,new NoOpREHandler());
             shouldThrow();
-        }
-        catch (NullPointerException successdn8){}  
+        } catch (NullPointerException success) {}
     }
-    
+
 
     /**
      *  execute throws RejectedExecutionException
      *  if saturated.
      */
     public void testSaturatedExecute() {
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
+        ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
         try {
-            
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 2; ++i)
                 p.execute(new MediumRunnable());
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.execute(new MediumRunnable());
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
             }
-            shouldThrow();
-        } catch(RejectedExecutionException success){}
-        joinPool(p);
+        } finally {
+            joinPool(p);
+        }
     }
 
     /**
@@ -769,24 +709,22 @@
      */
     public void testSaturatedExecute2() {
         RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
         try {
-            
+
             TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 5; ++i) {
                 tasks[i] = new TrackedNoOpRunnable();
             }
             TrackedLongRunnable mr = new TrackedLongRunnable();
             p.execute(mr);
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 5; ++i) {
                 p.execute(tasks[i]);
             }
-            for(int i = 1; i < 5; ++i) {
+            for (int i = 1; i < 5; ++i) {
                 assertTrue(tasks[i].done);
             }
-            try { p.shutdownNow(); } catch(SecurityException ok) { return; }
-        } catch(RejectedExecutionException ex){
-            unexpectedException();
+            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
         } finally {
             joinPool(p);
         }
@@ -797,23 +735,21 @@
      */
     public void testSaturatedExecute3() {
         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
         try {
-            
+
             TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 5; ++i) {
                 tasks[i] = new TrackedNoOpRunnable();
             }
             p.execute(new TrackedLongRunnable());
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 5; ++i) {
                 p.execute(tasks[i]);
             }
-            for(int i = 0; i < 5; ++i){
+            for (int i = 0; i < 5; ++i) {
                 assertFalse(tasks[i].done);
             }
-            try { p.shutdownNow(); } catch(SecurityException ok) { return; }
-        } catch(RejectedExecutionException ex){
-            unexpectedException();
+            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
         } finally {
             joinPool(p);
         }
@@ -824,7 +760,7 @@
      */
     public void testSaturatedExecute4() {
         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
         try {
             p.execute(new TrackedLongRunnable());
             TrackedLongRunnable r2 = new TrackedLongRunnable();
@@ -834,9 +770,7 @@
             p.execute(r3);
             assertFalse(p.getQueue().contains(r2));
             assertTrue(p.getQueue().contains(r3));
-            try { p.shutdownNow(); } catch(SecurityException ok) { return; }
-        } catch(RejectedExecutionException ex){
-            unexpectedException();
+            try { p.shutdownNow(); } catch (SecurityException ok) { return; }
         } finally {
             joinPool(p);
         }
@@ -846,14 +780,14 @@
      *  execute throws RejectedExecutionException if shutdown
      */
     public void testRejectedExecutionExceptionOnShutdown() {
-        ThreadPoolExecutor tpe = 
-            new ThreadPoolExecutor(1,1,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
-        try { tpe.shutdown(); } catch(SecurityException ok) { return; }
+        ThreadPoolExecutor tpe =
+            new ThreadPoolExecutor(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
+        try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         try {
             tpe.execute(new NoOpRunnable());
             shouldThrow();
-        } catch(RejectedExecutionException success){}
-        
+        } catch (RejectedExecutionException success) {}
+
         joinPool(tpe);
     }
 
@@ -862,15 +796,13 @@
      */
     public void testCallerRunsOnShutdown() {
         RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
 
-        try { p.shutdown(); } catch(SecurityException ok) { return; }
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
         try {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } catch(RejectedExecutionException success){
-            unexpectedException();
         } finally {
             joinPool(p);
         }
@@ -881,15 +813,13 @@
      */
     public void testDiscardOnShutdown() {
         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
 
-        try { p.shutdown(); } catch(SecurityException ok) { return; }
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
         try {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } catch(RejectedExecutionException success){
-            unexpectedException();
         } finally {
             joinPool(p);
         }
@@ -901,15 +831,13 @@
      */
     public void testDiscardOldestOnShutdown() {
         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
-        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
+        ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
 
-        try { p.shutdown(); } catch(SecurityException ok) { return; }
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
         try {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
             p.execute(r);
             assertFalse(r.done);
-        } catch(RejectedExecutionException success){
-            unexpectedException();
         } finally {
             joinPool(p);
         }
@@ -920,89 +848,87 @@
      *  execute (null) throws NPE
      */
     public void testExecuteNull() {
-        ThreadPoolExecutor tpe = null;
+        ThreadPoolExecutor tpe = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
         try {
-            tpe = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
             tpe.execute(null);
             shouldThrow();
-        } catch(NullPointerException success){}
-        
+        } catch (NullPointerException success) {}
+
         joinPool(tpe);
     }
-    
+
     /**
      *  setCorePoolSize of negative value throws IllegalArgumentException
      */
     public void testCorePoolSizeIllegalArgumentException() {
-        ThreadPoolExecutor tpe = null;
-        try {
-            tpe = new ThreadPoolExecutor(1,2,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        } catch(Exception e){}
+        ThreadPoolExecutor tpe =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
         try {
             tpe.setCorePoolSize(-1);
             shouldThrow();
-        } catch(IllegalArgumentException success){
+        } catch (IllegalArgumentException success) {
         } finally {
-            try { tpe.shutdown(); } catch(SecurityException ok) { return; }
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         }
         joinPool(tpe);
-    }   
+    }
 
     /**
      *  setMaximumPoolSize(int) throws IllegalArgumentException if
      *  given a value less the core pool size
-     */  
+     */
     public void testMaximumPoolSizeIllegalArgumentException() {
-        ThreadPoolExecutor tpe = null;
-        try {
-            tpe = new ThreadPoolExecutor(2,3,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        } catch(Exception e){}
+        ThreadPoolExecutor tpe =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
         try {
             tpe.setMaximumPoolSize(1);
             shouldThrow();
-        } catch(IllegalArgumentException success){
+        } catch (IllegalArgumentException success) {
         } finally {
-            try { tpe.shutdown(); } catch(SecurityException ok) { return; }
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         }
         joinPool(tpe);
     }
-    
+
     /**
      *  setMaximumPoolSize throws IllegalArgumentException
      *  if given a negative value
      */
     public void testMaximumPoolSizeIllegalArgumentException2() {
-        ThreadPoolExecutor tpe = null;
-        try {
-            tpe = new ThreadPoolExecutor(2,3,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        } catch(Exception e){}
+        ThreadPoolExecutor tpe =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
         try {
             tpe.setMaximumPoolSize(-1);
             shouldThrow();
-        } catch(IllegalArgumentException success){
+        } catch (IllegalArgumentException success) {
         } finally {
-            try { tpe.shutdown(); } catch(SecurityException ok) { return; }
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         }
         joinPool(tpe);
     }
-    
+
 
     /**
      *  setKeepAliveTime  throws IllegalArgumentException
      *  when given a negative value
      */
     public void testKeepAliveTimeIllegalArgumentException() {
-        ThreadPoolExecutor tpe = null;
+        ThreadPoolExecutor tpe =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
         try {
-            tpe = new ThreadPoolExecutor(2,3,LONG_DELAY_MS, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
-        } catch(Exception e){}
-        
-        try {
-            tpe.setKeepAliveTime(-1,TimeUnit.MILLISECONDS);
+            tpe.setKeepAliveTime(-1,MILLISECONDS);
             shouldThrow();
-        } catch(IllegalArgumentException success){
+        } catch (IllegalArgumentException success) {
         } finally {
-            try { tpe.shutdown(); } catch(SecurityException ok) { return; }
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         }
         joinPool(tpe);
     }
@@ -1012,7 +938,7 @@
      */
     public void testTerminated() {
         ExtendedTPE tpe = new ExtendedTPE();
-        try { tpe.shutdown(); } catch(SecurityException ok) { return; }
+        try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         assertTrue(tpe.terminatedCalled);
         joinPool(tpe);
     }
@@ -1020,7 +946,7 @@
     /**
      * beforeExecute and afterExecute are called when executing task
      */
-    public void testBeforeAfter() {
+    public void testBeforeAfter() throws InterruptedException {
         ExtendedTPE tpe = new ExtendedTPE();
         try {
             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
@@ -1029,10 +955,7 @@
             assertTrue(r.done);
             assertTrue(tpe.beforeCalled);
             assertTrue(tpe.afterCalled);
-            try { tpe.shutdown(); } catch(SecurityException ok) { return; }
-        }
-        catch(Exception ex) {
-            unexpectedException();
+            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
         } finally {
             joinPool(tpe);
         }
@@ -1041,18 +964,12 @@
     /**
      * completed submit of callable returns result
      */
-    public void testSubmitCallable() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testSubmitCallable() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             Future<String> future = e.submit(new StringTask());
             String result = future.get();
             assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1061,18 +978,12 @@
     /**
      * completed submit of runnable returns successfully
      */
-    public void testSubmitRunnable() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testSubmitRunnable() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             Future<?> future = e.submit(new NoOpRunnable());
             future.get();
             assertTrue(future.isDone());
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1081,37 +992,27 @@
     /**
      * completed submit of (runnable, result) returns result
      */
-    public void testSubmitRunnable2() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testSubmitRunnable2() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
             String result = future.get();
             assertSame(TEST_STRING, result);
-        }
-        catch (ExecutionException ex) {
-            unexpectedException();
-        }
-        catch (InterruptedException ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
     }
 
 
-
-
-
     /**
      * invokeAny(null) throws NPE
      */
-    public void testInvokeAny1() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAny1() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             e.invokeAny(null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1120,13 +1021,12 @@
     /**
      * invokeAny(empty collection) throws IAE
      */
-    public void testInvokeAny2() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAny2() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             e.invokeAny(new ArrayList<Callable<String>>());
+            shouldThrow();
         } catch (IllegalArgumentException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1135,17 +1035,18 @@
     /**
      * invokeAny(c) throws NPE if c has null elements
      */
-    public void testInvokeAny3() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
             e.invokeAny(l);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
+            latch.countDown();
             joinPool(e);
         }
     }
@@ -1153,15 +1054,15 @@
     /**
      * invokeAny(c) throws ExecutionException if no task completes
      */
-    public void testInvokeAny4() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAny4() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
             e.invokeAny(l);
+            shouldThrow();
         } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -1170,17 +1071,14 @@
     /**
      * invokeAny(c) returns result of some task
      */
-    public void testInvokeAny5() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAny5() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
             String result = e.invokeAny(l);
             assertSame(TEST_STRING, result);
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1189,13 +1087,12 @@
     /**
      * invokeAll(null) throws NPE
      */
-    public void testInvokeAll1() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAll1() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             e.invokeAll(null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1204,13 +1101,11 @@
     /**
      * invokeAll(empty collection) returns empty collection
      */
-    public void testInvokeAll2() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAll2() throws InterruptedException {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
             assertTrue(r.isEmpty());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1219,16 +1114,15 @@
     /**
      * invokeAll(c) throws NPE if c has null elements
      */
-    public void testInvokeAll3() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAll3() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
             e.invokeAll(l);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1237,18 +1131,19 @@
     /**
      * get of element of invokeAll(c) throws exception on failed task
      */
-    public void testInvokeAll4() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAll4() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new NPETask());
-            List<Future<String>> result = e.invokeAll(l);
-            assertEquals(1, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                it.next().get();
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
         } finally {
             joinPool(e);
         }
@@ -1257,19 +1152,16 @@
     /**
      * invokeAll(c) returns results of all completed tasks
      */
-    public void testInvokeAll5() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testInvokeAll5() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l);
-            assertEquals(2, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                assertSame(TEST_STRING, it.next().get());
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
         } finally {
             joinPool(e);
         }
@@ -1280,13 +1172,12 @@
     /**
      * timed invokeAny(null) throws NPE
      */
-    public void testTimedInvokeAny1() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAny1() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            e.invokeAny(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1295,15 +1186,14 @@
     /**
      * timed invokeAny(,,null) throws NPE
      */
-    public void testTimedInvokeAnyNullTimeUnit() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
             e.invokeAny(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1312,13 +1202,12 @@
     /**
      * timed invokeAny(empty collection) throws IAE
      */
-    public void testTimedInvokeAny2() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAny2() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (IllegalArgumentException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1327,18 +1216,18 @@
     /**
      * timed invokeAny(c) throws NPE if c has null elements
      */
-    public void testTimedInvokeAny3() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(latchAwaitingStringTask(latch));
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
-            e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            ex.printStackTrace();
-            unexpectedException();
         } finally {
+            latch.countDown();
             joinPool(e);
         }
     }
@@ -1346,15 +1235,15 @@
     /**
      * timed invokeAny(c) throws ExecutionException if no task completes
      */
-    public void testTimedInvokeAny4() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAny4() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
-            e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -1363,17 +1252,14 @@
     /**
      * timed invokeAny(c) returns result of some task
      */
-    public void testTimedInvokeAny5() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAny5() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            String result = e.invokeAny(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
             assertSame(TEST_STRING, result);
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1382,13 +1268,12 @@
     /**
      * timed invokeAll(null) throws NPE
      */
-    public void testTimedInvokeAll1() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAll1() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            e.invokeAll(null, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1397,15 +1282,14 @@
     /**
      * timed invokeAll(,,null) throws NPE
      */
-    public void testTimedInvokeAllNullTimeUnit() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
             e.invokeAll(l, MEDIUM_DELAY_MS, null);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1414,13 +1298,11 @@
     /**
      * timed invokeAll(empty collection) returns empty collection
      */
-    public void testTimedInvokeAll2() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAll2() throws InterruptedException {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
             assertTrue(r.isEmpty());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1429,16 +1311,15 @@
     /**
      * timed invokeAll(c) throws NPE if c has null elements
      */
-    public void testTimedInvokeAll3() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAll3() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new StringTask());
+        l.add(null);
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new StringTask());
-            l.add(null);
-            e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            shouldThrow();
         } catch (NullPointerException success) {
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1447,18 +1328,18 @@
     /**
      * get of element of invokeAll(c) throws exception on failed task
      */
-    public void testTimedInvokeAll4() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAll4() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        List<Callable<String>> l = new ArrayList<Callable<String>>();
+        l.add(new NPETask());
+        List<Future<String>> futures =
+            e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+        assertEquals(1, futures.size());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
-            l.add(new NPETask());
-            List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(1, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                it.next().get();
-        } catch(ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            futures.get(0).get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertTrue(success.getCause() instanceof NullPointerException);
         } finally {
             joinPool(e);
         }
@@ -1467,19 +1348,17 @@
     /**
      * timed invokeAll(c) returns results of all completed tasks
      */
-    public void testTimedInvokeAll5() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAll5() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(2, result.size());
-            for (Iterator<Future<String>> it = result.iterator(); it.hasNext();) 
-                assertSame(TEST_STRING, it.next().get());
-        } catch (ExecutionException success) {
-        } catch(Exception ex) {
-            unexpectedException();
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
         } finally {
             joinPool(e);
         }
@@ -1488,16 +1367,17 @@
     /**
      * timed invokeAll(c) cancels tasks not completed by timeout
      */
-    public void testTimedInvokeAll6() {
-        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+    public void testTimedInvokeAll6() throws Exception {
+        ExecutorService e = new ThreadPoolExecutor(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             l.add(new StringTask());
             l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
             l.add(new StringTask());
-            List<Future<String>> result = e.invokeAll(l, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
-            assertEquals(3, result.size());
-            Iterator<Future<String>> it = result.iterator(); 
+            List<Future<String>> futures =
+                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
+            assertEquals(3, futures.size());
+            Iterator<Future<String>> it = futures.iterator();
             Future<String> f1 = it.next();
             Future<String> f2 = it.next();
             Future<String> f3 = it.next();
@@ -1506,8 +1386,6 @@
             assertTrue(f3.isDone());
             assertFalse(f1.isCancelled());
             assertTrue(f2.isCancelled());
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
@@ -1517,34 +1395,71 @@
      * Execution continues if there is at least one thread even if
      * thread factory fails to create more
      */
-    public void testFailingThreadFactory() {
-        ExecutorService e = new ThreadPoolExecutor(100, 100, LONG_DELAY_MS, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new FailingThreadFactory());
+    public void testFailingThreadFactory() throws InterruptedException {
+        ExecutorService e = new ThreadPoolExecutor(100, 100, LONG_DELAY_MS, MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new FailingThreadFactory());
         try {
-            ArrayList<Callable<String>> l = new ArrayList<Callable<String>>();
+            List<Callable<String>> l = new ArrayList<Callable<String>>();
             for (int k = 0; k < 100; ++k) {
                 e.execute(new NoOpRunnable());
             }
             Thread.sleep(LONG_DELAY_MS);
-        } catch(Exception ex) {
-            unexpectedException();
         } finally {
             joinPool(e);
         }
     }
 
     /**
+     * allowsCoreThreadTimeOut is by default false.
+     */
+    public void testAllowsCoreThreadTimeOut() {
+        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        assertFalse(tpe.allowsCoreThreadTimeOut());
+        joinPool(tpe);
+    }
+
+    /**
+     * allowCoreThreadTimeOut(true) causes idle threads to time out
+     */
+    public void testAllowCoreThreadTimeOut_true() throws InterruptedException {
+        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 10, 10, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        tpe.allowCoreThreadTimeOut(true);
+        tpe.execute(new NoOpRunnable());
+        try {
+            Thread.sleep(MEDIUM_DELAY_MS);
+            assertEquals(0, tpe.getPoolSize());
+        } finally {
+            joinPool(tpe);
+        }
+    }
+
+    /**
+     * allowCoreThreadTimeOut(false) causes idle threads not to time out
+     */
+    public void testAllowCoreThreadTimeOut_false() throws InterruptedException {
+        ThreadPoolExecutor tpe = new ThreadPoolExecutor(2, 10, 10, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+        tpe.allowCoreThreadTimeOut(false);
+        tpe.execute(new NoOpRunnable());
+        try {
+            Thread.sleep(MEDIUM_DELAY_MS);
+            assertTrue(tpe.getPoolSize() >= 1);
+        } finally {
+            joinPool(tpe);
+        }
+    }
+
+    /**
      * execute allows the same task to be submitted multiple times, even
      * if rejected
      */
-    public void testRejectedRecycledTask() {
+    public void testRejectedRecycledTask() throws InterruptedException {
         final int nTasks = 1000;
         final AtomicInteger nRun = new AtomicInteger(0);
         final Runnable recycledTask = new Runnable() {
                 public void run() {
                     nRun.getAndIncrement();
                 } };
-        final ThreadPoolExecutor p = 
-            new ThreadPoolExecutor(1, 30, 60, TimeUnit.SECONDS, 
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 30, 60, TimeUnit.SECONDS,
                                    new ArrayBlockingQueue(30));
         try {
             for (int i = 0; i < nTasks; ++i) {
@@ -1559,12 +1474,9 @@
             }
             Thread.sleep(5000); // enough time to run all tasks
             assertEquals(nRun.get(), nTasks);
-        } catch(Exception ex) {
-            ex.printStackTrace();
-            unexpectedException();
         } finally {
             p.shutdown();
         }
     }
-            
+
 }
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java
index 253d9eb..e9f28ac 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/ThreadTest.java
@@ -2,23 +2,15 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
-
-// BEGIN android-added
-import dalvik.annotation.BrokenTest;
-// END android-added
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 
 public class ThreadTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());        
-    }
-    
     public static Test suite() {
         return new TestSuite(ThreadTest.class);
     }
@@ -28,7 +20,7 @@
             e.printStackTrace();
         }
     }
-    
+
     /**
      * getUncaughtExceptionHandler returns ThreadGroup unless set,
      * otherwise returning value of last setUncaughtExceptionHandler.
@@ -48,11 +40,8 @@
 
     /**
      * getDefaultUncaughtExceptionHandler returns value of last
-     * setDefaultUncaughtExceptionHandler. 
+     * setDefaultUncaughtExceptionHandler.
      */
-    // BEGIN android-added
-    @BrokenTest("Different behavior between run-core-tests and CTS")
-    // END android-added
     public void testGetAndSetDefaultUncaughtExceptionHandler() {
         assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
         // failure due to securityException is OK.
@@ -65,13 +54,12 @@
             assertEquals(eh, Thread.getDefaultUncaughtExceptionHandler());
             Thread.setDefaultUncaughtExceptionHandler(null);
         }
-        catch(SecurityException ok) {
+        catch (SecurityException ok) {
         }
         assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
     }
 
-    
+
     // How to test actually using UEH within junit?
 
 }
-
diff --git a/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java b/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java
index 54fdc69..84be0c4 100755
--- a/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java
+++ b/concurrent/src/test/java/tests/api/java/util/concurrent/TimeUnitTest.java
@@ -2,21 +2,17 @@
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
  * http://creativecommons.org/licenses/publicdomain
- * Other contributors include Andrew Wright, Jeffrey Hayes, 
- * Pat Fisher, Mike Judd. 
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
  */
 
-package tests.api.java.util.concurrent;
+package tests.api.java.util.concurrent; // android-added
 
 import junit.framework.*;
 import java.util.concurrent.*;
 import java.io.*;
 
 public class TimeUnitTest extends JSR166TestCase {
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());        
-    }
-    
     public static Test suite() {
         return new TestSuite(TimeUnitTest.class);
     }
@@ -28,57 +24,93 @@
      */
     public void testConvert() {
         for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*60*60*24,
+                         TimeUnit.SECONDS.convert(t,
+                                                  TimeUnit.DAYS));
+            assertEquals(t*60*60,
+                         TimeUnit.SECONDS.convert(t,
+                                                  TimeUnit.HOURS));
+            assertEquals(t*60,
+                         TimeUnit.SECONDS.convert(t,
+                                                  TimeUnit.MINUTES));
             assertEquals(t,
-                         TimeUnit.SECONDS.convert(t, 
+                         TimeUnit.SECONDS.convert(t,
                                                   TimeUnit.SECONDS));
-            assertEquals(t, 
-                         TimeUnit.SECONDS.convert(1000L*t, 
+            assertEquals(t,
+                         TimeUnit.SECONDS.convert(1000L*t,
                                                   TimeUnit.MILLISECONDS));
-            assertEquals(t, 
-                         TimeUnit.SECONDS.convert(1000000L*t, 
+            assertEquals(t,
+                         TimeUnit.SECONDS.convert(1000000L*t,
                                                   TimeUnit.MICROSECONDS));
-            assertEquals(t, 
-                         TimeUnit.SECONDS.convert(1000000000L*t, 
+            assertEquals(t,
+                         TimeUnit.SECONDS.convert(1000000000L*t,
                                                   TimeUnit.NANOSECONDS));
 
 
+            assertEquals(1000L*t*60*60*24,
+                         TimeUnit.MILLISECONDS.convert(t,
+                                                  TimeUnit.DAYS));
+            assertEquals(1000L*t*60*60,
+                         TimeUnit.MILLISECONDS.convert(t,
+                                                  TimeUnit.HOURS));
+            assertEquals(1000L*t*60,
+                         TimeUnit.MILLISECONDS.convert(t,
+                                                  TimeUnit.MINUTES));
             assertEquals(1000L*t,
-                         TimeUnit.MILLISECONDS.convert(t, 
+                         TimeUnit.MILLISECONDS.convert(t,
                                                   TimeUnit.SECONDS));
-            assertEquals(t, 
-                         TimeUnit.MILLISECONDS.convert(t, 
+            assertEquals(t,
+                         TimeUnit.MILLISECONDS.convert(t,
                                                   TimeUnit.MILLISECONDS));
-            assertEquals(t, 
-                         TimeUnit.MILLISECONDS.convert(1000L*t, 
+            assertEquals(t,
+                         TimeUnit.MILLISECONDS.convert(1000L*t,
                                                   TimeUnit.MICROSECONDS));
-            assertEquals(t, 
-                         TimeUnit.MILLISECONDS.convert(1000000L*t, 
+            assertEquals(t,
+                         TimeUnit.MILLISECONDS.convert(1000000L*t,
                                                   TimeUnit.NANOSECONDS));
 
+            assertEquals(1000000L*t*60*60*24,
+                         TimeUnit.MICROSECONDS.convert(t,
+                                                  TimeUnit.DAYS));
+            assertEquals(1000000L*t*60*60,
+                         TimeUnit.MICROSECONDS.convert(t,
+                                                  TimeUnit.HOURS));
+            assertEquals(1000000L*t*60,
+                         TimeUnit.MICROSECONDS.convert(t,
+                                                  TimeUnit.MINUTES));
             assertEquals(1000000L*t,
-                         TimeUnit.MICROSECONDS.convert(t, 
+                         TimeUnit.MICROSECONDS.convert(t,
                                                   TimeUnit.SECONDS));
-            assertEquals(1000L*t, 
-                         TimeUnit.MICROSECONDS.convert(t, 
+            assertEquals(1000L*t,
+                         TimeUnit.MICROSECONDS.convert(t,
                                                   TimeUnit.MILLISECONDS));
-            assertEquals(t, 
-                         TimeUnit.MICROSECONDS.convert(t, 
+            assertEquals(t,
+                         TimeUnit.MICROSECONDS.convert(t,
                                                   TimeUnit.MICROSECONDS));
-            assertEquals(t, 
-                         TimeUnit.MICROSECONDS.convert(1000L*t, 
+            assertEquals(t,
+                         TimeUnit.MICROSECONDS.convert(1000L*t,
                                                   TimeUnit.NANOSECONDS));
 
+            assertEquals(1000000000L*t*60*60*24,
+                         TimeUnit.NANOSECONDS.convert(t,
+                                                  TimeUnit.DAYS));
+            assertEquals(1000000000L*t*60*60,
+                         TimeUnit.NANOSECONDS.convert(t,
+                                                  TimeUnit.HOURS));
+            assertEquals(1000000000L*t*60,
+                         TimeUnit.NANOSECONDS.convert(t,
+                                                  TimeUnit.MINUTES));
             assertEquals(1000000000L*t,
-                         TimeUnit.NANOSECONDS.convert(t, 
+                         TimeUnit.NANOSECONDS.convert(t,
                                                   TimeUnit.SECONDS));
-            assertEquals(1000000L*t, 
-                         TimeUnit.NANOSECONDS.convert(t, 
+            assertEquals(1000000L*t,
+                         TimeUnit.NANOSECONDS.convert(t,
                                                   TimeUnit.MILLISECONDS));
-            assertEquals(1000L*t, 
-                         TimeUnit.NANOSECONDS.convert(t, 
+            assertEquals(1000L*t,
+                         TimeUnit.NANOSECONDS.convert(t,
                                                   TimeUnit.MICROSECONDS));
-            assertEquals(t, 
-                         TimeUnit.NANOSECONDS.convert(t, 
+            assertEquals(t,
+                         TimeUnit.NANOSECONDS.convert(t,
                                                   TimeUnit.NANOSECONDS));
         }
     }
@@ -89,13 +121,19 @@
      */
     public void testToNanos() {
         for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*1000000000L*60*60*24,
+                         TimeUnit.DAYS.toNanos(t));
+            assertEquals(t*1000000000L*60*60,
+                         TimeUnit.HOURS.toNanos(t));
+            assertEquals(t*1000000000L*60,
+                         TimeUnit.MINUTES.toNanos(t));
             assertEquals(1000000000L*t,
                          TimeUnit.SECONDS.toNanos(t));
-            assertEquals(1000000L*t, 
+            assertEquals(1000000L*t,
                          TimeUnit.MILLISECONDS.toNanos(t));
-            assertEquals(1000L*t, 
+            assertEquals(1000L*t,
                          TimeUnit.MICROSECONDS.toNanos(t));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.NANOSECONDS.toNanos(t));
         }
     }
@@ -106,13 +144,19 @@
      */
     public void testToMicros() {
         for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*1000000L*60*60*24,
+                         TimeUnit.DAYS.toMicros(t));
+            assertEquals(t*1000000L*60*60,
+                         TimeUnit.HOURS.toMicros(t));
+            assertEquals(t*1000000L*60,
+                         TimeUnit.MINUTES.toMicros(t));
             assertEquals(1000000L*t,
                          TimeUnit.SECONDS.toMicros(t));
-            assertEquals(1000L*t, 
+            assertEquals(1000L*t,
                          TimeUnit.MILLISECONDS.toMicros(t));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.MICROSECONDS.toMicros(t));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.NANOSECONDS.toMicros(t*1000L));
         }
     }
@@ -123,13 +167,19 @@
      */
     public void testToMillis() {
         for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*1000L*60*60*24,
+                         TimeUnit.DAYS.toMillis(t));
+            assertEquals(t*1000L*60*60,
+                         TimeUnit.HOURS.toMillis(t));
+            assertEquals(t*1000L*60,
+                         TimeUnit.MINUTES.toMillis(t));
             assertEquals(1000L*t,
                          TimeUnit.SECONDS.toMillis(t));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.MILLISECONDS.toMillis(t));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.MICROSECONDS.toMillis(t*1000L));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.NANOSECONDS.toMillis(t*1000000L));
         }
     }
@@ -140,19 +190,95 @@
      */
     public void testToSeconds() {
         for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*60*60*24,
+                         TimeUnit.DAYS.toSeconds(t));
+            assertEquals(t*60*60,
+                         TimeUnit.HOURS.toSeconds(t));
+            assertEquals(t*60,
+                         TimeUnit.MINUTES.toSeconds(t));
             assertEquals(t,
                          TimeUnit.SECONDS.toSeconds(t));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.MILLISECONDS.toSeconds(t*1000L));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.MICROSECONDS.toSeconds(t*1000000L));
-            assertEquals(t, 
+            assertEquals(t,
                          TimeUnit.NANOSECONDS.toSeconds(t*1000000000L));
         }
     }
 
     /**
-     * convert saturates positive too-large values to Long.MAX_VALUE 
+     * toMinutes correctly converts sample values in different units to
+     * minutes
+     */
+    public void testToMinutes() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*60*24,
+                         TimeUnit.DAYS.toMinutes(t));
+            assertEquals(t*60,
+                         TimeUnit.HOURS.toMinutes(t));
+            assertEquals(t,
+                         TimeUnit.MINUTES.toMinutes(t));
+            assertEquals(t,
+                         TimeUnit.SECONDS.toMinutes(t*60));
+            assertEquals(t,
+                         TimeUnit.MILLISECONDS.toMinutes(t*1000L*60));
+            assertEquals(t,
+                         TimeUnit.MICROSECONDS.toMinutes(t*1000000L*60));
+            assertEquals(t,
+                         TimeUnit.NANOSECONDS.toMinutes(t*1000000000L*60));
+        }
+    }
+
+    /**
+     * toHours correctly converts sample values in different units to
+     * hours
+     */
+    public void testToHours() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*24,
+                         TimeUnit.DAYS.toHours(t));
+            assertEquals(t,
+                         TimeUnit.HOURS.toHours(t));
+            assertEquals(t,
+                         TimeUnit.MINUTES.toHours(t*60));
+            assertEquals(t,
+                         TimeUnit.SECONDS.toHours(t*60*60));
+            assertEquals(t,
+                         TimeUnit.MILLISECONDS.toHours(t*1000L*60*60));
+            assertEquals(t,
+                         TimeUnit.MICROSECONDS.toHours(t*1000000L*60*60));
+            assertEquals(t,
+                         TimeUnit.NANOSECONDS.toHours(t*1000000000L*60*60));
+        }
+    }
+
+    /**
+     * toDays correctly converts sample values in different units to
+     * days
+     */
+    public void testToDays() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t,
+                         TimeUnit.DAYS.toDays(t));
+            assertEquals(t,
+                         TimeUnit.HOURS.toDays(t*24));
+            assertEquals(t,
+                         TimeUnit.MINUTES.toDays(t*60*24));
+            assertEquals(t,
+                         TimeUnit.SECONDS.toDays(t*60*60*24));
+            assertEquals(t,
+                         TimeUnit.MILLISECONDS.toDays(t*1000L*60*60*24));
+            assertEquals(t,
+                         TimeUnit.MICROSECONDS.toDays(t*1000000L*60*60*24));
+            assertEquals(t,
+                         TimeUnit.NANOSECONDS.toDays(t*1000000000L*60*60*24));
+        }
+    }
+
+
+    /**
+     * convert saturates positive too-large values to Long.MAX_VALUE
      * and negative to LONG.MIN_VALUE
      */
     public void testConvertSaturate() {
@@ -162,18 +288,35 @@
         assertEquals(Long.MIN_VALUE,
                      TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
                                                   TimeUnit.SECONDS));
-
+        assertEquals(Long.MAX_VALUE,
+                     TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+                                                  TimeUnit.MINUTES));
+        assertEquals(Long.MIN_VALUE,
+                     TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+                                                  TimeUnit.MINUTES));
+        assertEquals(Long.MAX_VALUE,
+                     TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+                                                  TimeUnit.HOURS));
+        assertEquals(Long.MIN_VALUE,
+                     TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+                                                  TimeUnit.HOURS));
+        assertEquals(Long.MAX_VALUE,
+                     TimeUnit.NANOSECONDS.convert(Long.MAX_VALUE / 2,
+                                                  TimeUnit.DAYS));
+        assertEquals(Long.MIN_VALUE,
+                     TimeUnit.NANOSECONDS.convert(-Long.MAX_VALUE / 4,
+                                                  TimeUnit.DAYS));
     }
 
     /**
-     * toNanos saturates positive too-large values to Long.MAX_VALUE 
+     * toNanos saturates positive too-large values to Long.MAX_VALUE
      * and negative to LONG.MIN_VALUE
      */
     public void testToNanosSaturate() {
-            assertEquals(Long.MAX_VALUE,
-                         TimeUnit.MILLISECONDS.toNanos(Long.MAX_VALUE / 2));
-            assertEquals(Long.MIN_VALUE,
-                         TimeUnit.MILLISECONDS.toNanos(-Long.MAX_VALUE / 3));
+        assertEquals(Long.MAX_VALUE,
+                     TimeUnit.MILLISECONDS.toNanos(Long.MAX_VALUE / 2));
+        assertEquals(Long.MIN_VALUE,
+                     TimeUnit.MILLISECONDS.toNanos(-Long.MAX_VALUE / 3));
     }
 
 
@@ -185,151 +328,100 @@
         assertTrue(s.indexOf("ECOND") >= 0);
     }
 
-    
+
     /**
      *  Timed wait without holding lock throws
      *  IllegalMonitorStateException
      */
-    public void testTimedWait_IllegalMonitorException() {
-        //created a new thread with anonymous runnable
+    public void testTimedWait_IllegalMonitorException() throws Exception {
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Object o = new Object();
+                TimeUnit tu = TimeUnit.MILLISECONDS;
+                try {
+                    tu.timedWait(o,LONG_DELAY_MS);
+                    threadShouldThrow();
+                } catch (IllegalMonitorStateException success) {}}});
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    Object o = new Object();
-                    TimeUnit tu = TimeUnit.MILLISECONDS;
-                    try {
-                        tu.timedWait(o,LONG_DELAY_MS);
-                        threadShouldThrow();
-                    }
-                    catch (InterruptedException ie) {
-                        threadUnexpectedException();
-                    } 
-                    catch(IllegalMonitorStateException success) {
-                    }
-                    
-                }
-            });
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(Exception e) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
-    
+
     /**
      * timedWait throws InterruptedException when interrupted
      */
-    public void testTimedWait() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    Object o = new Object();
-                    
-                    TimeUnit tu = TimeUnit.MILLISECONDS;
-                    try {
-                        synchronized(o) {
-                            tu.timedWait(o,MEDIUM_DELAY_MS);
-                        }
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {} 
-                    catch(IllegalMonitorStateException failure) {
-                        threadUnexpectedException();
-                    }
+    public void testTimedWait() throws InterruptedException {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                Object o = new Object();
+
+                TimeUnit tu = TimeUnit.MILLISECONDS;
+                synchronized(o) {
+                    tu.timedWait(o,MEDIUM_DELAY_MS);
                 }
-            });
+            }});
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(Exception e) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
-    
-    
+
+
     /**
      * timedJoin throws InterruptedException when interrupted
      */
-    public void testTimedJoin() {
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    TimeUnit tu = TimeUnit.MILLISECONDS;        
-                    try {
-                        Thread s = new Thread(new Runnable() {
-                                public void run() {
-                                    try {
-                                        Thread.sleep(MEDIUM_DELAY_MS);
-                                    } catch(InterruptedException success){}
-                                }
-                            });
-                        s.start();
-                        tu.timedJoin(s,MEDIUM_DELAY_MS);
-                        threadShouldThrow();
-                    }
-                    catch(Exception e) {}
-                }
-            });
+    public void testTimedJoin() throws InterruptedException {
+        final Thread s = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(MEDIUM_DELAY_MS);
+            }});
+        final Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                TimeUnit tu = TimeUnit.MILLISECONDS;
+                tu.timedJoin(s, MEDIUM_DELAY_MS);
+            }});;
+        s.start();
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(Exception e) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
+        s.interrupt();
+        s.join();
     }
-    
+
     /**
      *  timedSleep throws InterruptedException when interrupted
      */
-    public void testTimedSleep() {
-        //created a new thread with anonymous runnable
+    public void testTimedSleep() throws InterruptedException {
+        Thread t = new Thread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                TimeUnit tu = TimeUnit.MILLISECONDS;
+                tu.sleep(MEDIUM_DELAY_MS);
+            }});
 
-        Thread t = new Thread(new Runnable() {
-                public void run() {
-                    TimeUnit tu = TimeUnit.MILLISECONDS;
-                    try {
-                        tu.sleep(MEDIUM_DELAY_MS);
-                        threadShouldThrow();
-                    }
-                    catch(InterruptedException success) {} 
-                }
-            });
         t.start();
-        try {
-            Thread.sleep(SHORT_DELAY_MS);
-            t.interrupt();
-            t.join();
-        } catch(Exception e) {
-            unexpectedException();
-        }
+        Thread.sleep(SHORT_DELAY_MS);
+        t.interrupt();
+        t.join();
     }
 
     /**
-     * a deserialized serialized unit is equal 
+     * a deserialized serialized unit is the same instance
      */
-    public void testSerialization() {
+    public void testSerialization() throws Exception {
         TimeUnit q = TimeUnit.MILLISECONDS;
 
-        try {
-            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
-            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
-            out.writeObject(q);
-            out.close();
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
+        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
+        out.writeObject(q);
+        out.close();
 
-            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
-            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
-            TimeUnit r = (TimeUnit)in.readObject();
-            
-            assertEquals(q.toString(), r.toString());
-        } catch(Exception e){
-            e.printStackTrace();
-            unexpectedException();
-        }
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
+        TimeUnit r = (TimeUnit)in.readObject();
+        assertSame(q, r);
     }
 
 }
diff --git a/concurrent/src/test/java/tests/concurrent/AllTests.java b/concurrent/src/test/java/tests/concurrent/AllTests.java
index d2ebbeb..d599370 100644
--- a/concurrent/src/test/java/tests/concurrent/AllTests.java
+++ b/concurrent/src/test/java/tests/concurrent/AllTests.java
@@ -23,16 +23,11 @@
  * Test suite for the concurrent module
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     /**
      * Collects all JSR166 unit tests as one suite
      */ 
     public static Test suite ( ) {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("JSR166 Unit Tests");
+        TestSuite suite = new TestSuite("JSR166 Unit Tests");
 
         suite.addTest(tests.api.java.util.concurrent.JSR166TestCase.suite());
         
diff --git a/crypto/src/main/java/javax/crypto/interfaces/package.html b/crypto/src/main/java/javax/crypto/interfaces/package.html
index 04a7c0b..d278318 100644
--- a/crypto/src/main/java/javax/crypto/interfaces/package.html
+++ b/crypto/src/main/java/javax/crypto/interfaces/package.html
@@ -7,6 +7,5 @@
       The parameters for the DH algorithm must be accessed without unduly 
       restriction as for example hardware repository for the parameters material.
     </p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/crypto/src/main/java/javax/crypto/package.html b/crypto/src/main/java/javax/crypto/package.html
index 3f3bb47..3239b72 100644
--- a/crypto/src/main/java/javax/crypto/package.html
+++ b/crypto/src/main/java/javax/crypto/package.html
@@ -8,12 +8,11 @@
 This package provides the classes and interfaces for cryptographic applications implementing algorithms for encryption, decryption, or
 key agreement. 
 </p><p>
-Stream ciphers are supported as well as asymmetric, symmetric and block ciphers. Cipher implementations from different providers are easily integratable thanks
-to the SPI (Security Provider Interface) abstract classes. With class {@link javax.crypto.SealedObject} a programmer can secure an object by
+Stream ciphers are supported as well as asymmetric, symmetric and block ciphers. Cipher implementations from different providers can be integrated using
+the SPI (Service Provider Interface) abstract classes. With class {@link javax.crypto.SealedObject} a programmer can secure an object by
 encrypting it with a cipher.
 </p><p>
 Authentication may be based on MAC (Message Authentication Code) such as HMAC (Hash MAC, i.e. with a SHA-1 hash function).
 </p>
-@since Android 1.0
 </body>
 </html>
diff --git a/crypto/src/main/java/javax/crypto/spec/package.html b/crypto/src/main/java/javax/crypto/spec/package.html
index f647f75..177ac3d 100644
--- a/crypto/src/main/java/javax/crypto/spec/package.html
+++ b/crypto/src/main/java/javax/crypto/spec/package.html
@@ -2,16 +2,24 @@
   <body>
     <p>
       This package provides the classes and interfaces needed to specify keys
-      and parameter for encryption. Following standards are supported:
-      (1) PKCS#3 Diffie-Hellman ekey agreement's standard;
-      (2) FIPS-46-2 Data Encryption Standard (DES);
-      (3) PKCS#5 Password Based Encryption (PBE) standard.
-      Keys may be specified via algorithm or in a more abstract and general way
+      and parameter for encryption. The following standards are supported:
+      <ul>
+      <li>PKCS#3 Diffie-Hellman Key Agreement standard;
+      <li>FIPS-46-2 Data Encryption Standard (DES);
+      <li>PKCS#5 Password-Based Cryptography standard.
+      </ul>
+      <p>Keys may be specified via algorithm or in a more abstract and general way
       with ASN.1.
 
-      Keys and algorithm parameters are specified for the following procedures:
-      (i) DH, (ii) DES, (iii) TripleDES, (iv) PBE, (v) RC2 and (vi) RC5.
+      <p>Keys and algorithm parameters are specified for the following procedures:
+      <ul>
+      <li>DH
+      <li>DES
+      <li>TripleDES
+      <li>PBE
+      <li>RC2
+      <li>RC5
+      </li>
     </p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java
index 5050fc8..aa3240f 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(BadPaddingExceptionTest.class);
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
index 220c6c6..6f1db9e 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
@@ -922,7 +922,6 @@
         method = "engineGenerateSecret",
         args = {java.lang.String.class}
     )})
-    @KnownFailure("Does not throw expected exception")
     public void test_generateSecretLjava_lang_String() throws Exception {
         if (!DEFSupported) {
             fail(NotSupportMsg);
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
index 750342c..5e2414e 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
@@ -1171,11 +1171,6 @@
     public static Test suite() {
         return new TestSuite(MacTest.class);
     }
-
-    public static void main(String args[]) {        
-        junit.textui.TestRunner.run(suite());
-        
-    }        
 }
 /**
  * Additional class for Mac constructor verification
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
index 906057b..68b6720 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
@@ -24,11 +24,6 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
         TestSuite suite = new TestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.func;");
         // $JUnit-BEGIN$
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java
index b66a384..b47c23e 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.interfaces;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.interfaces;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(DHPrivateKeyTest.class);
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java
index 0be596e..02e0bbb 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.serialization;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.serialization;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(BadPaddingExceptionTest.class);
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java
index 2f632ae..3992d44 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java
@@ -42,8 +42,4 @@
         return new Object[] { new BadPaddingException(),
                 new BadPaddingException(null), new BadPaddingException(msgs[1]) };
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(BadPaddingExceptionTest.class);
-    }
 }
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java
index 7fd8cd0..33665d0 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java
@@ -42,8 +42,4 @@
         return new Object[] { new ExemptionMechanismException(),
                 new ExemptionMechanismException(null), new ExemptionMechanismException(msgs[1]) };
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(ExemptionMechanismExceptionTest.class);
-    }
 }
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java
index 2cc1daa..652c0b0 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java
@@ -42,8 +42,4 @@
         return new Object[] { new IllegalBlockSizeException(),
                 new IllegalBlockSizeException(null), new IllegalBlockSizeException(msgs[1]) };
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(IllegalBlockSizeExceptionTest.class);
-    }
 }
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java
index 475bd2f..12b98fb 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java
@@ -42,8 +42,4 @@
         return new Object[] { new NoSuchPaddingException(),
                 new NoSuchPaddingException(null), new NoSuchPaddingException(msgs[1]) };
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(NoSuchPaddingExceptionTest.class);
-    }
 }
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java
index ab696e8..c42a5cb 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java
@@ -42,8 +42,4 @@
         return new Object[] { new ShortBufferException(),
                 new ShortBufferException(null), new ShortBufferException(msgs[1]) };
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(ShortBufferExceptionTest.class);
-    }
 }
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java
index d31dc54..cdd3d51 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.spec;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.spec;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(DESKeySpecTest.class);
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java
index 9904eed..9106a87 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java
@@ -324,9 +324,5 @@
     public static Test suite() {
         return new TestSuite(DESKeySpecTest.class);
     }
-
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java
index 5c312a4..3f8ce0a 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java
@@ -226,9 +226,5 @@
     public static Test suite() {
         return new TestSuite(DESedeKeySpecTest.class);
     }
-
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java
index 7b09cb6..aef1286 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java
@@ -84,9 +84,5 @@
     public static Test suite() {
         return new TestSuite(DHGenParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java
index 0c0ac3b..65d1a17 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java
@@ -111,9 +111,5 @@
     public static Test suite() {
         return new TestSuite(DHParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java
index 7181623..327004a 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java
@@ -95,9 +95,5 @@
     public static Test suite() {
         return new TestSuite(DHPrivateKeySpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java
index 064c713..905d8cd 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java
@@ -95,9 +95,5 @@
     public static Test suite() {
         return new TestSuite(DHPublicKeySpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java
index fda566a..1c27f68 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java
@@ -160,9 +160,5 @@
     public static Test suite() {
         return new TestSuite(IvParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java
index 6b2c673..3fa2d72 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java
@@ -194,9 +194,5 @@
     public static Test suite() {
         return new TestSuite(OAEPParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java
index 1cb017e..bbce868 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java
@@ -356,9 +356,5 @@
     public static Test suite() {
         return new TestSuite(PBEKeySpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java
index b294995..6bca15c 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java
@@ -118,9 +118,5 @@
     public static Test suite() {
         return new TestSuite(PBEParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java
index 08e8acd..ac3c5e5 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java
@@ -155,8 +155,4 @@
     public static Test suite() {
         return new TestSuite(PSourceTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java
index cf72d23..6eb636f 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java
@@ -254,9 +254,5 @@
     public static Test suite() {
         return new TestSuite(RC2ParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java
index 6182615..9b7704d 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java
@@ -350,9 +350,5 @@
     public static Test suite() {
         return new TestSuite(RC5ParameterSpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
index 5eeb76f..b39bb1d 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
@@ -315,9 +315,5 @@
     public static Test suite() {
         return new TestSuite(SecretKeySpecTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/crypto/src/test/java/tests/crypto/AllTests.java b/crypto/src/test/java/tests/crypto/AllTests.java
index 795d0a9..0b53942 100644
--- a/crypto/src/test/java/tests/crypto/AllTests.java
+++ b/crypto/src/test/java/tests/crypto/AllTests.java
@@ -23,14 +23,8 @@
  * Test suite that includes all tests for the regex project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-//AllTests.java 
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All crypto test suites");
+        TestSuite suite = new TestSuite("All crypto test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.interfaces.AllTests.suite());
         suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.serialization.AllTests.suite());
diff --git a/dalvik/src/main/java/dalvik/annotation/HostController.java b/dalvik/src/main/java/dalvik/annotation/HostController.java
index 2ccc292..c6e0bff 100644
--- a/dalvik/src/main/java/dalvik/annotation/HostController.java
+++ b/dalvik/src/main/java/dalvik/annotation/HostController.java
@@ -25,8 +25,6 @@
  * Record the host side controller information for a test method,
  * so that the CTS host can locate correspond host side unit while running it.
  * {@hide pending API Council approval}
- * 
- * @since Android 1.0
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ ElementType.METHOD })
diff --git a/dalvik/src/main/java/dalvik/annotation/TestLevel.java b/dalvik/src/main/java/dalvik/annotation/TestLevel.java
index ff9ddb3..9d2c6e7 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestLevel.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestLevel.java
@@ -19,7 +19,6 @@
 /**
  * Defines an enumeration of possible states a test case can be in.
  * 
- * @since Android 1.0
  * @hide
  */
 public enum TestLevel {
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTarget.java b/dalvik/src/main/java/dalvik/annotation/TestTarget.java
index 7cbddca..9912312 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTarget.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTarget.java
@@ -25,8 +25,6 @@
  * Defines an annotation used be used within the TestInfo annotation. It
  * specifies a single method target for the test (but can be used multiple
  * times).
- * 
- * @since Android 1.0
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ ElementType.ANNOTATION_TYPE })
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java b/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
index acbc1f1..c79b0f1 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargetClass.java
@@ -28,8 +28,6 @@
  * that is being tested. The current assumption is that the test are somewhat
  * organized according to the API classes they test. Might be too strict for
  * some cases.
- * 
- * @since Android 1.0
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ ElementType.TYPE })
@@ -45,4 +43,4 @@
      * @hide
      */
     TestTargetNew[] untestedMethods() default {};
-}
\ No newline at end of file
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java b/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
index c00e37b..507c041 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargetNew.java
@@ -25,8 +25,6 @@
  * Defines an annotation used be used within the TestInfo annotation. It
  * specifies a single method target for the test (but can be used multiple
  * times).
- * 
- * @since Android 1.0
  * @hide
  */
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/dalvik/src/main/java/dalvik/annotation/TestTargets.java b/dalvik/src/main/java/dalvik/annotation/TestTargets.java
index ead6149..8552717 100644
--- a/dalvik/src/main/java/dalvik/annotation/TestTargets.java
+++ b/dalvik/src/main/java/dalvik/annotation/TestTargets.java
@@ -28,8 +28,6 @@
  * that is being tested. The current assumption is that the test are somewhat
  * organized according to the API classes they test. Might be too strict for
  * some cases.
- * 
- * @since Android 1.0
  * @hide
  */
 @Retention(RetentionPolicy.RUNTIME)
@@ -40,4 +38,4 @@
      * Specifies the API methods that are tested by the annotated test method.
      */
     TestTargetNew[] value();
-}
\ No newline at end of file
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java b/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
index 6985929..751a038 100644
--- a/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
+++ b/dalvik/src/main/java/dalvik/annotation/ToBeFixed.java
@@ -25,8 +25,6 @@
  * Defines an annotation for test methods that indicate the test method
  * need to be fixed in future.
  * {@hide pending API Council approval}
- *
- * @since Android 1.0
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ ElementType.METHOD })
diff --git a/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java b/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java
index 019e4b0..ff9cf35 100644
--- a/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java
+++ b/dalvik/src/main/java/dalvik/annotation/VirtualTestTarget.java
@@ -44,8 +44,6 @@
  * annotating them with {@code @VirtualTestTarget}. This class can then be
  * used in the {@code @TestTargetClass} annotation with which we annotate 
  * {@code TestCase} subclasses.
- * 
- * @since Android 1.0
  * @hide
  */
 @Retention(RetentionPolicy.RUNTIME)
@@ -56,4 +54,4 @@
      * Field for comments.
      */
     String value() default "";
-}
\ No newline at end of file
+}
diff --git a/dalvik/src/main/java/dalvik/annotation/package.html b/dalvik/src/main/java/dalvik/annotation/package.html
index fc7cf07..2a67dc0 100644
--- a/dalvik/src/main/java/dalvik/annotation/package.html
+++ b/dalvik/src/main/java/dalvik/annotation/package.html
@@ -4,6 +4,5 @@
       Defines some annotations that are used within the Android system, either
       for the core libraries or for testing purposes.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/dalvik/src/main/java/dalvik/bytecode/Opcodes.java b/dalvik/src/main/java/dalvik/bytecode/Opcodes.java
index 33795ba..845ace2 100644
--- a/dalvik/src/main/java/dalvik/bytecode/Opcodes.java
+++ b/dalvik/src/main/java/dalvik/bytecode/Opcodes.java
@@ -273,13 +273,18 @@
     int OP_SHR_INT_LIT8                 = 0xe1;
     int OP_USHR_INT_LIT8                = 0xe2;
 
-    /* e3-eb unused */
+    /* e3-e7 unused */
 
     /*
      * The rest of these are either generated by dexopt for optimized
      * code, or inserted by the VM at runtime.  They are never generated
      * by "dx".
      */
+    int OP_IGET_WIDE_VOLATILE           = 0xe8;
+    int OP_IPUT_WIDE_VOLATILE           = 0xe9;
+    int OP_SGET_WIDE_VOLATILE           = 0xea;
+    int OP_SPUT_WIDE_VOLATILE           = 0xeb;
+
     int OP_BREAKPOINT                   = 0xec;
     int OP_THROW_VERIFICATION_ERROR     = 0xed;
 
diff --git a/dalvik/src/main/java/dalvik/bytecode/package.html b/dalvik/src/main/java/dalvik/bytecode/package.html
index 1a6d7c4..92b0e92 100644
--- a/dalvik/src/main/java/dalvik/bytecode/package.html
+++ b/dalvik/src/main/java/dalvik/bytecode/package.html
@@ -1,8 +1,7 @@
 <html>
   <body>
     <p>
-      Provides classes surrounding the Dalvik bytecode. 
+      Provides classes related to Dalvik bytecode. 
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/dalvik/src/main/java/dalvik/system/AllocationLimitError.java b/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
index 9118199..e1417e2 100644
--- a/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
+++ b/dalvik/src/main/java/dalvik/system/AllocationLimitError.java
@@ -19,8 +19,7 @@
 /**
  * Is thrown when an allocation limit is exceeded.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public class AllocationLimitError extends VirtualMachineError {
     /**
diff --git a/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
index 4a440b5..d4ccfed 100644
--- a/dalvik/src/main/java/dalvik/system/DexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -235,7 +235,6 @@
             System.out.println("DexClassLoader " + this
                 + ": findClass '" + name + "'");
 
-        byte[] data = null;
         int length = mFiles.length;
 
         for (int i = 0; i < length; i++) {
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index 00de314..7beddbb 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -29,8 +29,6 @@
  * <p>
  * Note we don't directly open and read the DEX file here. They're memory-mapped
  * read-only by the VM.
- * 
- * @since Android 1.0
  */
 public final class DexFile {
     private final int mCookie;
@@ -40,7 +38,7 @@
      * Opens a DEX file from a given File object. This will usually be a ZIP/JAR
      * file with a "classes.dex" inside.
      *
-     * The VM will generate the name of the coresponding file in
+     * The VM will generate the name of the corresponding file in
      * /data/dalvik-cache and open it, possibly creating or updating
      * it first if system permissions allow.  Don't pass in the name of
      * a file in /data/dalvik-cache, as the named file is expected to be
@@ -61,7 +59,7 @@
      * Opens a DEX file from a given filename. This will usually be a ZIP/JAR
      * file with a "classes.dex" inside.
      *
-     * The VM will generate the name of the coresponding file in
+     * The VM will generate the name of the corresponding file in
      * /data/dalvik-cache and open it, possibly creating or updating
      * it first if system permissions allow.  Don't pass in the name of
      * a file in /data/dalvik-cache, as the named file is expected to be
@@ -288,4 +286,3 @@
     native public static boolean isDexOptNeeded(String fileName)
             throws FileNotFoundException, IOException;
 }
-
diff --git a/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index 5d7333e..5bb18de 100644
--- a/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -37,8 +37,6 @@
  * of files and directories in the local file system, but does not attempt to
  * load classes from the network. Android uses this class for its system class
  * loader and for its application class loader(s).
- *
- * @since Android 1.0
  */
 public class PathClassLoader extends ClassLoader {
 
@@ -277,7 +275,6 @@
      * @param resName
      *            the name of the resource to find.
      * @return an enumeration of {@code URL} objects for the requested resource.
-     * @since Android 1.0
      */
     @Override
     protected Enumeration<URL> findResources(String resName) {
diff --git a/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java b/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
index 938a5cd..70f5fc0 100644
--- a/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
+++ b/dalvik/src/main/java/dalvik/system/PotentialDeadlockError.java
@@ -19,8 +19,7 @@
 /**
  * Is thrown when the VM identifies a potential deadlock.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public class PotentialDeadlockError extends VirtualMachineError {
     /**
diff --git a/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java b/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
index ffde7cb..22f8668 100644
--- a/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
+++ b/dalvik/src/main/java/dalvik/system/StaleDexCacheError.java
@@ -20,8 +20,7 @@
  * Is thrown when the VM determines that a DEX file's cache is out of date, and
  * that there is no way to recreate it.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public class StaleDexCacheError extends VirtualMachineError {
     /**
diff --git a/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java b/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
index 0e26a70..e05292e 100644
--- a/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
+++ b/dalvik/src/main/java/dalvik/system/TemporaryDirectory.java
@@ -26,8 +26,7 @@
  * startup, as a reasonably easy way to get the standard property
  * <code>java.io.tmpdir</code> to point at something useful.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public class TemporaryDirectory {
     /** system property name for the temporary directory */
diff --git a/dalvik/src/main/java/dalvik/system/TouchDex.java b/dalvik/src/main/java/dalvik/system/TouchDex.java
index 04c6546..aca0fd3 100644
--- a/dalvik/src/main/java/dalvik/system/TouchDex.java
+++ b/dalvik/src/main/java/dalvik/system/TouchDex.java
@@ -25,8 +25,7 @@
 /**
  * Induces optimization/verification of a set of DEX files.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public class TouchDex {
 
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 31e82ec..118d4a6 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -28,8 +28,7 @@
  * 
  * @cts Please complete the spec.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public final class VMDebug {
     /**
diff --git a/dalvik/src/main/java/dalvik/system/VMRuntime.java b/dalvik/src/main/java/dalvik/system/VMRuntime.java
index e05e489..0d0747b 100644
--- a/dalvik/src/main/java/dalvik/system/VMRuntime.java
+++ b/dalvik/src/main/java/dalvik/system/VMRuntime.java
@@ -21,10 +21,7 @@
  * An application cannot create its own Runtime instance, and must obtain
  * one from the getRuntime method.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
- *
- * @since Android 1.0
+ * @hide
  */
 public final class VMRuntime {
 
@@ -162,6 +159,7 @@
      * @return true if the VM thinks there's enough process memory
      *         to satisfy this request, or false if not.
      */
+    @Deprecated
     public native boolean trackExternalAllocation(long size);
 
     /**
@@ -177,6 +175,7 @@
      *             should have been passed to trackExternalAlloc() when
      *             the underlying memory was originally allocated.
      */
+    @Deprecated
     public native void trackExternalFree(long size);
 
     /**
@@ -185,6 +184,7 @@
      *
      * @return the number of bytes
      */
+    @Deprecated
     public native long getExternalBytesAllocated();
 
     /**
diff --git a/dalvik/src/main/java/dalvik/system/VMStack.java b/dalvik/src/main/java/dalvik/system/VMStack.java
index b049962..e9d5765 100644
--- a/dalvik/src/main/java/dalvik/system/VMStack.java
+++ b/dalvik/src/main/java/dalvik/system/VMStack.java
@@ -20,8 +20,7 @@
  * Provides a limited interface to the Dalvik VM stack. This class is mostly
  * used for implementing security checks.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public final class VMStack {
     /**
diff --git a/dalvik/src/main/java/dalvik/system/Zygote.java b/dalvik/src/main/java/dalvik/system/Zygote.java
index 641e856..21eee3d 100644
--- a/dalvik/src/main/java/dalvik/system/Zygote.java
+++ b/dalvik/src/main/java/dalvik/system/Zygote.java
@@ -21,8 +21,7 @@
  * be partially initialized and then fork()'d from the partially initialized
  * state.
  *
- * @deprecated this is an internal Dalvik class that is not appropriate for
- *      general use. It will be removed from the public API in a future release.
+ * @hide
  */
 public class Zygote {
     /*
diff --git a/dalvik/src/main/java/dalvik/system/package.html b/dalvik/src/main/java/dalvik/system/package.html
index 215671c..01d0d30 100644
--- a/dalvik/src/main/java/dalvik/system/package.html
+++ b/dalvik/src/main/java/dalvik/system/package.html
@@ -3,6 +3,5 @@
     <p>
       Provides utility and system information classes specific to the Dalvik VM.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/dalvik/src/main/native/dalvik_system_TouchDex.cpp b/dalvik/src/main/native/dalvik_system_TouchDex.cpp
index e8b834b..b2614c9 100644
--- a/dalvik/src/main/native/dalvik_system_TouchDex.cpp
+++ b/dalvik/src/main/native/dalvik_system_TouchDex.cpp
@@ -259,20 +259,12 @@
     fclose(fp);
 }
 
-/*
- * JNI registration.
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "trampoline", "(Ljava/lang/String;Ljava/lang/String;)I",
         (void*) dalvik_system_TouchDex_trampoline },
 };
-
-extern "C" int register_dalvik_system_TouchDex(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, JAVA_PACKAGE "/TouchDex",
-        gMethods, NELEM(gMethods));
+int register_dalvik_system_TouchDex(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, JAVA_PACKAGE "/TouchDex", gMethods, NELEM(gMethods));
 }
 
 }; // namespace android
-
diff --git a/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.c b/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.c
index 25235dc..9aa0a8e 100644
--- a/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.c
+++ b/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.c
@@ -50,11 +50,7 @@
     // This space intentionally left blank.
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "emptyJniStaticMethod0",  "()V",  emptyJniStaticMethod0 },
     { "emptyJniStaticMethod6",  "(IIIIII)V", emptyJniStaticMethod6 },
     { "emptyJniStaticMethod6L",
@@ -62,9 +58,7 @@
       "Ljava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V",
       emptyJniStaticMethod6L },
 };
-
-int register_org_apache_harmony_dalvik_NativeTestTarget(JNIEnv* env)
-{
+int register_org_apache_harmony_dalvik_NativeTestTarget(JNIEnv* env) {
     int result = jniRegisterNativeMethods(env,
             "org/apache/harmony/dalvik/NativeTestTarget",
             gMethods, NELEM(gMethods));
@@ -75,4 +69,3 @@
     }
     return 0;
 }
-
diff --git a/dom/src/test/java/tests/api/org/w3c/dom/AllTests.java b/dom/src/test/java/tests/api/org/w3c/dom/AllTests.java
index 677780a..7214d4f 100644
--- a/dom/src/test/java/tests/api/org/w3c/dom/AllTests.java
+++ b/dom/src/test/java/tests/api/org/w3c/dom/AllTests.java
@@ -28,7 +28,7 @@
     }*/
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTest(AllTests_Level1.suite());
         suite.addTest(AllTests_Level2.suite());
         return suite;
diff --git a/dom/src/test/java/tests/dom/AllTests.java b/dom/src/test/java/tests/dom/AllTests.java
index 6a5831f..48b362b 100644
--- a/dom/src/test/java/tests/dom/AllTests.java
+++ b/dom/src/test/java/tests/dom/AllTests.java
@@ -24,7 +24,10 @@
 public class AllTests {
 
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
+        // BEGIN android-changed: this was only referenced from the xml module!
+        suite.addTest(tests.api.org.w3c.dom.AllTests.suite());
+        // END android-changed
         suite.addTestSuite(JunitTestCases.class);
         return suite;
     }
diff --git a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java
index df6f7dc..fe0f920 100644
--- a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java
+++ b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetICU.java
@@ -5,7 +5,7 @@
 *******************************************************************************
 *
 *******************************************************************************
-*/ 
+*/
 
 package com.ibm.icu4jni.charset;
 
@@ -15,14 +15,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
-// BEGIN android-removed
-// import com.ibm.icu4jni.common.ErrorCode;
-// import com.ibm.icu4jni.converters.NativeConverter;
-// END android-removed
-
-
-public final class CharsetICU extends Charset{
-    private String icuCanonicalName;
+public final class CharsetICU extends Charset {
+    private final String icuCanonicalName;
     /**
      * Constructor to create a the CharsetICU object
      * @param canonicalName the canonical name as a string
@@ -30,69 +24,64 @@
      * @stable ICU 2.4
      */
     protected CharsetICU(String canonicalName, String icuCanonName, String[] aliases) {
-         super(canonicalName,aliases);
+         super(canonicalName, aliases);
          icuCanonicalName = icuCanonName;
-        
     }
     /**
      * Returns a new decoder instance of this charset object
      * @return a new decoder object
      * @stable ICU 2.4
      */
-    public CharsetDecoder newDecoder(){
-        // the arrays are locals and not
-        // instance variables since the
-        // methods on this class need to 
-        // be thread safe
+    public CharsetDecoder newDecoder() {
         long converterHandle = NativeConverter.openConverter(icuCanonicalName);
-        return new CharsetDecoderICU(this,converterHandle);
-    };
-    
+        return new CharsetDecoderICU(this, converterHandle);
+    }
+
     // hardCoded list of replacement bytes
-    private static final Map subByteMap = new HashMap();
-    static{
-        subByteMap.put("UTF-32",new byte[]{0x00, 0x00, (byte)0xfe, (byte)0xff});
-        subByteMap.put("ibm-16684_P110-2003",new byte[]{0x40, 0x40}); // make \u3000 the sub char
-        subByteMap.put("ibm-971_P100-1995",new byte[]{(byte)0xa1, (byte)0xa1}); // make \u3000 the sub char
+    private static final Map<String, byte[]> subByteMap = new HashMap<String, byte[]>();
+    static {
+        subByteMap.put("UTF-32", new byte[]{0x00, 0x00, (byte)0xfe, (byte)0xff});
+        subByteMap.put("ibm-16684_P110-2003", new byte[]{0x40, 0x40}); // make \u3000 the sub char
+        subByteMap.put("ibm-971_P100-1995", new byte[]{(byte)0xa1, (byte)0xa1}); // make \u3000 the sub char
     }
     /**
      * Returns a new encoder object of the charset
      * @return a new encoder
      * @stable ICU 2.4
      */
-    public CharsetEncoder newEncoder(){
+    public CharsetEncoder newEncoder() {
         // the arrays are locals and not
         // instance variables since the
-        // methods on this class need to 
+        // methods on this class need to
         // be thread safe
         long converterHandle = NativeConverter.openConverter(icuCanonicalName);
-        
+
         //According to the contract all converters should have non-empty replacement
         byte[] replacement = NativeConverter.getSubstitutionBytes(converterHandle);
 
-       try{
+       try {
             return new CharsetEncoderICU(this,converterHandle, replacement);
-        }catch(IllegalArgumentException ex){
+        } catch (IllegalArgumentException ex) {
             // work around for the non-sensical check in the nio API that
             // a substitution character must be mappable while decoding!!
-            replacement = (byte[])subByteMap.get(icuCanonicalName);
-            if(replacement==null){
+            replacement = subByteMap.get(icuCanonicalName);
+            if (replacement == null) {
                 replacement = new byte[NativeConverter.getMinBytesPerChar(converterHandle)];
-                for(int i=0; i<replacement.length; i++){
+                for(int i = 0; i < replacement.length; ++i) {
                     replacement[i]= 0x3f;
                 }
             }
             NativeConverter.setSubstitutionBytes(converterHandle, replacement, replacement.length);
             return new CharsetEncoderICU(this,converterHandle, replacement);
         }
-    } 
-    
+    }
+
     /**
      * Ascertains if a charset is a sub set of this charset
      * @param cs charset to test
      * @return true if the given charset is a subset of this charset
      * @stable ICU 2.4
-     * 
+     *
      * //CSDL: major changes by Jack
      */
     public boolean contains(Charset cs){
@@ -101,7 +90,7 @@
         } else if (this.equals(cs)) {
             return true;
         }
-        
+
         long converterHandle1 = 0;
         long converterHandle2 = 0;
 
@@ -125,5 +114,3 @@
         }
     }
 }
-
-
diff --git a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetProviderICU.java b/icu/src/main/java/com/ibm/icu4jni/charset/CharsetProviderICU.java
deleted file mode 100644
index 6f63479..0000000
--- a/icu/src/main/java/com/ibm/icu4jni/charset/CharsetProviderICU.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
-*******************************************************************************
-* Copyright (C) 1996-2005, International Business Machines Corporation and    *
-* others. All Rights Reserved.                                                *
-*******************************************************************************
-*
-*******************************************************************************
-*/ 
-
-package com.ibm.icu4jni.charset;
-
-import java.nio.charset.Charset;
-import java.nio.charset.spi.CharsetProvider;
-import java.util.*;
-import java.util.Iterator;
-// BEGIN android-removed
-// import com.ibm.icu4jni.converters.NativeConverter;
-// END android-removed
-
-public final class CharsetProviderICU extends CharsetProvider{
-    
-    /**
-     * Constructs a CharsetProviderICU object 
-     * @stable ICU 2.4
-     */
-    public CharsetProviderICU(){
-    }
-    
-    /**
-     * Constructs a charset for the given charset name
-     * @param charsetName charset name
-     * @return charset objet for the given charset name
-     * @stable ICU 2.4
-     */
-    public final Charset charsetForName(String charsetName) {
-        // get the canonical name    
-        String icuCanonicalName = NativeConverter.getICUCanonicalName(charsetName);      
-
-        // create the converter object and return it
-        if(icuCanonicalName==null || icuCanonicalName.length()==0){
-            // this would make the Charset API to throw 
-            // unsupported encoding exception
-            return null;
-        }
-        
-        // BEGIN android-added
-        try{
-            long cn = NativeConverter.openConverter(icuCanonicalName);
-            NativeConverter.closeConverter(cn);
-        }catch (RuntimeException re) {
-            // unsupported encoding. let the charset api throw an 
-            // UnsupportedEncodingException
-            return null;
-        }
-        // END android-added
-        
-        return getCharset(icuCanonicalName);
-    }
-    private final Charset getCharset(String icuCanonicalName){
-       String[] aliases = (String[])NativeConverter.getAliases(icuCanonicalName);    
-       String canonicalName = NativeConverter.getJavaCanonicalName(icuCanonicalName);
-       return (new CharsetICU(canonicalName,icuCanonicalName, aliases));  
-    }
-    /**
-     * Adds an entry to the given map whose key is the charset's 
-     * canonical name and whose value is the charset itself. 
-     * @param map a map to receive charset objects and names
-     * @stable ICU 2.4
-     */
-    public final void putCharsets(Map map) {
-        // Get the available converter canonical names and aliases    
-        String[] charsets = NativeConverter.getAvailable();        
-        for(int i=0; i<charsets.length;i++){           
-            // store the charsets and aliases in a Map    
-            if (!map.containsKey(charsets[i])){
-                map.put(charsets[i], charsetForName(charsets[i]));
-            }
-        }
-    }
-    /**
-     * Class that implements the iterator for charsets
-     * @stable ICU 2.4
-     */
-    protected final class CharsetIterator implements Iterator{
-      private String[] names;
-      private int currentIndex;
-      protected CharsetIterator(String[] strs){
-        names = strs;
-        currentIndex=0;
-      }
-      public boolean hasNext(){
-        return (currentIndex< names.length);
-      }
-      public Object next(){
-        if(currentIndex<names.length){
-              return charsetForName(names[currentIndex++]);
-        }else{
-              throw new NoSuchElementException();
-        }
-      }
-      public void remove() {
-            throw new UnsupportedOperationException();
-      }
-    }
-      
-
-    /**
-     * Returns an iterator for the available charsets
-     * @return Iterator the charset name iterator
-     * @stable ICU 2.4
-     */
-    public final Iterator charsets(){
-          String[] charsets = NativeConverter.getAvailable();
-          Iterator iter = new CharsetIterator(charsets);
-          return iter;
-    }
-     
-}
diff --git a/icu/src/main/java/com/ibm/icu4jni/charset/NativeConverter.java b/icu/src/main/java/com/ibm/icu4jni/charset/NativeConverter.java
index 9af63ee..6a97c27 100644
--- a/icu/src/main/java/com/ibm/icu4jni/charset/NativeConverter.java
+++ b/icu/src/main/java/com/ibm/icu4jni/charset/NativeConverter.java
@@ -5,26 +5,21 @@
 *******************************************************************************
 *
 *******************************************************************************
-*/ 
+*/
 
 package com.ibm.icu4jni.charset;
 
-/**
- * Class for accessing the underlying JNI methods
- * @internal ICU 2.4
- */
-final class NativeConverter{
-  
-    //Native methods
-    
+import java.nio.charset.Charset;
+
+public final class NativeConverter {
     /**
      * Converts an array of bytes containing characters in an external
      * encoding into an array of Unicode characters.  This  method allows
-     * a buffer by buffer conversion of a data stream.  The state of the
-     * conversion is saved between calls to convert.  Among other things,
+     * buffer-by-buffer conversion of a data stream.  The state of the
+     * conversion is saved between calls.  Among other things,
      * this means multibyte input sequences can be split between calls.
-     * If a call to convert results in an Error, the conversion may be
-     * continued by calling convert again with suitably modified parameters.
+     * If a call to results in an error, the conversion may be
+     * continued by calling this method again with suitably modified parameters.
      * All conversions should be finished with a call to the flush method.
      *
      * @param converterHandle Address of converter object created by C code
@@ -32,52 +27,22 @@
      * @param inEnd stop conversion at this offset in input array (exclusive).
      * @param output character array to receive conversion result.
      * @param outEnd stop writing to output array at this offset (exclusive).
-     * @param data integer array containing the following data    
+     * @param data integer array containing the following data
      *        data[0] = inputOffset
      *        data[1] = outputOffset
      * @return int error code returned by ICU
      * @internal ICU 2.4
      */
-     
-    public static final native int convertByteToChar( long converterHandle,
-                                   byte[] input, int inEnd,
-                                   char[] output, int outEnd,
-                                   int[] data,
-                                   boolean flush);
+    public static native int decode(long converterHandle, byte[] input, int inEnd,
+            char[] output, int outEnd, int[] data, boolean flush);
+
     /**
-     * Converts an array of bytes containing characters in an external
-     * encoding into an array of Unicode characters.  This  method allows
-     * a buffer by buffer conversion of a data stream.  The state of the
+     * Converts an array of Unicode chars to an array of bytes in an external encoding.
+     * This  method allows a buffer by buffer conversion of a data stream.  The state of the
      * conversion is saved between calls to convert.  Among other things,
      * this means multibyte input sequences can be split between calls.
-     * If a call to convert results in an Error, the conversion may be
-     * continued by calling convert again with suitably modified parameters.
-     * All conversions should be finished with a call to the flush method.
-     *
-     * @param converterHandle Address of converter object created by C code
-     * @param input byte array containing text to be converted.
-     * @param inEnd stop conversion at this offset in input array (exclusive).
-     * @param output character array to receive conversion result.
-     * @param outEnd stop writing to output array at this offset (exclusive).
-     * @param data integer array containing the following data    
-     *        data[0] = inputOffset
-     *        data[1] = outputOffset
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */
-    public static final native int decode( long converterHandle,
-                                   byte[] input, int inEnd,
-                                   char[] output, int outEnd,
-                                   int[] data,
-                                   boolean flush);
-    /**
-     * Converts an array of Unicode chars containing characters in an 
-     * external encoding into an array of bytes.  This  method allows
-     * a buffer by buffer conversion of a data stream.  The state of the
-     * conversion is saved between calls to convert.  Among other things,
-     * this means multibyte input sequences can be split between calls.
-     * If a call to convert results in an Error, the conversion may be
-     * continued by calling convert again with suitably modified parameters.
+     * If a call results in an error, the conversion may be
+     * continued by calling this method again with suitably modified parameters.
      * All conversions should be finished with a call to the flush method.
      *
      * @param converterHandle Address of converter object created by C code
@@ -85,331 +50,71 @@
      * @param inEnd stop conversion at this offset in input array (exclusive).
      * @param output byte array to receive conversion result.
      * @param outEnd stop writing to output array at this offset (exclusive).
-     * @param data integer array containing the following data    
+     * @param data integer array containing the following data
      *        data[0] = inputOffset
      *        data[1] = outputOffset
      * @return int error code returned by ICU
      * @internal ICU 2.4
-     */                             
-    public static final native int convertCharToByte(long converterHandle,
-                                   char[] input, int inEnd,
-                                   byte[] output, int outEnd,
-                                   int[] data,
-                                   boolean flush); 
-    /**
-     * Converts an array of Unicode chars containing characters in an 
-     * external encoding into an array of bytes.  This  method allows
-     * a buffer by buffer conversion of a data stream.  The state of the
-     * conversion is saved between calls to convert.  Among other things,
-     * this means multibyte input sequences can be split between calls.
-     * If a call to convert results in an Error, the conversion may be
-     * continued by calling convert again with suitably modified parameters.
-     * All conversions should be finished with a call to the flush method.
-     *
-     * @param converterHandle Address of converter object created by C code
-     * @param input char array containing text to be converted.
-     * @param inEnd stop conversion at this offset in input array (exclusive).
-     * @param output byte array to receive conversion result.
-     * @param outEnd stop writing to output array at this offset (exclusive).
-     * @param data integer array containing the following data    
-     *        data[0] = inputOffset
-     *        data[1] = outputOffset
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */                                     
-    public static final native int encode(long converterHandle,
-                                   char[] input, int inEnd,
-                                   byte[] output, int outEnd,
-                                   int[] data,
-                                   boolean flush);
+     */
+    public static native int encode(long converterHandle, char[] input, int inEnd,
+            byte[] output, int outEnd, int[] data, boolean flush);
+
     /**
      * Writes any remaining output to the output buffer and resets the
-     * converter to its initial state. 
+     * converter to its initial state.
      *
      * @param converterHandle Address of converter object created by C code
      * @param output byte array to receive flushed output.
      * @param outEnd stop writing to output array at this offset (exclusive).
      * @return int error code returned by ICU
-     * @param data integer array containing the following data    
+     * @param data integer array containing the following data
      *        data[0] = inputOffset
      *        data[1] = outputOffset
      * @internal ICU 2.4
-     */ 
-    public static final native int flushCharToByte(long converterHandle,
-                                   byte[] output, 
-                                   int outEnd, 
-                                   int[] data);
+     */
+    public static native int flushCharToByte(long converterHandle, byte[] output, int outEnd, int[] data);
+
     /**
      * Writes any remaining output to the output buffer and resets the
-     * converter to its initial state. 
+     * converter to its initial state.
      *
      * @param converterHandle Address of converter object created by the native code
      * @param output char array to receive flushed output.
      * @param outEnd stop writing to output array at this offset (exclusive).
      * @return int error code returned by ICU
-     * @param data integer array containing the following data    
+     * @param data integer array containing the following data
      *        data[0] = inputOffset
      *        data[1] = outputOffset
      * @internal ICU 2.4
-     */     
-    public static final native int flushByteToChar(long converterHandle,
-                                   char[] output,  
-                                   int outEnd, 
-                                   int[] data);
-    
-    /**
-     * Open the converter with the specified encoding
-     *
-     * @param converterHandle long array for recieving the adress of converter object
-     *        created by the native code
-     * @param encoding string representing encoding
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
      */
-    public static final native long openConverter(String encoding);
-    /**
-     * Resets the ByteToChar (toUnicode) state of specified converter 
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @internal ICU 2.4
-     */
-    public static final native void resetByteToChar(long  converterHandle);
-    
-    /**
-     * Resets the CharToByte (fromUnicode) state of specified converter 
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @internal ICU 2.4
-     */
-    public static final native void resetCharToByte(long  converterHandle);
-    
-    /**
-     * Closes the specified converter and releases the resources
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @internal ICU 2.4
-     */
-    public static final native void closeConverter(long converterHandle);
-    
-    /**
-     * Sets the substitution Unicode chars of the specified converter used
-     * by encoder
-     * @param converterHandle Address of converter object created by the native code
-     * @param subChars array of chars to used for substitution
-     * @param length length of the array 
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */    
-    public static final native int setSubstitutionChars( long converterHandle,
-                                   char[] subChars,int length); 
-    /**
-     * Sets the substitution bytes of the specified converter used by decoder
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @param subChars array of bytes to used for substitution
-     * @param length length of the array 
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */    
-    public static final native int setSubstitutionBytes( long converterHandle,
-                                   byte[] subChars,int length);
-    /**
-     * Sets the substitution mode of CharToByte(fromUnicode) for the specified converter 
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @param mode to set the true/false
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */  
-    public static final native int setSubstitutionModeCharToByte(long converterHandle, 
-                                   boolean mode);
-    /**
-     * Sets the substitution mode of CharToByte(fromUnicode) for the specified converter 
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @param mode to set the true/false
-     * @return int error code returned by ICU
-     * @internal ICU 3.6
-     */  
-    public static final native int setSubstitutionModeByteToChar(long converterHandle, 
-                                   boolean mode);
-    /**
-     * Gets the numnber of invalid bytes in the specified converter object 
-     * for the last error that has occured
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @param length array of int to recieve length of the array 
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */
-    public static final native int countInvalidBytes(long converterHandle, int[] length);
-    
-    /**
-     * Gets the numnber of invalid chars in the specified converter object 
-     * for the last error that has occured
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @param length array of int to recieve length of the array 
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */   
-    public static final native int countInvalidChars(long converterHandle, int[] length);
-    
-    /**
-     * Gets the number of bytes needed for converting a char
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @return number of bytes needed
-     * @internal ICU 2.4
-     */ 
-    public static final native int getMaxBytesPerChar(long converterHandle);
-    
-    /**
-     * Gets the number of bytes needed for converting a char
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @return number of bytes needed
-     * @internal ICU 3.2
-     */ 
-    public static final native int getMinBytesPerChar(long converterHandle);
-    
-    /**
-     * Gets the average numnber of bytes needed for converting a char
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @return number of bytes needed
-     * @internal ICU 2.4
-     */ 
-    public static final native float getAveBytesPerChar(long converterHandle);
-   
-    /**
-     * Gets the number of chars needed for converting a byte
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @return number of bytes needed
-     * @internal ICU 2.4
-     */ 
-    public static final native int getMaxCharsPerByte(long converterHandle);
-   
-    /**
-     * Gets the average numnber of chars needed for converting a byte
-     *
-     * @param converterHandle Address of converter object created by the native code
-     * @return number of bytes needed
-     * @internal ICU 2.4
-     */ 
-    public static final native float getAveCharsPerByte(long converterHandle);
-    
-    //CSDL: added by Jack
-    /**
-     * Determines whether charset1 contains charset2.
-     */
-    public static final native boolean contains(long converterHandle1, long converterHandle2);
-    
-    public static final native byte[] getSubstitutionBytes(long converterHandle);
-    
-    /**
-     * Ascertains if a given Unicode code unit can 
-     * be converted to the target encoding
-     * @param converterHandle Address of converter object created by the native code
-     * @param  codeUnit the character to be converted
-     * @return true if a character can be converted
-     * @internal ICU 2.4
-     * 
-     */
-    public static final native boolean canEncode(long converterHandle,int codeUnit);
-    
-    /**
-     * Ascertains if a given a byte sequence can be converted to Unicode
-     * @param converterHandle Address of converter object created by the native code
-     * @param  bytes the bytes to be converted
-     * @return true if a character can be converted
-     * @internal ICU 2.4
-     * 
-     */
-    public static final native boolean canDecode(long converterHandle,byte[] bytes);
-    
-    /**
-     * Gets the canonical names of available converters 
-     * @return Object[] names as an object array
-     * @internal ICU 2.4
-     */
-    public static final native String[] getAvailable();
-    
-    /**
-     * Gets the number of aliases for a converter name
-     * @param enc encoding name
-     * @return number of aliases for the converter
-     * @internal ICU 2.4
-     */
-    public static final native int countAliases(String enc);
-    
-    /** 
-     * Gets the aliases associated with the converter name
-     * @param enc converter name
-     * @return converter names as elements in an object array
-     * @internal ICU 2.4
-     */
-    public static final native String[] getAliases(String enc);
-    
-    /**
-     * Gets the canonical name of the converter
-     * @param enc converter name
-     * @return canonical name of the converter
-     * @internal ICU 2.4
-     */
-    public static final native String getCanonicalName(String enc);
-    
-    /**
-     * Gets the canonical name of the converter as defined by Java
-     * @param enc converter name
-     * @return canonical name of the converter
-     * @internal ICU 3.4
-     */
-    public static final native String getICUCanonicalName(String enc);
-      
-    /**
-     * Gets the canonical name of the converter as defined by Java
-     * @param icuCanonicalName converter name
-     * @return canonical name of the converter
-     * @internal ICU 3.4
-     */
-    public static final native String getJavaCanonicalName(String icuCanonicalName);
-    
-    /**
-     * Sets the callback to Unicode for ICU conveter. The default behaviour of ICU callback
-     * is to call the specified callback function for both illegal and unmapped sequences.
-     * @param converterHandle Adress of the converter object created by native code
-     * @param mode call back mode to set. This is either STOP_CALLBACK, SKIP_CALLBACK or SUBSTITUE_CALLBACK
-     *        The converter performs the specified callback when an error occurs
-     * @param stopOnIllegal If true sets the alerts the converter callback to stop on an illegal sequence
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */
-    public static final native int setCallbackDecode(long converterHandle, int onMalformedInput, int onUnmappableInput, char[] subChars, int length);
-   
-    /**
-     * Sets the callback from Unicode for ICU conveter. The default behaviour of ICU callback
-     * is to call the specified callback function for both illegal and unmapped sequences.
-     * @param converterHandle Adress of the converter object created by native code
-     * @param mode call back mode to set. This is either STOP_CALLBACK, SKIP_CALLBACK or SUBSTITUE_CALLBACK
-     *        The converter performs the specified callback when an error occurs
-     * @param stopOnIllegal If true sets the alerts the converter callback to stop on an illegal sequence
-     * @return int error code returned by ICU
-     * @internal ICU 2.4
-     */
-    public static final native int setCallbackEncode(long converterHandle, int onMalformedInput, int onUnmappableInput, byte[] subBytes, int length);
-    
-    /**
-     * Returns a thread safe clone of the converter
-     * @internal ICU 2.4
-     */
-    public static final native long safeClone(long converterHandle);
-    
-    /** @internal ICU 2.4 */
+    public static native int flushByteToChar(long converterHandle, char[] output,  int outEnd, int[] data);
+
+    public static native long openConverter(String encoding);
+    public static native void closeConverter(long converterHandle);
+
+    public static native void resetByteToChar(long  converterHandle);
+    public static native void resetCharToByte(long  converterHandle);
+
+    public static native int setSubstitutionChars(long converterHandle, char[] subChars,int length);
+    public static native int setSubstitutionBytes(long converterHandle, byte[] subChars,int length);
+    public static native byte[] getSubstitutionBytes(long converterHandle);
+
+    public static native int getMaxBytesPerChar(long converterHandle);
+    public static native int getMinBytesPerChar(long converterHandle);
+    public static native float getAveBytesPerChar(long converterHandle);
+    public static native int getMaxCharsPerByte(long converterHandle);
+    public static native float getAveCharsPerByte(long converterHandle);
+
+    public static native boolean contains(long converterHandle1, long converterHandle2);
+
+    public static native boolean canEncode(long converterHandle, int codeUnit);
+
+    public static native String[] getAvailableCharsetNames();
+    public static native Charset charsetForName(String charsetName);
+
     public static final int STOP_CALLBACK = 0;//CodingErrorAction.REPORT
-    /** @internal ICU 2.4 */
     public static final int SKIP_CALLBACK = 1;//CodingErrorAction.IGNORE
-    /** @internal ICU 2.4 */
     public static final int SUBSTITUTE_CALLBACK = 2;//CodingErrorAction.REPLACE
+    public static native int setCallbackDecode(long converterHandle, int onMalformedInput, int onUnmappableInput, char[] subChars, int length);
+    public static native int setCallbackEncode(long converterHandle, int onMalformedInput, int onUnmappableInput, byte[] subBytes, int length);
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/lang/UCharacter.java b/icu/src/main/java/com/ibm/icu4jni/lang/UCharacter.java
index 2839ac3..08fe26a 100644
--- a/icu/src/main/java/com/ibm/icu4jni/lang/UCharacter.java
+++ b/icu/src/main/java/com/ibm/icu4jni/lang/UCharacter.java
@@ -18,7 +18,7 @@
 
 import java.lang.Character.UnicodeBlock;
 
-public class UCharacter {
+public final class UCharacter {
 
     public static native boolean isDefined(int codePoint);
     public static native boolean isDigit(int codePoint);
@@ -42,6 +42,8 @@
     public static native int toLowerCase(int codePoint);
     public static native int toTitleCase(int codePoint);
     public static native int toUpperCase(int codePoint);
+    public static native String toLowerCase(String s, String localeName);
+    public static native String toUpperCase(String s, String localeName);
 
     public static UnicodeBlock[] getBlockTable() {
         /**
diff --git a/icu/src/main/java/com/ibm/icu4jni/regex/NativeRegEx.java b/icu/src/main/java/com/ibm/icu4jni/regex/NativeRegEx.java
index bdfff5b..a8ce8a6 100644
--- a/icu/src/main/java/com/ibm/icu4jni/regex/NativeRegEx.java
+++ b/icu/src/main/java/com/ibm/icu4jni/regex/NativeRegEx.java
@@ -16,7 +16,9 @@
 
 package com.ibm.icu4jni.regex;
 
-public class NativeRegEx {
+public final class NativeRegEx {
+    private NativeRegEx() {
+    }
 
     /**
      * Opens (compiles) an ICU regular expression.
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java b/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
deleted file mode 100644
index 5ef1161..0000000
--- a/icu/src/main/java/com/ibm/icu4jni/text/BreakIterator.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ibm.icu4jni.text;
-
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-import java.util.Locale;
-
-public abstract class BreakIterator implements Cloneable
-{
-    protected static final int BI_CHAR_INSTANCE = 1;
-    protected static final int BI_WORD_INSTANCE = 2;
-    protected static final int BI_LINE_INSTANCE = 3;
-    protected static final int BI_SENT_INSTANCE = 4;
-    
-    protected int type = 0;
-    
-    public static Locale[] getAvailableLocales() {
-        
-        String[] locales = NativeBreakIterator.getAvailableLocalesImpl();
-        
-        Locale[] result = new Locale[locales.length];
-        
-        String locale;
-        
-        int index, index2;
-        
-        for(int i = 0; i < locales.length; i++) {
-            locale = locales[i];
-            
-            index = locale.indexOf('_');
-            index2 = locale.lastIndexOf('_');
-            
-            if(index == -1) {
-                result[i] = new Locale(locales[i]);
-            } else if(index > 0 && index == index2) {
-                result[i] = new Locale(
-                        locale.substring(0,index),
-                        locale.substring(index+1));
-            } else if(index > 0 && index2 > index) {
-                result[i] = new Locale(
-                        locale.substring(0,index),
-                        locale.substring(index+1,index2),
-                        locale.substring(index2+1));
-            }
-        }
-        
-        return result;
-    }
-    
-    public static BreakIterator getCharacterInstance() {
-        int iter = NativeBreakIterator.getCharacterInstanceImpl("");
-        return new RuleBasedBreakIterator(iter, BI_CHAR_INSTANCE);
-    }
-
-    public static BreakIterator getCharacterInstance(Locale where) {
-        int iter = NativeBreakIterator.getCharacterInstanceImpl(where.toString());
-        return new RuleBasedBreakIterator(iter, BI_CHAR_INSTANCE);
-    }
-
-    public static BreakIterator getLineInstance() {
-        int iter = NativeBreakIterator.getLineInstanceImpl("");
-        return new RuleBasedBreakIterator(iter, BI_LINE_INSTANCE);
-    }
-    
-    public static BreakIterator getLineInstance(Locale where) {
-        int iter = NativeBreakIterator.getLineInstanceImpl(where.toString());
-        return new RuleBasedBreakIterator(iter, BI_LINE_INSTANCE);
-    }
-    
-    public static BreakIterator getSentenceInstance() {
-        int iter = NativeBreakIterator.getSentenceInstanceImpl("");
-        return new RuleBasedBreakIterator(iter, BI_SENT_INSTANCE);
-    }
-
-    public static BreakIterator getSentenceInstance(Locale where) {
-        int iter = NativeBreakIterator.getSentenceInstanceImpl(where.toString());
-        return new RuleBasedBreakIterator(iter, BI_SENT_INSTANCE);
-    }
-    
-    public static BreakIterator getWordInstance() {
-        int iter = NativeBreakIterator.getWordInstanceImpl("");
-        return new RuleBasedBreakIterator(iter, BI_WORD_INSTANCE);
-    }
-
-    public static BreakIterator getWordInstance(Locale where) {
-        int iter = NativeBreakIterator.getWordInstanceImpl(where.toString());
-        return new RuleBasedBreakIterator(iter, BI_WORD_INSTANCE);
-    }
-
-    public void setText(String newText) {
-        setText(new StringCharacterIterator(newText));
-    }
-
-    public abstract boolean isBoundary(int offset);
-
-    public abstract int preceding(int offset);
-    
-    public abstract Object clone();
-
-    public abstract int current();
-
-    public abstract int first();
-
-    public abstract int following(int offset);
-
-    public abstract CharacterIterator getText();
-
-    public abstract int last();
-
-    public abstract int next(int n);
-
-    public abstract int next();
-
-    public abstract int previous();
-
-    public abstract void setText(CharacterIterator newText);
-
-}
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java b/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java
index b1c6107..eaf626f 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/CollationAttribute.java
@@ -10,205 +10,31 @@
 package com.ibm.icu4jni.text;
 
 /**
-* Interface for storing ICU collation equivalent enum values.
-* Constants with the prefix VALUE corresponds to ICU's UColAttributeValues,
-* the rest corresponds to UColAttribute.
-* @author syn wee quek
-* @stable ICU 2.4
-*/
-
-public final class CollationAttribute
-{ 
-  // Collation strength constants ----------------------------------
-  /**
-  * Default value, accepted by most attributes
-  * @stable ICU 2.4
-  */ 
-  public static final int VALUE_DEFAULT = -1;
-  /** 
-  * Primary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_PRIMARY = 0;
-  /** 
-  * Secondary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_SECONDARY = 1;
-  /** 
-  * Tertiary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_TERTIARY = 2;
-  /** 
-  * Default collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_DEFAULT_STRENGTH = VALUE_TERTIARY;
-  /** 
-  * Quaternary collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_QUATERNARY = 3;
-  /** 
-  * Identical collation strength 
-  * @stable ICU 2.4
-  */
-  public static final int VALUE_IDENTICAL = 15;
-
-  /** 
-   * Turn the feature off - works for FRENCH_COLLATION, CASE_LEVEL, 
-   * HIRAGANA_QUATERNARY_MODE and DECOMPOSITION_MODE
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_OFF = 16;
-  /** @stable ICU 2.4 */
-  public static final int VALUE_ON = 17;
-  
-  /** 
-   * ALTERNATE_HANDLING mode constants
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_SHIFTED = 20;
-  /** @stable ICU 2.4 */
-  public static final int VALUE_NON_IGNORABLE = 21;
-
-  /** 
-   * CASE_FIRST mode constants
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_LOWER_FIRST = 24;
-  /** @stable ICU 2.4 */
-  public static final int VALUE_UPPER_FIRST = 25;
-
-  /** 
-   * NORMALIZATION_MODE mode constants
-   * @deprecated ICU 2.4. Users advised to use VALUE_ON instead.
-   */
-  public static final int VALUE_ON_WITHOUT_HANGUL = 28;
-
-  /** 
-   * Number of attribute value constants
-   * @stable ICU 2.4
-   */
-  public static final int VALUE_ATTRIBUTE_VALUE_COUNT = 29;
-
-  // Collation attribute constants -----------------------------------
-  
-  /** 
-   * Attribute for direction of secondary weights
-   * @stable ICU 2.4
-   */
-  public static final int FRENCH_COLLATION = 0;
-  /** 
-   * Attribute for handling variable elements
-   * @stable ICU 2.4
-   */
-  public static final int ALTERNATE_HANDLING = 1;
-  /** 
-   * Who goes first, lower case or uppercase.
-   * @stable ICU 2.4
-   */
-  public static final int CASE_FIRST = 2;
-  /** 
-   * Do we have an extra case level
-   * @stable ICU 2.4
-   */
-  public static final int CASE_LEVEL = 3;
-  /** 
-   * Attribute for normalization
-   * @stable ICU 2.4
-   */
-  public static final int NORMALIZATION_MODE = 4; 
-  /** 
-   * Attribute for strength 
-   * @stable ICU 2.4
-   */
-  public static final int STRENGTH = 5;
-  /** 
-   * Attribute count
-   * @stable ICU 2.4
-   */
-  public static final int ATTRIBUTE_COUNT = 6;
-  
-  // package methods --------------------------------------------------
-  
-  /**
-  * Checks if argument is a valid collation strength
-  * @param strength potential collation strength
-  * @return true if strength is a valid collation strength, false otherwise
-  */
-  static boolean checkStrength(int strength)
-  {
-    if (strength < VALUE_PRIMARY || 
-        (strength > VALUE_QUATERNARY && strength != VALUE_IDENTICAL))
-      return false;
-    return true;
-  }
-  
-  /**
-  * Checks if argument is a valid collation type
-  * @param type collation type to be checked
-  * @return true if type is a valid collation type, false otherwise
-  */
-  static boolean checkType(int type)
-  {
-    if (type < FRENCH_COLLATION || type > STRENGTH)
-      return false;
-    return true;
-  }
-
-  /**
-  * Checks if argument is a valid normalization type
-  * @param type normalization type to be checked
-  * @return true if type is a valid normalization type, false otherwise
-  */
-  static boolean checkNormalization(int type)
-  {
-    if (type != VALUE_ON && type != VALUE_OFF 
-        && type != VALUE_ON_WITHOUT_HANGUL) {
-        return false;
-    }
-    return true;
-  }
-  
-  /**
-  * Checks if attribute type and corresponding attribute value is valid
-  * @param type attribute type
-  * @param value attribute value
-  * @return true if the pair is valid, false otherwise
-  */
-  static boolean checkAttribute(int type, int value)
-  {
-    if (value == VALUE_DEFAULT) {
-      return true;
-    }
-      
-    switch (type)
-    {
-      case FRENCH_COLLATION :
-                          if (value >= VALUE_OFF && value <= VALUE_ON)
-                            return true;
-                          break;
-      case ALTERNATE_HANDLING :
-                          if (value >= VALUE_SHIFTED && 
-                              value <= VALUE_NON_IGNORABLE)
-                            return true;
-                          break;
-      case CASE_FIRST :
-                          if (value >= VALUE_LOWER_FIRST && 
-                              value <= VALUE_UPPER_FIRST)
-                            return true;
-                          break;
-      case CASE_LEVEL :
-                          return (value == VALUE_ON || 
-                                  value <= VALUE_OFF);
-      case NORMALIZATION_MODE : 
-                          return (value == VALUE_OFF || value == VALUE_ON ||
-                                  value == VALUE_ON_WITHOUT_HANGUL);
-      case STRENGTH :
-                          checkStrength(value);
-    }
-    return false;
-  }
+ * TODO: move these constants into NativeCollation.
+ */
+public final class CollationAttribute {
+    // Values from the native UColAttributeValue enum.
+    public static final int VALUE_DEFAULT = -1;
+    public static final int VALUE_PRIMARY = 0;
+    public static final int VALUE_SECONDARY = 1;
+    public static final int VALUE_TERTIARY = 2;
+    public static final int VALUE_DEFAULT_STRENGTH = VALUE_TERTIARY;
+    public static final int VALUE_QUATERNARY = 3;
+    public static final int VALUE_IDENTICAL = 15;
+    public static final int VALUE_OFF = 16;
+    public static final int VALUE_ON = 17;
+    public static final int VALUE_SHIFTED = 20;
+    public static final int VALUE_NON_IGNORABLE = 21;
+    public static final int VALUE_LOWER_FIRST = 24;
+    public static final int VALUE_UPPER_FIRST = 25;
+    public static final int VALUE_ON_WITHOUT_HANGUL = 28;
+    public static final int VALUE_ATTRIBUTE_VALUE_COUNT = 29;
+    // Values from the UColAttribute enum.
+    public static final int FRENCH_COLLATION = 0;
+    public static final int ALTERNATE_HANDLING = 1;
+    public static final int CASE_FIRST = 2;
+    public static final int CASE_LEVEL = 3;
+    public static final int NORMALIZATION_MODE = 4;
+    public static final int DECOMPOSITION_MODE = NORMALIZATION_MODE;
+    public static final int STRENGTH = 5;
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java b/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
index 9e9401d..dbd714c 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/CollationKey.java
@@ -11,176 +11,112 @@
 package com.ibm.icu4jni.text;
 
 /**
-* Collation key wrapper, containing the byte array sort key.
-* @author syn wee quek
-* @stable ICU 2.4
-*/
+ * A concrete implementation of the abstract java.text.CollationKey.
+ */
+public final class CollationKey extends java.text.CollationKey {
+    /**
+     * The key.
+     */
+    private final byte[] bytes;
 
-public final class CollationKey implements Comparable
-{ 
-  // public methods -----------------------------------------------
+    /**
+     * Cached hash value.
+     */
+    private int hashCode;
 
-  /**
-  * Bitwise comparison for the collation keys
-  * @param target CollationKey to be compared
-  * @return comparison result from Collator, RESULT_LESS, RESULT_EQUAL, 
-  *         RESULT_GREATER
-  * @stable ICU 2.4    
-  */
-  public int compareTo(CollationKey target)
-  {
-    byte tgtbytes[] = target.m_bytes_;
-    
-    if (m_bytes_ == null || m_bytes_.length == 0) {
-      if (tgtbytes == null || tgtbytes.length == 0) {
-        return Collator.RESULT_EQUAL;
-      }
-      return Collator.RESULT_LESS;
-    }
-    else {
-      if (tgtbytes == null || tgtbytes.length == 0) {
-        return Collator.RESULT_GREATER;
-      }
-    }
-        
-    int count = m_bytes_.length;
-    if (tgtbytes.length < count) {
-      count = tgtbytes.length;
+    CollationKey(String source, byte[] bytes) {
+        super(source);
+        this.bytes = bytes;
     }
 
-    int s,
-        t;
-    for (int i = 0; i < count; i ++)
-    {
-      // unable to use Arrays.equals
-      s = m_bytes_[i] & UNSIGNED_BYTE_MASK_;
-      t = tgtbytes[i] & UNSIGNED_BYTE_MASK_;
-      if (s < t) {
-        return Collator.RESULT_LESS;
-      }
-      if (s > t) {
-        return Collator.RESULT_GREATER;
-      }
+    public int compareTo(java.text.CollationKey other) {
+        // Get the bytes from the other collation key.
+        final byte[] rhsBytes;
+        if (other instanceof CollationKey) {
+            rhsBytes = ((CollationKey) other).bytes;
+        } else {
+            rhsBytes = other.toByteArray();
+        }
+
+        if (bytes == null || bytes.length == 0) {
+            if (rhsBytes == null || rhsBytes.length == 0) {
+                return 0;
+            }
+            return -1;
+        } else {
+            if (rhsBytes == null || rhsBytes.length == 0) {
+                return 1;
+            }
+        }
+
+        int count = Math.min(bytes.length, rhsBytes.length);
+        for (int i = 0; i < count; ++i) {
+            int s = bytes[i] & 0xff;
+            int t = rhsBytes[i] & 0xff;
+            if (s < t) {
+                return -1;
+            }
+            if (s > t) {
+                return 1;
+            }
+        }
+        if (bytes.length < rhsBytes.length) {
+            return -1;
+        }
+        if (bytes.length > rhsBytes.length) {
+            return 1;
+        }
+        return 0;
     }
 
-    if (m_bytes_.length < target.m_bytes_.length) {
-      return Collator.RESULT_LESS;
+    /**
+     * Checks if target object is equal to this object.
+     * Target is first casted to CollationKey and bitwise compared.
+     * @param target comparison object
+     * @return true if both objects are equal, false otherwise
+     * @stable ICU 2.4
+     */
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (!(object instanceof CollationKey)) {
+            return false;
+        }
+        return compareTo((CollationKey) object) == 0;
     }
-    
-    if (m_bytes_.length > target.m_bytes_.length) {
-      return Collator.RESULT_GREATER;
+
+    /**
+     * Creates a hash code for this CollationKey.
+     * Compute the hash by iterating sparsely over about 32 (up to 63) bytes
+     * spaced evenly through the string.  For each byte, multiply the previous
+     * hash value by a prime number and add the new byte in, like a linear
+     * congruential random number generator, producing a pseudo-random
+     * deterministic value well distributed over the output range.
+     * @return hash value of collation key. Hash value is never 0.
+     * @stable ICU 2.4
+     */
+    public int hashCode() {
+        if (hashCode == 0) {
+            if (bytes != null && bytes.length != 0) {
+                int len = bytes.length;
+                int inc = ((len - 32) / 32) + 1;
+                for (int i = 0; i < len;) {
+                    hashCode = (hashCode * 37) + bytes[i];
+                    i += inc;
+                }
+            }
+            if (hashCode == 0) {
+                hashCode = 1;
+            }
+        }
+        return hashCode;
     }
-    
-    return Collator.RESULT_EQUAL;
-  }
-  
-  /**
-  * Bitwise comparison for the collation keys.
-  * Argument is casted to CollationKey
-  * @param target CollationKey to be compared
-  * @return comparison result from Collator, RESULT_LESS, RESULT_EQUAL, 
-  * RESULT_GREATER
-  * @stable ICU 2.4
-  */
-  public int compareTo(Object target)
-  {
-    return compareTo((CollationKey)target);
-  }
 
-  /**
-  * Checks if target object is equal to this object.
-  * Target is first casted to CollationKey and bitwise compared.
-  * @param target comparison object
-  * @return true if both objects are equal, false otherwise
-  * @stable ICU 2.4
-  */
-  public boolean equals(Object target)
-  {
-    if (this == target) {
-      return true;
+    public byte[] toByteArray() {
+        if (bytes == null || bytes.length == 0) {
+            return null;
+        }
+        return bytes.clone();
     }
-      
-    // checks getClass here since CollationKey is final not subclassable
-    if (target == null || target.getClass() != getClass()) {
-      return false;
-    }
-    
-    return compareTo((CollationKey)target) == Collator.RESULT_EQUAL;
-  }
-
-  /**
-  * Creates a hash code for this CollationKey. 
-  * Compute the hash by iterating sparsely over about 32 (up to 63) bytes 
-  * spaced evenly through the string.  For each byte, multiply the previous 
-  * hash value by a prime number and add the new byte in, like a linear 
-  * congruential random number generator, producing a pseudorandom 
-  * deterministic value well distributed over the output range.
-  * @return hash value of collation key. Hash value is never 0.
-  * @stable ICU 2.4
-  */
-  public int hashCode()
-  {
-    if (m_hash_ == 0)
-    {
-      if (m_bytes_ != null && m_bytes_.length != 0)
-      {                        
-        int len = m_bytes_.length;
-        int inc = ((len - 32) / 32) + 1;  
-        for (int i = 0; i < len;)
-        {
-          m_hash_ = (m_hash_ * 37) + m_bytes_[i];
-          i += inc;                         
-        }                                     
-      }             
-      if (m_hash_ == 0)
-        m_hash_ = 1;
-    }
-    return m_hash_;
-  }
-
-  /**
-  * Create the value of the Collation key in term of bytes
-  * @return value of Collation key in bytes
-  * @stable ICU 2.4
-  */
-  public byte[] toByteArray()
-  {
-    if (m_bytes_ == null || m_bytes_.length == 0)
-      return null;
-      
-    return (byte[])m_bytes_.clone(); 
-  }
-
-  // package constructors ----------------------------------------------
-  
-  /**
-  * Default constructor, for use by the Collator and its subclasses.
-  */
-  CollationKey()
-  {
-    m_hash_ = 0;
-  }
-  
-  /**
-  * Constructor, for use only by the Collator and its subclasses.
-  */
-  CollationKey(byte[] bytes)
-  {
-    m_bytes_ = bytes;
-    m_hash_ = 0;
-  }
-
-  // private data members -----------------------------------------------
-  
-  private byte m_bytes_[];
-  
-  /**
-  * Mask value to retrieve a single unsigned byte
-  */
-  private static final int UNSIGNED_BYTE_MASK_ = 0x00FF;
-  
-  /**
-  * Cached hash value
-  */
-  private int m_hash_;
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/Collator.java b/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
index 4a7e1bf..7883d30 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/Collator.java
@@ -10,18 +10,18 @@
 
 package com.ibm.icu4jni.text;
 
-import java.util.Locale;
 import com.ibm.icu4jni.text.RuleBasedCollator;
+import java.util.Locale;
 
 /**
 * Abstract class handling locale specific collation via JNI and ICU.
-* Subclasses implement specific collation strategies. One subclass, 
-* com.ibm.icu4jni.text.RuleBasedCollator, is currently provided and is 
-* applicable to a wide set of languages. Other subclasses may be created to 
-* handle more specialized needs. 
-* You can use the static factory method, getInstance(), to obtain the 
-* appropriate Collator object for a given locale. 
-* 
+* Subclasses implement specific collation strategies. One subclass,
+* com.ibm.icu4jni.text.RuleBasedCollator, is currently provided and is
+* applicable to a wide set of languages. Other subclasses may be created to
+* handle more specialized needs.
+* You can use the static factory method, getInstance(), to obtain the
+* appropriate Collator object for a given locale.
+*
 * <pre>
 * // Compare two strings in the default locale
 * Collator myCollator = Collator.getInstance();
@@ -33,18 +33,18 @@
 * }
 * </pre>
 *
-* You can set a Collator's strength property to determine the level of 
-* difference considered significant in comparisons. 
-* Five strengths in CollationAttribute are provided: VALUE_PRIMARY, 
-* VALUE_SECONDARY, VALUE_TERTIARY, VALUE_QUARTENARY and VALUE_IDENTICAL. 
-* The exact assignment of strengths to language features is locale dependant. 
-* For example, in Czech, "e" and "f" are considered primary differences, while 
-* "e" and "?" latin small letter e with circumflex are secondary differences, 
-* "e" and "E" are tertiary differences and "e" and "e" are identical. 
+* You can set a Collator's strength property to determine the level of
+* difference considered significant in comparisons.
+* Five strengths in CollationAttribute are provided: VALUE_PRIMARY,
+* VALUE_SECONDARY, VALUE_TERTIARY, VALUE_QUATERNARY and VALUE_IDENTICAL.
+* The exact assignment of strengths to language features is locale-dependent.
+* For example, in Czech, "e" and "f" are considered primary differences, while
+* "e" and "?" latin small letter e with circumflex are secondary differences,
+* "e" and "E" are tertiary differences and "e" and "e" are identical.
 *
 * <p>
-* The following shows how both case and accents could be ignored for US 
-* English. 
+* The following shows how both case and accents could be ignored for US
+* English.
 * <pre>
 * //Get the Collator for US English and set its strength to PRIMARY
 * Collator usCollator = Collator.getInstance(Locale.US);
@@ -53,15 +53,15 @@
 *   System.out.println("Strings are equivalent");
 * }
 * </pre>
-* For comparing Strings exactly once, the compare method provides the best 
-* performance. 
-* When sorting a list of Strings however, it is generally necessary to compare 
-* each String multiple times. 
-* In this case, com.ibm.icu4jni.text.CollationKey provide better performance. 
-* The CollationKey class converts a String to a series of bits that can be 
-* compared bitwise against other CollationKeys. 
-* A CollationKey is created by a Collator object for a given String. 
-* Note: CollationKeys from different Collators can not be compared. 
+* For comparing Strings exactly once, the compare method provides the best
+* performance.
+* When sorting a list of Strings however, it is generally necessary to compare
+* each String multiple times.
+* In this case, com.ibm.icu4jni.text.CollationKey provide better performance.
+* The CollationKey class converts a String to a series of bits that can be
+* compared bitwise against other CollationKeys.
+* A CollationKey is created by a Collator object for a given String.
+* Note: CollationKeys from different Collators can not be compared.
 * </p>
 *
 * Considerations :
@@ -71,12 +71,9 @@
 * @stable ICU 2.4
 */
 
-public abstract class Collator implements Cloneable
-{ 
-    // public data members ---------------------------------------------------
-        
+public abstract class Collator implements Cloneable {
     /**
-     * Strongest collator strength value. Typically used to denote differences 
+     * Strongest collator strength value. Typically used to denote differences
      * between base characters. See class documentation for more explanation.
      * @see #setStrength
      * @see #getStrength
@@ -85,10 +82,10 @@
     public final static int PRIMARY = CollationAttribute.VALUE_PRIMARY;
 
     /**
-     * Second level collator strength value. 
+     * Second level collator strength value.
      * Accents in the characters are considered secondary differences.
-     * Other differences between letters can also be considered secondary 
-     * differences, depending on the language. 
+     * Other differences between letters can also be considered secondary
+     * differences, depending on the language.
      * See class documentation for more explanation.
      * @see #setStrength
      * @see #getStrength
@@ -97,23 +94,23 @@
     public final static int SECONDARY = CollationAttribute.VALUE_SECONDARY;
 
     /**
-     * Third level collator strength value. 
+     * Third level collator strength value.
      * Upper and lower case differences in characters are distinguished at this
-     * strength level. In addition, a variant of a letter differs from the base 
+     * strength level. In addition, a variant of a letter differs from the base
      * form on the tertiary level.
      * See class documentation for more explanation.
      * @see #setStrength
      * @see #getStrength
      * @stable ICU 2.4
      */
-    public final static int TERTIARY = CollationAttribute.VALUE_TERTIARY;                            
+    public final static int TERTIARY = CollationAttribute.VALUE_TERTIARY;
 
     /**
-     * Fourth level collator strength value. 
-     * When punctuation is ignored 
+     * Fourth level collator strength value.
+     * When punctuation is ignored
      * <a href="http://www-124.ibm.com/icu/userguide/Collate_Concepts.html#Ignoring_Punctuation">
-     * (see Ignoring Punctuations in the user guide)</a> at PRIMARY to TERTIARY 
-     * strength, an additional strength level can 
+     * (see Ignoring Punctuations in the user guide)</a> at PRIMARY to TERTIARY
+     * strength, an additional strength level can
      * be used to distinguish words with and without punctuation.
      * See class documentation for more explanation.
      * @see #setStrength
@@ -124,10 +121,10 @@
 
     /**
      * <p>
-     * Smallest Collator strength value. When all other strengths are equal, 
-     * the IDENTICAL strength is used as a tiebreaker. The Unicode code point 
-     * values of the NFD form of each string are compared, just in case there 
-     * is no difference. 
+     * Smallest Collator strength value. When all other strengths are equal,
+     * the IDENTICAL strength is used as a tiebreaker. The Unicode code point
+     * values of the NFD form of each string are compared, just in case there
+     * is no difference.
      * See class documentation for more explanation.
      * </p>
      * <p>
@@ -147,7 +144,7 @@
      * @see #CANONICAL_DECOMPOSITION
      * @see #getDecomposition
      * @see #setDecomposition
-     * @stable ICU 2.4 
+     * @stable ICU 2.4
      */
     public final static int NO_DECOMPOSITION = CollationAttribute.VALUE_OFF;
 
@@ -163,132 +160,65 @@
      * @see #NO_DECOMPOSITION
      * @see #getDecomposition
      * @see #setDecomposition
-     * @stable ICU 2.4 
-     */
-    public final static int CANONICAL_DECOMPOSITION 
-                                                = CollationAttribute.VALUE_ON;
-  
-    // Collation result constants -----------------------------------
-    // corresponds to ICU's UCollationResult enum balues
-    /** 
-     * string a == string b 
      * @stable ICU 2.4
      */
-    public static final int RESULT_EQUAL = 0;
-    /** 
-     * string a > string b 
-     * @stable ICU 2.4
-     */
-    public static final int RESULT_GREATER = 1;
-    /** 
-     * string a < string b 
-     * @stable ICU 2.4
-     */
-    public static final int RESULT_LESS = -1;
-    /** 
-     * accepted by most attributes 
-     * @stable ICU 2.4
-     */
-    public static final int RESULT_DEFAULT = -1;
-  
-    // public methods -----------------------------------------------
-  
-  /**
-  * Factory method to create an appropriate Collator which uses the default
-  * locale collation rules.
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  * @return an instance of Collator
-  * @stable ICU 2.4
-  */
-  public static Collator getInstance()
-  {
-    return getInstance(null);
-  }
+    public final static int CANONICAL_DECOMPOSITION = CollationAttribute.VALUE_ON;
 
-  /**
-  * Factory method to create an appropriate Collator which uses the argument
-  * locale collation rules.<br>
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  * @param locale to be used for collation
-  * @return an instance of Collator
-  * @stable ICU 2.4
-  */
-  public static Collator getInstance(Locale locale)
-  {
-    RuleBasedCollator result = new RuleBasedCollator(locale);
-    return result;
-  }
+    public static Collator getInstance() {
+        return getInstance(null);
+    }
 
-  /**
-  * Locale dependent equality check for the argument strings.
-  * @param source string
-  * @param target string
-  * @return true if source is equivalent to target, false otherwise 
-  * @stable ICU 2.4
-  */
-  public boolean equals(String source, String target)
-  {
-    return (compare(source, target) == RESULT_EQUAL);
-  }
-  
-  /**
-  * Checks if argument object is equals to this object.
-  * @param target object
-  * @return true if source is equivalent to target, false otherwise 
-  * @stable ICU 2.4
-  */
-  public abstract boolean equals(Object target);
-  
-  /**
-  * Makes a copy of the current object.
-  * @return a copy of this object
-  * @stable ICU 2.4
-  */
-  public abstract Object clone() throws CloneNotSupportedException;
-  
-  /**
-  * The comparison function compares the character data stored in two
-  * different strings. Returns information about whether a string is less 
-  * than, greater than or equal to another string.
-  * <p>Example of use:
-  * <pre>
-  * .  Collator myCollation = Collator.getInstance(Locale::US);
-  * .  myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
-  * .  // result would be CollationAttribute.VALUE_EQUAL 
-  * .  // ("abc" == "ABC")
-  * .  // (no primary difference between "abc" and "ABC")
-  * .  int result = myCollation.compare("abc", "ABC",3);
-  * .  myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
-  * .  // result would be Collation.LESS (abc" &lt;&lt;&lt; "ABC")
-  * .  // (with tertiary difference between "abc" and "ABC")
-  * .  int result = myCollation.compare("abc", "ABC",3);
-  * </pre>
-  * @param source source string.
-  * @param target target string.
-  * @return result of the comparison, Collator.RESULT_EQUAL, 
-  *         Collator.RESULT_GREATER or Collator.RESULT_LESS
-  * @stable ICU 2.4
-  */
-  public abstract int compare(String source, String target);
-                                               
     /**
-     * Get the decomposition mode of this Collator. 
+     * Factory method to create an appropriate Collator which uses the given
+     * locale's collation rules.<br>
+     * Current implementation createInstance() returns a RuleBasedCollator(Locale)
+     * instance. The RuleBasedCollator will be created in the following order,
+     * <ul>
+     * <li> Data from argument locale resource bundle if found, otherwise
+     * <li> Data from parent locale resource bundle of given locale if found, otherwise
+     * <li> Data from built-in default collation rules if found, other
+     * <li> null is returned
+     * </ul>
+     * @param locale to be used for collation
+     * @return an instance of Collator
+     * @stable ICU 2.4
+     */
+    public static Collator getInstance(Locale locale) {
+        RuleBasedCollator result = new RuleBasedCollator(locale);
+        return result;
+    }
+
+    public boolean equals(String source, String target) {
+        return (compare(source, target) == 0);
+    }
+
+    public abstract boolean equals(Object target);
+
+    public abstract Object clone() throws CloneNotSupportedException;
+
+    /**
+     * The comparison function compares the character data stored in two
+     * different strings. Returns information about whether a string is less
+     * than, greater than or equal to another string.
+     * <p>Example of use:
+     * <pre>
+     * .  Collator myCollation = Collator.getInstance(Locale::US);
+     * .  myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
+     * .  // result would be CollationAttribute.VALUE_EQUAL
+     * .  // ("abc" == "ABC")
+     * .  // (no primary difference between "abc" and "ABC")
+     * .  int result = myCollation.compare("abc", "ABC",3);
+     * .  myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
+     * .  // result would be Collation.LESS (abc" &lt;&lt;&lt; "ABC")
+     * .  // (with tertiary difference between "abc" and "ABC")
+     * .  int result = myCollation.compare("abc", "ABC",3);
+     * </pre>
+     * @stable ICU 2.4
+     */
+    public abstract int compare(String source, String target);
+
+    /**
+     * Get the decomposition mode of this Collator.
      * @return the decomposition mode
      * @see #CANONICAL_DECOMPOSITION
      * @see #NO_DECOMPOSITION
@@ -313,7 +243,7 @@
      * E.g. with strength == SECONDARY, the tertiary difference is ignored
      * </p>
      * <p>
-     * E.g. with strength == PRIMARY, the secondary and tertiary difference 
+     * E.g. with strength == PRIMARY, the secondary and tertiary difference
      * are ignored.
      * </p>
      * @return the current comparison level.
@@ -325,15 +255,15 @@
      * @stable ICU 2.4
      */
     public abstract int getStrength();
-  
-  /**
-  * Gets the attribute to be used in comparison or transformation.
-  * @param type the attribute to be set from CollationAttribute
-  * @return value attribute value from CollationAttribute
-  * @stable ICU 2.4
-  */
-  public abstract int getAttribute(int type);
-  
+
+    /**
+     * Gets the attribute to be used in comparison or transformation.
+     * @param type the attribute to be set from CollationAttribute
+     * @return value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public abstract int getAttribute(int type);
+
     /**
      * Sets the minimum strength to be used in comparison or transformation.
      * <p>Example of use:
@@ -342,90 +272,55 @@
      * . myCollation.setStrength(PRIMARY);
      * . // result will be "abc" == "ABC"
      * . // tertiary differences will be ignored
-     * . int result = myCollation->compare("abc", "ABC"); 
+     * . int result = myCollation->compare("abc", "ABC");
      * </pre>
      * @param strength the new comparison level.
      * @see #PRIMARY
      * @see #SECONDARY
      * @see #TERTIARY
-     * @see #QUATERNARY 
+     * @see #QUATERNARY
      * @see #IDENTICAL
      * @stable ICU 2.4
      */
      public abstract void setStrength(int strength);
-  
-  /**
-  * Sets the attribute to be used in comparison or transformation.
-  * <p>Example of use:
-  * <pre>
-  * . Collator myCollation = Collator.createInstance(Locale::US);
-  * . myCollation.setAttribute(CollationAttribute.CASE_LEVEL, 
-  * .                          CollationAttribute.VALUE_ON);
-  * . int result = myCollation->compare("\\u30C3\\u30CF", 
-  * .                                   "\\u30C4\\u30CF");
-  * . // result will be Collator.RESULT_LESS.
-  * </pre>
-  * @param type the attribute to be set from CollationAttribute
-  * @param value attribute value from CollationAttribute
-  * @stable ICU 2.4
-  */
-  public abstract void setAttribute(int type, int value);
-  
-  /**
-  * Get the sort key as an CollationKey object from the argument string.
-  * To retrieve sort key in terms of byte arrays, use the method as below<br>
-  * <code>
-  * Collator collator = Collator.getInstance();
-  * CollationKey collationkey = collator.getCollationKey("string");
-  * byte[] array = collationkey.toByteArray();
-  * </code><br>
-  * Byte array result are zero-terminated and can be compared using 
-  * java.util.Arrays.equals();
-  * @param source string to be processed.
-  * @return the sort key
-  * @stable ICU 2.4
-  */
-  public abstract CollationKey getCollationKey(String source);
-  
-  /**
-  * Returns a hash of this collation object
-  * @return hash of this collation object
-  * @stable ICU 2.4
-  */
-  public abstract int hashCode();
-  
-  // BEGIN android-added
-  public static Locale[] getAvailableLocales() {
-      
-      String[] locales = NativeCollation.getAvailableLocalesImpl();
-      
-      Locale[] result = new Locale[locales.length];
-      
-      String locale;
-      
-      int index, index2;
-      
-      for(int i = 0; i < locales.length; i++) {
-          locale = locales[i];
 
-          index = locale.indexOf('_');
-          index2 = locale.lastIndexOf('_');
+    /**
+     * Sets the attribute to be used in comparison or transformation.
+     * <p>Example of use:
+     * <pre>
+     * . Collator myCollation = Collator.createInstance(Locale::US);
+     * . myCollation.setAttribute(CollationAttribute.CASE_LEVEL,
+     * .                          CollationAttribute.VALUE_ON);
+     * . int result = myCollation->compare("\\u30C3\\u30CF",
+     * .                                   "\\u30C4\\u30CF");
+     * . // result will be -1.
+     * </pre>
+     * @param type the attribute to be set from CollationAttribute
+     * @param value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public abstract void setAttribute(int type, int value);
 
-          if(index == -1) {
-              result[i] = new Locale(locales[i]);
-          } else if(index == 2 && index == index2) {
-              result[i] = new Locale(
-                      locale.substring(0,2),
-                      locale.substring(3,5));
-          } else if(index == 2 && index2 > index) {
-              result[i] = new Locale(
-                      locale.substring(0,index),
-                      locale.substring(index + 1,index2),
-                      locale.substring(index2 + 1));
-          }
-      }
-      
-      return result;
-  }
-  // END android-added
+    /**
+     * Get the sort key as an CollationKey object from the argument string.
+     * To retrieve sort key in terms of byte arrays, use the method as below<br>
+     * <code>
+     * Collator collator = Collator.getInstance();
+     * CollationKey collationKey = collator.getCollationKey("string");
+     * byte[] array = collationKey.toByteArray();
+     * </code><br>
+     * Byte array result are zero-terminated and can be compared using
+     * java.util.Arrays.equals();
+     * @param source string to be processed.
+     * @return the sort key
+     * @stable ICU 2.4
+     */
+    public abstract CollationKey getCollationKey(String source);
+
+    /**
+     * Returns a hash of this collation object
+     * @return hash of this collation object
+     * @stable ICU 2.4
+     */
+    public abstract int hashCode();
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java
index e318e47..272d525 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeBreakIterator.java
@@ -16,39 +16,143 @@
 
 package com.ibm.icu4jni.text;
 
-final class NativeBreakIterator {
-    private NativeBreakIterator() {
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+
+public final class NativeBreakIterator implements Cloneable {
+    // Acceptable values for the 'type' field.
+    private static final int BI_CHAR_INSTANCE = 1;
+    private static final int BI_WORD_INSTANCE = 2;
+    private static final int BI_LINE_INSTANCE = 3;
+    private static final int BI_SENT_INSTANCE = 4;
+
+    private final int addr;
+    private final int type;
+    private CharacterIterator charIter;
+
+    private NativeBreakIterator(int iterAddr, int type) {
+        this.addr = iterAddr;
+        this.type = type;
+        this.charIter = new StringCharacterIterator("");
     }
 
-    static native String[] getAvailableLocalesImpl();
+    @Override
+    public Object clone() {
+        int cloneAddr = cloneImpl(this.addr);
+        NativeBreakIterator clone = new NativeBreakIterator(cloneAddr, this.type);
+        // The RI doesn't clone the CharacterIterator.
+        clone.charIter = this.charIter;
+        return clone;
+    }
 
-    static native int getCharacterInstanceImpl(String locale);
-    
-    static native int getWordInstanceImpl(String locale);
-    
-    static native int getLineInstanceImpl(String locale);
-    
-    static native int getSentenceInstanceImpl(String locale);
+    @Override
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (!(object instanceof NativeBreakIterator)) {
+            return false;
+        }
+        // TODO: is this sufficient? shouldn't we be checking the underlying rules?
+        NativeBreakIterator rhs = (NativeBreakIterator) object;
+        return type == rhs.type && charIter.equals(rhs.charIter);
+    }
 
-    static native void closeBreakIteratorImpl(int biaddress);
-    
-    static native void setTextImpl(int biaddress, String text);
-    
-    static native int cloneImpl(int biaddress);
-    
-    static native int precedingImpl(int biaddress, int offset);
+    @Override
+    public int hashCode() {
+        return 42; // No-one uses BreakIterator as a hash key.
+    }
 
-    static native boolean isBoundaryImpl(int biaddress, int offset);
+    @Override
+    protected void finalize() {
+        closeBreakIteratorImpl(this.addr);
+    }
 
-    static native int nextImpl(int biaddress, int n);
+    public int current() {
+        return currentImpl(this.addr);
+    }
 
-    static native int previousImpl(int biaddress);
+    public int first() {
+        return firstImpl(this.addr);
+    }
 
-    static native int currentImpl(int biaddress);
+    public int following(int offset) {
+        return followingImpl(this.addr, offset);
+    }
 
-    static native int firstImpl(int biaddress);
+    public CharacterIterator getText() {
+        int newLoc = currentImpl(this.addr);
+        this.charIter.setIndex(newLoc);
+        return this.charIter;
+    }
 
-    static native int followingImpl(int biaddress, int offset);
+    public int last() {
+        return lastImpl(this.addr);
+    }
 
-    static native int lastImpl(int biaddress);
+    public int next(int n) {
+        return nextImpl(this.addr, n);
+    }
+
+    public int next() {
+        return nextImpl(this.addr, 1);
+    }
+
+    public int previous() {
+        return previousImpl(this.addr);
+    }
+
+    public void setText(CharacterIterator newText) {
+        this.charIter = newText;
+        StringBuilder sb = new StringBuilder();
+        for (char c = newText.first(); c != CharacterIterator.DONE; c = newText.next()) {
+            sb.append(c);
+        }
+        setTextImpl(this.addr, sb.toString());
+    }
+
+    public void setText(String newText) {
+        setText(new StringCharacterIterator(newText));
+    }
+
+    public boolean isBoundary(int offset) {
+        return isBoundaryImpl(this.addr, offset);
+    }
+
+    public int preceding(int offset) {
+        return precedingImpl(this.addr, offset);
+    }
+
+    public static NativeBreakIterator getCharacterInstance(Locale where) {
+        return new NativeBreakIterator(getCharacterInstanceImpl(where.toString()), BI_CHAR_INSTANCE);
+    }
+
+    public static NativeBreakIterator getLineInstance(Locale where) {
+        return new NativeBreakIterator(getLineInstanceImpl(where.toString()), BI_LINE_INSTANCE);
+    }
+
+    public static NativeBreakIterator getSentenceInstance(Locale where) {
+        return new NativeBreakIterator(getSentenceInstanceImpl(where.toString()), BI_SENT_INSTANCE);
+    }
+
+    public static NativeBreakIterator getWordInstance(Locale where) {
+        return new NativeBreakIterator(getWordInstanceImpl(where.toString()), BI_WORD_INSTANCE);
+    }
+
+    private static native int getCharacterInstanceImpl(String locale);
+    private static native int getWordInstanceImpl(String locale);
+    private static native int getLineInstanceImpl(String locale);
+    private static native int getSentenceInstanceImpl(String locale);
+    private static native void closeBreakIteratorImpl(int addr);
+    private static native void setTextImpl(int addr, String text);
+    private static native int cloneImpl(int addr);
+    private static native int precedingImpl(int addr, int offset);
+    private static native boolean isBoundaryImpl(int addr, int offset);
+    private static native int nextImpl(int addr, int n);
+    private static native int previousImpl(int addr);
+    private static native int currentImpl(int addr);
+    private static native int firstImpl(int addr);
+    private static native int followingImpl(int addr, int offset);
+    private static native int lastImpl(int addr);
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java
index 7d474ef..fbdcf93 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeCollation.java
@@ -244,6 +244,4 @@
   * @internal ICU 2.4
   */
   static native void setOffset(int address, int offset);
-
-  static native String[] getAvailableLocalesImpl();
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
index d1da72f..6f751d5 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java
@@ -20,6 +20,7 @@
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedString;
 import java.text.DecimalFormatSymbols;
@@ -30,7 +31,7 @@
 import java.util.Currency;
 import java.util.Locale;
 
-public class NativeDecimalFormat {
+public final class NativeDecimalFormat {
     /**
      * Constants corresponding to the native type UNumberFormatSymbol, for setSymbol.
      */
@@ -570,6 +571,21 @@
         }
     }
 
+    public void setRoundingMode(RoundingMode roundingMode, double roundingIncrement) {
+        final int nativeRoundingMode;
+        switch (roundingMode) {
+        case CEILING: nativeRoundingMode = 0; break;
+        case FLOOR: nativeRoundingMode = 1; break;
+        case DOWN: nativeRoundingMode = 2; break;
+        case UP: nativeRoundingMode = 3; break;
+        case HALF_EVEN: nativeRoundingMode = 4; break;
+        case HALF_DOWN: nativeRoundingMode = 5; break;
+        case HALF_UP: nativeRoundingMode = 6; break;
+        default: throw new AssertionError();
+        }
+        setRoundingMode(addr, nativeRoundingMode, roundingIncrement);
+    }
+
     private static native void applyPatternImpl(int addr, boolean localized, String pattern);
     private static native int cloneDecimalFormatImpl(int addr);
     private static native void closeDecimalFormatImpl(int addr);
@@ -589,6 +605,7 @@
             String nan, char patternSeparator, char percent, char perMill, char zeroDigit);
     private static native void setSymbol(int addr, int symbol, String str);
     private static native void setAttribute(int addr, int symbol, int i);
+    private static native void setRoundingMode(int addr, int roundingMode, double roundingIncrement);
     private static native void setTextAttribute(int addr, int symbol, String str);
     private static native String toPatternImpl(int addr, boolean localized);
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeIDN.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeIDN.java
new file mode 100644
index 0000000..b973131
--- /dev/null
+++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeIDN.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.icu4jni.text;
+
+public class NativeIDN {
+    public static String toASCII(String s, int flags) {
+        return convert(s, flags, true);
+    }
+
+    public static String toUnicode(String s, int flags) {
+        try {
+            return convert(s, flags, false);
+        } catch (IllegalArgumentException ex) {
+            // The RI documentation explicitly states that this method can't fail.
+            // ICU4C disagrees, as does the RI in practice.
+            // The RI just returns the input string if it can't
+            return s;
+        }
+    }
+
+    private static String convert(String s, int flags, boolean toAscii) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        return convertImpl(s, flags, toAscii);
+    }
+    private static native String convertImpl(String s, int flags, boolean toAscii);
+
+    private NativeIDN() {}
+}
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedBreakIterator.java b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedBreakIterator.java
deleted file mode 100644
index 4d38f2b..0000000
--- a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedBreakIterator.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ibm.icu4jni.text;
-
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-
-public class RuleBasedBreakIterator extends BreakIterator {
-
-    private CharacterIterator charIter;
-    
-    private int addr;
-
-    RuleBasedBreakIterator(int iterAddr, int type) {
-        this.addr = iterAddr;
-        this.type = type;
-        this.charIter = new StringCharacterIterator("");
-    }
-    
-    @Override
-    public Object clone() {
-        int cloneAddr = NativeBreakIterator.cloneImpl(this.addr);
-        RuleBasedBreakIterator rbbi = 
-                new RuleBasedBreakIterator(cloneAddr, this.type);
-        
-        rbbi.charIter = this.charIter;
-        
-        return rbbi;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-        if(object == null) {
-            return false;
-        }
-        
-        if(!(object instanceof RuleBasedBreakIterator)) {
-            return false;
-        }
-        
-        CharacterIterator iter = ((RuleBasedBreakIterator) object).charIter;
-        
-        boolean result = this.type == ((RuleBasedBreakIterator) object).type;
-        
-        return result && iter.equals(this.charIter);
-    }
-    
-    @Override
-    public int current() {
-        return NativeBreakIterator.currentImpl(this.addr);
-    }
-
-    @Override
-    public int first() {
-        return NativeBreakIterator.firstImpl(this.addr);
-    }
-
-    @Override
-    public int following(int offset) {
-        return NativeBreakIterator.followingImpl(this.addr, offset);
-    }
-
-    @Override
-    public CharacterIterator getText() {
-        int newLoc = NativeBreakIterator.currentImpl(this.addr);
-        this.charIter.setIndex(newLoc);
-        return this.charIter;
-    }
-
-    @Override
-    public int last() {
-        return NativeBreakIterator.lastImpl(this.addr);
-    }
-    
-    @Override
-    public int next(int n) {
-        return NativeBreakIterator.nextImpl(this.addr, n);
-    }
-
-    @Override
-    public int next() {
-        return NativeBreakIterator.nextImpl(this.addr, 1);
-    }
-    
-    @Override
-    public int previous() {
-        return NativeBreakIterator.previousImpl(this.addr);
-    }
-
-    @Override
-    public void setText(CharacterIterator newText) {
-        this.charIter = newText;
-
-        StringBuilder sb = new StringBuilder();
-        
-        char c = newText.first();
-        while(c != CharacterIterator.DONE) {
-            sb.append(c);
-            c = newText.next();
-        }
-
-        NativeBreakIterator.setTextImpl(this.addr, sb.toString());
-    }
-
-    protected void finalize() {
-        NativeBreakIterator.closeBreakIteratorImpl(this.addr);
-    }
-
-    @Override
-    public boolean isBoundary(int offset) {
-        return NativeBreakIterator.isBoundaryImpl(this.addr, offset);
-    }
-
-    @Override
-    public int preceding(int offset) {
-        return NativeBreakIterator.precedingImpl(this.addr, offset);
-    }
-
-}
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
index c0aca3b..3135daa 100644
--- a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
+++ b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedCollator.java
@@ -13,7 +13,6 @@
 import java.util.Locale;
 import java.text.CharacterIterator;
 import java.text.ParseException;
-import com.ibm.icu4jni.common.ErrorCode;
 
 /**
 * Concrete implementation class for Collation.
@@ -26,28 +25,28 @@
 *    < reset > < text-argument >
 * </pre>
 * <p>
-* <code>RuleBasedCollator</code> has the following restrictions for efficiency 
+* <code>RuleBasedCollator</code> has the following restrictions for efficiency
 * (other subclasses may be used for more complex languages) :
 * <ol>
-* <li> If a French secondary ordering is specified it applies to the whole 
+* <li> If a French secondary ordering is specified it applies to the whole
 *      collator object.
-* <li> All non-mentioned Unicode characters are at the end of the collation 
+* <li> All non-mentioned Unicode characters are at the end of the collation
 *      order.
-* <li> If a character is not located in the RuleBasedCollator, the default 
-*      Unicode Collation Algorithm (UCA) rulebased table is automatically 
+* <li> If a character is not located in the RuleBasedCollator, the default
+*      Unicode Collation Algorithm (UCA) rule-based table is automatically
 *      searched as a backup.
 * </ol>
 *
 * The following demonstrates how to create your own collation rules:
 * <UL Type=disc>
 *    <LI><strong>Text-Argument</strong>: A text-argument is any sequence of
-*        characters, excluding special characters (that is, common whitespace 
-*        characters [0009-000D, 0020] and rule syntax characters [0021-002F, 
-*        003A-0040, 005B-0060, 007B-007E]). If those characters are desired, 
-*        you can put them in single quotes (e.g. ampersand => '&'). Note that 
-*        unquoted white space characters are ignored; e.g. <code>b c</code> is 
+*        characters, excluding special characters (that is, common whitespace
+*        characters [0009-000D, 0020] and rule syntax characters [0021-002F,
+*        003A-0040, 005B-0060, 007B-007E]). If those characters are desired,
+*        you can put them in single quotes (e.g. ampersand => '&'). Note that
+*        unquoted white space characters are ignored; e.g. <code>b c</code> is
 *        treated as <code>bc</code>.
-*    <LI><strong>Modifier</strong>: There is a single modifier which is used 
+*    <LI><strong>Modifier</strong>: There is a single modifier which is used
 *        to specify that all accents (secondary differences) are backwards.
 *        <p>'@' : Indicates that accents are sorted backwards, as in French.
 *    <LI><strong>Relation</strong>: The relations are the following:
@@ -57,8 +56,8 @@
 *            <LI>',' : Greater, as a case difference (tertiary)
 *            <LI>'=' : Equal
 *        </UL>
-*    <LI><strong>Reset</strong>: There is a single reset which is used 
-*        primarily for contractions and expansions, but which can also be used 
+*    <LI><strong>Reset</strong>: There is a single reset which is used
+*        primarily for contractions and expansions, but which can also be used
 *        to add a modification at the end of a set of rules.
 *        <p>'&' : Indicates that the next rule follows the position to where
 *            the reset text-argument would be sorted.
@@ -89,9 +88,9 @@
 * instead, "e" is sorted as if it were expanded to two characters: "a"
 * followed by an "e". This difference appears in natural languages: in
 * traditional Spanish "ch" is treated as though it contracts to a single
-* character (expressed as "c < ch < d"), while in traditional German a-umlaut 
-* is treated as though it expanded to two characters (expressed as "a,A < b,B 
-* ... & ae;? & AE;?"). [? and ? are, of course, the escape sequences for 
+* character (expressed as "c < ch < d"), while in traditional German a-umlaut
+* is treated as though it expanded to two characters (expressed as "a,A < b,B
+* ... & ae;? & AE;?"). [? and ? are, of course, the escape sequences for
 * a-umlaut.]
 * <p>
 * <strong>Ignorable Characters</strong>
@@ -107,16 +106,16 @@
 * <p><strong>Normalization and Accents</strong>
 * <p>
 * <code>RuleBasedCollator</code> automatically processes its rule table to
-* include both pre-composed and combining-character versions of accented 
-* characters. Even if the provided rule string contains only base characters 
-* and separate combining accent characters, the pre-composed accented 
-* characters matching all canonical combinations of characters from the rule 
+* include both pre-composed and combining-character versions of accented
+* characters. Even if the provided rule string contains only base characters
+* and separate combining accent characters, the pre-composed accented
+* characters matching all canonical combinations of characters from the rule
 * string will be entered in the table.
 * <p>
-* This allows you to use a RuleBasedCollator to compare accented strings even 
-* when the collator is set to NO_DECOMPOSITION. However, if the strings to be 
-* collated contain combining sequences that may not be in canonical order, you 
-* should set the collator to CANONICAL_DECOMPOSITION to enable sorting of 
+* This allows you to use a RuleBasedCollator to compare accented strings even
+* when the collator is set to NO_DECOMPOSITION. However, if the strings to be
+* collated contain combining sequences that may not be in canonical order, you
+* should set the collator to CANONICAL_DECOMPOSITION to enable sorting of
 * combining sequences.
 * For more information, see
 * <A HREF="http://www.aw.com/devpress">The Unicode Standard, Version 3.0</A>.)
@@ -130,7 +129,7 @@
 *     <LI>A relation or reset character not followed by a text-argument
 *        (e.g. "a < , b").
 *     <LI>A reset where the text-argument (or an initial substring of the
-*         text-argument) is not already in the sequence or allocated in the 
+*         text-argument) is not already in the sequence or allocated in the
 *         default UCA table.
 *         (e.g. "a < b & e < f")
 * </UL>
@@ -148,7 +147,7 @@
 * <p>
 * Normally, to create a rule-based Collator object, you will use
 * <code>Collator</code>'s factory method <code>getInstance</code>.
-* However, to create a rule-based Collator object with specialized rules 
+* However, to create a rule-based Collator object with specialized rules
 * tailored to your needs, you construct the <code>RuleBasedCollator</code>
 * with the rules contained in a <code>String</code> object. For example:
 * <blockquote>
@@ -230,7 +229,7 @@
 * <blockquote>
 * <pre>
 * // get en_US Collator rules
-* RuleBasedCollator en_USCollator = 
+* RuleBasedCollator en_USCollator =
 *                      (RuleBasedCollator)Collator.getInstance(Locale.US);
 * // add a few Japanese character to sort before English characters
 * // suppose the last character before the first base letter 'a' in
@@ -242,478 +241,374 @@
 * </blockquote>
 * <P>
 * @author syn wee quek
-* @stable ICU 2.4 
+* @stable ICU 2.4
 */
-    
-public final class RuleBasedCollator extends Collator 
-{
-  // public constructors ------------------------------------------
-  
-  /**
-  * RuleBasedCollator constructor. This takes the table rules and builds a 
-  * collation table out of them. Please see RuleBasedCollator class
-  * description for more details on the collation rule syntax.
-  * @param rules the collation rules to build the collation table from.
-  * @exception ParseException thrown if rules are empty or a Runtime error
-  *            if collator can not be created.
-  * @stable ICU 2.4 
-  */
-  public RuleBasedCollator(String rules) throws ParseException
-  {
-    // BEGIN android-changed
-    if (rules == null) {
-      throw new NullPointerException();
-    }
-    // if (rules.length() == 0)
-    //   throw new ParseException("Build rules empty.", 0);
-    // END android-changed
-    m_collator_ = NativeCollation.openCollatorFromRules(rules,
-                              CollationAttribute.VALUE_OFF,
-                              CollationAttribute.VALUE_DEFAULT_STRENGTH);
-  }
+public final class RuleBasedCollator extends Collator {
+    private int m_collator_;
+    private int m_hashcode_ = 0;
 
-  /**
-  * RuleBasedCollator constructor. This takes the table rules and builds a 
-  * collation table out of them. Please see RuleBasedCollator class
-  * description for more details on the collation rule syntax.
-  * @param rules the collation rules to build the collation table from.
-  * @param strength collation strength
-  * @exception ParseException thrown if rules are empty or a Runtime error
-  *            if collator can not be created.
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @stable ICU 2.4
-  */
-  public RuleBasedCollator(String rules, int strength) throws ParseException
-  {
-    // BEGIN android-changed
-    if (rules == null) {
-      throw new NullPointerException();
+    /**
+     * RuleBasedCollator constructor. This takes the table rules and builds a
+     * collation table out of them. Please see RuleBasedCollator class
+     * description for more details on the collation rule syntax.
+     * @param rules the collation rules to build the collation table from.
+     * @exception ParseException thrown if rules are empty or a Runtime error
+     *            if collator can not be created.
+     * @stable ICU 2.4
+     */
+    public RuleBasedCollator(String rules) throws ParseException {
+        if (rules == null) {
+            throw new NullPointerException();
+        }
+        m_collator_ = NativeCollation.openCollatorFromRules(rules,
+                CollationAttribute.VALUE_OFF, CollationAttribute.VALUE_DEFAULT_STRENGTH);
     }
-    // if (rules.length() == 0)
-    //   throw new ParseException("Build rules empty.", 0);
-    // END android-changed
-    if (!CollationAttribute.checkStrength(strength))
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-      
-    m_collator_ = NativeCollation.openCollatorFromRules(rules,
-                                CollationAttribute.VALUE_OFF,
-                                strength);
-  }
 
-  /**
-  * RuleBasedCollator constructor. This takes the table rules and builds a 
-  * collation table out of them. Please see RuleBasedCollator class
-  * description for more details on the collation rule syntax.
-  * <p>Note API change starting from release 2.4. Prior to release 2.4, the 
-  * normalizationmode argument values are from the class 
-  * com.ibm.icu4jni.text.Normalization. In 2.4, 
-  * the valid normalizationmode arguments for this API are 
-  * CollationAttribute.VALUE_ON and CollationAttribute.VALUE_OFF.
-  * </p>
-  * @param rules the collation rules to build the collation table from.
-  * @param strength collation strength
-  * @param normalizationmode normalization mode
-  * @exception IllegalArgumentException thrown when constructor error occurs
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @see #CANONICAL_DECOMPOSITION
-  * @see #NO_DECOMPOSITION
-  * @stable ICU 2.4
-  */
-  public RuleBasedCollator(String rules, int normalizationmode, int strength)
-  {
-    // BEGIN android-added
-    if (rules == null) {
-      throw new NullPointerException();
+    /**
+     * RuleBasedCollator constructor. This takes the table rules and builds a
+     * collation table out of them. Please see RuleBasedCollator class
+     * description for more details on the collation rule syntax.
+     * @param rules the collation rules to build the collation table from.
+     * @param strength collation strength
+     * @exception ParseException thrown if rules are empty or a Runtime error
+     *            if collator can not be created.
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @stable ICU 2.4
+     */
+    public RuleBasedCollator(String rules, int strength) throws ParseException {
+        if (rules == null) {
+            throw new NullPointerException();
+        }
+        m_collator_ = NativeCollation.openCollatorFromRules(rules, CollationAttribute.VALUE_OFF, strength);
     }
-    // END android-added
-    if (!CollationAttribute.checkStrength(strength) || 
-        !CollationAttribute.checkNormalization(normalizationmode)) {
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    }
-      
-    m_collator_ = NativeCollation.openCollatorFromRules(rules,
-                                          normalizationmode, strength);
-  }
-  
-  // public methods -----------------------------------------------
-  
-  /**
-  * Makes a complete copy of the current object.
-  * @return a copy of this object if data clone is a success, otherwise null
-  * @stable ICU 2.4 
-  */
-  public Object clone() 
-  {
-    RuleBasedCollator result = null;
-    int collatoraddress = NativeCollation.safeClone(m_collator_);
-    result = new RuleBasedCollator(collatoraddress);
-    return (Collator)result;
-  }
-                              
-  /**
-  * The comparison function compares the character data stored in two
-  * different strings. Returns information about whether a string is less 
-  * than, greater than or equal to another string.
-  * <p>Example of use:
-  * <br>
-  * <code>
-  *   Collator myCollation = Collator.createInstance(Locale::US);
-  *   myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
-  *   // result would be Collator.RESULT_EQUAL ("abc" == "ABC")
-  *   // (no primary difference between "abc" and "ABC")
-  *   int result = myCollation.compare("abc", "ABC",3);
-  *   myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
-  *   // result would be Collation::LESS (abc" &lt;&lt;&lt; "ABC")
-  *   // (with tertiary difference between "abc" and "ABC")
-  *   int result = myCollation.compare("abc", "ABC",3);
-  * </code>
-  * @param source The source string.
-  * @param target The target string.
-  * @return result of the comparison, Collator.RESULT_EQUAL, 
-  *         Collator.RESULT_GREATER or Collator.RESULT_LESS
-  * @stable ICU 2.4 
-  */
-  public int compare(String source, String target)
-  {
-    return NativeCollation.compare(m_collator_, source, target);
-  }
-                                               
-  /**
-  * Get the normalization mode for this object.
-  * The normalization mode influences how strings are compared.
-  * @see #CANONICAL_DECOMPOSITION
-  * @see #NO_DECOMPOSITION
-  * @stable ICU 2.4
-  */
-  public int getDecomposition()
-  {
-    return NativeCollation.getNormalization(m_collator_);
-  }
 
-  /**
-  * <p>Sets the decomposition mode of the Collator object on or off.
-  * If the decomposition mode is set to on, string would be decomposed into
-  * NFD format where necessary before sorting.</p>
-  * </p>
-  * @param decompositionmode the new decomposition mode
-  * @see #CANONICAL_DECOMPOSITION
-  * @see #NO_DECOMPOSITION
-  * @stable ICU 2.4
-  */
-  public void setDecomposition(int decompositionmode)
-  {
-    if (!CollationAttribute.checkNormalization(decompositionmode)) 
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    NativeCollation.setAttribute(m_collator_, 
-                                 CollationAttribute.NORMALIZATION_MODE,
-                                 decompositionmode);
-  }
+    /**
+     * RuleBasedCollator constructor. This takes the table rules and builds a
+     * collation table out of them. Please see RuleBasedCollator class
+     * description for more details on the collation rule syntax.
+     * <p>Note API change starting from release 2.4. Prior to release 2.4, the
+     * normalizationMode argument values are from the class
+     * com.ibm.icu4jni.text.Normalization. In 2.4,
+     * the valid normalizationMode arguments for this API are
+     * CollationAttribute.VALUE_ON and CollationAttribute.VALUE_OFF.
+     * </p>
+     * @param rules the collation rules to build the collation table from.
+     * @param strength collation strength
+     * @param normalizationMode normalization mode
+     * @exception IllegalArgumentException thrown when constructor error occurs
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @see #CANONICAL_DECOMPOSITION
+     * @see #NO_DECOMPOSITION
+     * @stable ICU 2.4
+     */
+    public RuleBasedCollator(String rules, int normalizationMode, int strength) {
+        if (rules == null) {
+            throw new NullPointerException();
+        }
+        m_collator_ = NativeCollation.openCollatorFromRules(rules, normalizationMode, strength);
+    }
 
-  /**
-  * Determines the minimum strength that will be use in comparison or
-  * transformation.
-  * <p>
-  * E.g. with strength == CollationAttribute.VALUE_SECONDARY, the tertiary difference 
-  * is ignored
-  * </p>
-  * <p>
-  * E.g. with strength == PRIMARY, the secondary and tertiary difference are 
-  * ignored.
-  * </p>
-  * @return the current comparison level.
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @stable ICU 2.4
-  */
-  public int getStrength()
-  {
-    return NativeCollation.getAttribute(m_collator_, 
-                                        CollationAttribute.STRENGTH);
-  }
-  
-  /**
-  * Sets the minimum strength to be used in comparison or transformation.
-  * <p>Example of use:
-  * <br>
-  * <code>
-  * Collator myCollation = Collator.createInstance(Locale::US);
-  * myCollation.setStrength(PRIMARY);
-  * // result will be "abc" == "ABC"
-  * // tertiary differences will be ignored
-  * int result = myCollation->compare("abc", "ABC");
-  * </code>
-  * @param strength the new comparison level.
-  * @exception IllegalArgumentException when argument does not belong to any collation strength 
-  *            mode or error occurs while setting data.
-  * @see #PRIMARY
-  * @see #SECONDARY
-  * @see #TERTIARY
-  * @see #QUATERNARY
-  * @see #IDENTICAL
-  * @stable ICU 2.4
-  */
-  public void setStrength(int strength)
-  {
-    if (!CollationAttribute.checkStrength(strength)) 
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    NativeCollation.setAttribute(m_collator_, CollationAttribute.STRENGTH, 
-                                 strength);
-  }
-  
-  /**
-  * Sets the attribute to be used in comparison or transformation.
-  * <p>Example of use:
-  * <br>
-  * <code>
-  *  Collator myCollation = Collator.createInstance(Locale::US);
-  *  myCollation.setAttribute(CollationAttribute.CASE_LEVEL, 
-  *                           CollationAttribute.VALUE_ON);
-  *  int result = myCollation->compare("\\u30C3\\u30CF", 
-  *                                    "\\u30C4\\u30CF");
-  * // result will be Collator.RESULT_LESS.
-  * </code>
-  * @param type the attribute to be set from CollationAttribute
-  * @param value attribute value from CollationAttribute
-  * @stable ICU 2.4
-  */
-  public void setAttribute(int type, int value)
-  {
-    if (!CollationAttribute.checkAttribute(type, value))
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    NativeCollation.setAttribute(m_collator_, type, value);
-  }
-  
-  /**
-  * Gets the attribute to be used in comparison or transformation.
-  * @param type the attribute to be set from CollationAttribute
-  * @return value attribute value from CollationAttribute
-  * @stable ICU 2.4 
-  */
-  public int getAttribute(int type)
-  {
-    if (!CollationAttribute.checkType(type))
-      throw ErrorCode.getException(ErrorCode.U_ILLEGAL_ARGUMENT_ERROR);
-    return NativeCollation.getAttribute(m_collator_, type);
-  }
-  
-  /**
-  * Get the sort key as an CollationKey object from the argument string.
-  * To retrieve sort key in terms of byte arrays, use the method as below<br>
-  * <br>
-  * <code>
-  * Collator collator = Collator.getInstance();
-  * byte[] array = collator.getSortKey(source);
-  * </code><br>
-  * Byte array result are zero-terminated and can be compared using 
-  * java.util.Arrays.equals();
-  * @param source string to be processed.
-  * @return the sort key
-  * @stable ICU 2.4 
-  */
-  public CollationKey getCollationKey(String source)
-  {
-    // BEGIN android-removed
-    // return new CollationKey(NativeCollation.getSortKey(m_collator_, source));
-    // END android-removed
-    // BEGIN android-added
-    if(source == null) {
-        return null;
+    /**
+     * Makes a complete copy of the current object.
+     * @return a copy of this object if data clone is a success, otherwise null
+     * @stable ICU 2.4
+     */
+    public Object clone() {
+        RuleBasedCollator result = null;
+        int collatoraddress = NativeCollation.safeClone(m_collator_);
+        result = new RuleBasedCollator(collatoraddress);
+        return (Collator)result;
     }
-    byte[] key = NativeCollation.getSortKey(m_collator_, source);
-    if(key == null) {
-      return null;
-    }
-    return new CollationKey(key);
-    // END android-added
-  }
-  
-  /**
-  * Get a sort key for the argument string
-  * Sort keys may be compared using java.util.Arrays.equals
-  * @param source string for key to be generated
-  * @return sort key
-  * @stable ICU 2.4 
-  */
-  public byte[] getSortKey(String source)
-  {
-    return NativeCollation.getSortKey(m_collator_, source);
-  }
-  
-  /**
-  * Get the collation rules of this Collation object
-  * The rules will follow the rule syntax.
-  * @return collation rules.
-  * @stable ICU 2.4 
-  */
-  public String getRules()
-  {
-    return NativeCollation.getRules(m_collator_);
-  }
-  
-  /** 
-  * Create a CollationElementIterator object that will iterator over the 
-  * elements in a string, using the collation rules defined in this 
-  * RuleBasedCollator
-  * @param source string to iterate over
-  * @return address of C collationelement
-  * @exception IllegalArgumentException thrown when error occurs
-  * @stable ICU 2.4 
-  */
-  public CollationElementIterator getCollationElementIterator(String source)
-  {
-    CollationElementIterator result = new CollationElementIterator(
-         NativeCollation.getCollationElementIterator(m_collator_, source));
-    // result.setOwnCollationElementIterator(true);
-    return result;
-  }
-  
-  // BEGIN android-added
-  /** 
-  * Create a CollationElementIterator object that will iterator over the 
-  * elements in a string, using the collation rules defined in this 
-  * RuleBasedCollator
-  * @param source string to iterate over
-  * @return address of C collationelement
-  * @exception IllegalArgumentException thrown when error occurs
-  * @stable ICU 2.4 
-  */
-  public CollationElementIterator getCollationElementIterator(
-          CharacterIterator source)
-  {
-    CollationElementIterator result = new CollationElementIterator(
-         NativeCollation.getCollationElementIterator(m_collator_, 
-                 source.toString()));
-    // result.setOwnCollationElementIterator(true);
-    return result;
-  }
-  // END android-added
-  
-  /**
-  * Returns a hash of this collation object
-  * Note this method is not complete, it only returns 0 at the moment.
-  * @return hash of this collation object
-  * @stable ICU 2.4 
-  */
-  public int hashCode()
-  {
-    // since rules do not change once it is created, we can cache the hash
-    if (m_hashcode_ == 0) {
-      m_hashcode_ = NativeCollation.hashCode(m_collator_);
-      if (m_hashcode_ == 0)
-        m_hashcode_ = 1;
-    }
-    return m_hashcode_;
-  }
-  
-  /**
-  * Checks if argument object is equals to this object.
-  * @param target object
-  * @return true if source is equivalent to target, false otherwise 
-  * @stable ICU 2.4 
-  */
-  public boolean equals(Object target)
-  {
-    if (this == target) 
-      return true;
-    if (target == null) 
-      return false;
-    if (getClass() != target.getClass()) 
-      return false;
-    
-    RuleBasedCollator tgtcoll = (RuleBasedCollator)target;
-    return getRules().equals(tgtcoll.getRules()) && 
-           getStrength() == tgtcoll.getStrength() && 
-           getDecomposition() == tgtcoll.getDecomposition();
-  }
-  
-  // package constructor ----------------------------------------
-  
-  /**
-  * RuleBasedCollator default constructor. This constructor takes the default 
-  * locale. The only caller of this class should be Collator.getInstance(). 
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  */
-  RuleBasedCollator()
-  {
-    m_collator_ = NativeCollation.openCollator();
-  }
 
-  /**
-  * RuleBasedCollator constructor. This constructor takes a locale. The 
-  * only caller of this class should be Collator.createInstance(). 
-  * Current implementation createInstance() returns a RuleBasedCollator(Locale) 
-  * instance. The RuleBasedCollator will be created in the following order,
-  * <ul>
-  * <li> Data from argument locale resource bundle if found, otherwise
-  * <li> Data from parent locale resource bundle of arguemtn locale if found,
-  *      otherwise
-  * <li> Data from built-in default collation rules if found, other
-  * <li> null is returned
-  * </ul>
-  * @param locale locale used
-  */
-  RuleBasedCollator(Locale locale)
-  {
-    if (locale == null) {
-      m_collator_ = NativeCollation.openCollator();
+    /**
+     * The comparison function compares the character data stored in two
+     * different strings. Returns information about whether a string is less
+     * than, greater than or equal to another string.
+     * <p>Example of use:
+     * <br>
+     * <code>
+     *   Collator myCollation = Collator.createInstance(Locale::US);
+     *   myCollation.setStrength(CollationAttribute.VALUE_PRIMARY);
+     *   // result would be 0 ("abc" == "ABC")
+     *   // (no primary difference between "abc" and "ABC")
+     *   int result = myCollation.compare("abc", "ABC",3);
+     *   myCollation.setStrength(CollationAttribute.VALUE_TERTIARY);
+     *   // result would be -1 (abc" &lt;&lt;&lt; "ABC")
+     *   // (with tertiary difference between "abc" and "ABC")
+     *   int result = myCollation.compare("abc", "ABC",3);
+     * </code>
+     */
+    public int compare(String source, String target) {
+        return NativeCollation.compare(m_collator_, source, target);
     }
-    else {
-      m_collator_ = NativeCollation.openCollator(locale.toString());
+
+    /**
+     * Get the normalization mode for this object.
+     * The normalization mode influences how strings are compared.
+     * @see #CANONICAL_DECOMPOSITION
+     * @see #NO_DECOMPOSITION
+     * @stable ICU 2.4
+     */
+    public int getDecomposition() {
+        return NativeCollation.getNormalization(m_collator_);
     }
-  }
-  
-  // protected methods --------------------------------------------
-  
-  /**
-  * Garbage collection.
-  * Close C collator and reclaim memory.
-  */
-  protected void finalize()
-  {
-    NativeCollation.closeCollator(m_collator_);
-  }
-  
-  // private data members -----------------------------------------
-  
-  /**
-  * C collator
-  */
-  private int m_collator_;
-  
-  /**
-  * Hash code for rules
-  */
-  private int m_hashcode_ = 0;
-  
-  // private constructor -----------------------------------------
-  
-  /**
-  * Private use constructor.
-  * Does not create any instance of the C collator. Accepts argument as the
-  * C collator for new instance.
-  * @param collatoraddress address of C collator
-  */
-  private RuleBasedCollator(int collatoraddress)
-  {
-    m_collator_ = collatoraddress;
-  }
+
+    /**
+     * <p>Sets the decomposition mode of the Collator object on or off.
+     * If the decomposition mode is set to on, string would be decomposed into
+     * NFD format where necessary before sorting.</p>
+     * </p>
+     * @param decompositionmode the new decomposition mode
+     * @see #CANONICAL_DECOMPOSITION
+     * @see #NO_DECOMPOSITION
+     * @stable ICU 2.4
+     */
+    public void setDecomposition(int decompositionmode) {
+        NativeCollation.setAttribute(m_collator_,
+                CollationAttribute.NORMALIZATION_MODE, decompositionmode);
+    }
+
+    /**
+     * Determines the minimum strength that will be use in comparison or
+     * transformation.
+     * <p>
+     * E.g. with strength == CollationAttribute.VALUE_SECONDARY, the tertiary difference
+     * is ignored
+     * </p>
+     * <p>
+     * E.g. with strength == PRIMARY, the secondary and tertiary difference are
+     * ignored.
+     * </p>
+     * @return the current comparison level.
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @stable ICU 2.4
+     */
+    public int getStrength() {
+        return NativeCollation.getAttribute(m_collator_, CollationAttribute.STRENGTH);
+    }
+
+    /**
+     * Sets the minimum strength to be used in comparison or transformation.
+     * <p>Example of use:
+     * <br>
+     * <code>
+     * Collator myCollation = Collator.createInstance(Locale::US);
+     * myCollation.setStrength(PRIMARY);
+     * // result will be "abc" == "ABC"
+     * // tertiary differences will be ignored
+     * int result = myCollation->compare("abc", "ABC");
+     * </code>
+     * @param strength the new comparison level.
+     * @exception IllegalArgumentException when argument does not belong to any collation strength
+     *            mode or error occurs while setting data.
+     * @see #PRIMARY
+     * @see #SECONDARY
+     * @see #TERTIARY
+     * @see #QUATERNARY
+     * @see #IDENTICAL
+     * @stable ICU 2.4
+     */
+    public void setStrength(int strength) {
+        NativeCollation.setAttribute(m_collator_, CollationAttribute.STRENGTH, strength);
+    }
+
+    /**
+     * Sets the attribute to be used in comparison or transformation.
+     * <p>Example of use:
+     * <br>
+     * <code>
+     *  Collator myCollation = Collator.createInstance(Locale::US);
+     *  myCollation.setAttribute(CollationAttribute.CASE_LEVEL,
+     *                           CollationAttribute.VALUE_ON);
+     *  int result = myCollation->compare("\\u30C3\\u30CF",
+     *                                    "\\u30C4\\u30CF");
+     * // result will be -1
+     * </code>
+     * @param type the attribute to be set from CollationAttribute
+     * @param value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public void setAttribute(int type, int value) {
+        NativeCollation.setAttribute(m_collator_, type, value);
+    }
+
+    /**
+     * Gets the attribute to be used in comparison or transformation.
+     * @param type the attribute to be set from CollationAttribute
+     * @return value attribute value from CollationAttribute
+     * @stable ICU 2.4
+     */
+    public int getAttribute(int type) {
+        return NativeCollation.getAttribute(m_collator_, type);
+    }
+
+    /**
+     * Get the sort key as an CollationKey object from the argument string.
+     * To retrieve sort key in terms of byte arrays, use the method as below<br>
+     * <br>
+     * <code>
+     * Collator collator = Collator.getInstance();
+     * byte[] array = collator.getSortKey(source);
+     * </code><br>
+     * Byte array result are zero-terminated and can be compared using
+     * java.util.Arrays.equals();
+     * @param source string to be processed.
+     * @return the sort key
+     * @stable ICU 2.4
+     */
+    public CollationKey getCollationKey(String source) {
+        if (source == null) {
+            return null;
+        }
+        byte[] key = NativeCollation.getSortKey(m_collator_, source);
+        if (key == null) {
+            return null;
+        }
+        return new CollationKey(source, key);
+    }
+
+    /**
+     * Get a sort key for the argument string
+     * Sort keys may be compared using java.util.Arrays.equals
+     * @param source string for key to be generated
+     * @return sort key
+     * @stable ICU 2.4
+     */
+    public byte[] getSortKey(String source) {
+        return NativeCollation.getSortKey(m_collator_, source);
+    }
+
+    /**
+     * Get the collation rules of this Collation object
+     * The rules will follow the rule syntax.
+     * @return collation rules.
+     * @stable ICU 2.4
+     */
+    public String getRules() {
+        return NativeCollation.getRules(m_collator_);
+    }
+
+    /**
+     * Create a CollationElementIterator object that will iterator over the
+     * elements in a string, using the collation rules defined in this
+     * RuleBasedCollator
+     * @param source string to iterate over
+     * @return address of C collationelement
+     * @exception IllegalArgumentException thrown when error occurs
+     * @stable ICU 2.4
+     */
+    public CollationElementIterator getCollationElementIterator(String source) {
+        CollationElementIterator result = new CollationElementIterator(
+                NativeCollation.getCollationElementIterator(m_collator_, source));
+        // result.setOwnCollationElementIterator(true);
+        return result;
+    }
+
+    public CollationElementIterator getCollationElementIterator(CharacterIterator it) {
+        // We only implement the String-based API, so build a string from the iterator.
+        return getCollationElementIterator(characterIteratorToString(it));
+    }
+
+    private String characterIteratorToString(CharacterIterator it) {
+        StringBuilder result = new StringBuilder();
+        for (char ch = it.current(); ch != CharacterIterator.DONE; ch = it.next()) {
+            result.append(ch);
+        }
+        return result.toString();
+    }
+
+    /**
+     * Returns a hash of this collation object
+     * Note this method is not complete, it only returns 0 at the moment.
+     * @return hash of this collation object
+     * @stable ICU 2.4
+     */
+    public int hashCode() {
+        // since rules do not change once it is created, we can cache the hash
+        if (m_hashcode_ == 0) {
+            m_hashcode_ = NativeCollation.hashCode(m_collator_);
+            if (m_hashcode_ == 0) {
+                m_hashcode_ = 1;
+            }
+        }
+        return m_hashcode_;
+    }
+
+    /**
+     * Checks if argument object is equals to this object.
+     * @param target object
+     * @return true if source is equivalent to target, false otherwise
+     * @stable ICU 2.4
+     */
+    public boolean equals(Object object) {
+        if (object ==  this) {
+            return true;
+        }
+        if (!(object instanceof RuleBasedCollator)) {
+            return false;
+        }
+        RuleBasedCollator rhs = (RuleBasedCollator) object;
+        return getRules().equals(rhs.getRules()) &&
+                getStrength() == rhs.getStrength() &&
+                getDecomposition() == rhs.getDecomposition();
+    }
+
+    /**
+     * RuleBasedCollator default constructor. This constructor takes the default
+     * locale. The only caller of this class should be Collator.getInstance().
+     * Current implementation createInstance() returns a RuleBasedCollator(Locale)
+     * instance. The RuleBasedCollator will be created in the following order,
+     * <ul>
+     * <li> Data from argument locale resource bundle if found, otherwise
+     * <li> Data from parent locale resource bundle of arguemtn locale if found,
+     *      otherwise
+     * <li> Data from built-in default collation rules if found, other
+     * <li> null is returned
+     * </ul>
+     */
+    RuleBasedCollator() {
+        m_collator_ = NativeCollation.openCollator();
+    }
+
+    /**
+     * RuleBasedCollator constructor. This constructor takes a locale. The
+     * only caller of this class should be Collator.createInstance().
+     * Current implementation createInstance() returns a RuleBasedCollator(Locale)
+     * instance. The RuleBasedCollator will be created in the following order,
+     * <ul>
+     * <li> Data from argument locale resource bundle if found, otherwise
+     * <li> Data from parent locale resource bundle of arguemtn locale if found,
+     *      otherwise
+     * <li> Data from built-in default collation rules if found, other
+     * <li> null is returned
+     * </ul>
+     * @param locale locale used
+     */
+    RuleBasedCollator(Locale locale) {
+        if (locale == null) {
+            m_collator_ = NativeCollation.openCollator();
+        } else {
+            m_collator_ = NativeCollation.openCollator(locale.toString());
+        }
+    }
+
+    protected void finalize() {
+        NativeCollation.closeCollator(m_collator_);
+    }
+
+    private RuleBasedCollator(int collatoraddress) {
+        m_collator_ = collatoraddress;
+    }
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedNumberFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedNumberFormat.java
deleted file mode 100644
index 3c865d8..0000000
--- a/icu/src/main/java/com/ibm/icu4jni/text/RuleBasedNumberFormat.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ibm.icu4jni.text;
-
-import java.text.FieldPosition;
-import java.text.Format;
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-public class RuleBasedNumberFormat extends NumberFormat {
-
-    /**
-     * Enum of predefined RBNF types.
-     */
-    public enum RBNFType {
-        /**
-         * This creates a spellout instance of RBNF.
-         * It formats numbers into textual representation:
-         * 15 -> 'fifteen' or 15.15 -> 'fifteen point one five'
-         *  and it can parse words into numbers: 'twenty' -> 20
-         */
-        SPELLOUT(0),
-        /**
-         * This creates an ordinal instance of RBNF.
-         * It formats numbers into an ordinal text representation:
-         * 15 -> '15th' and by parsing it also works in the other direction.
-         */
-        ORDINAL(1),
-        /**
-         * This creates instance of RBNF that allows to format numbers into time
-         * values: 15 -> '15 sec.' and by parsing it also works in the other
-         * direction.
-         */
-        DURATION(2);
-        
-        int type;
-        
-        RBNFType(int t) {
-            type = t;
-        }
-        
-        int getType() {
-            return type;
-        }
-    }
-    
-    @Override
-    protected void finalize(){
-        close();
-    }
-    
-    private int addr = 0;
-
-    /**
-     * Open a new rule based number format of selected type for the 
-     * default location
-     * 
-     * @param type the type of rule based number format
-     */
-    public void open(RBNFType type) {
-        this.addr = openRBNFImpl(type.getType(),
-                Locale.getDefault().toString());
-    }
-
-    /**
-     * Open a new rule based number format of selected type for the 
-     * given location
-     * 
-     * @param type the type of rule based number format
-     * @param locale the locale to use for this rule based number format
-     */
-    public void open(RBNFType type, Locale locale) {
-        String loc = locale.toString();
-        if (loc == null) {
-            throw new NullPointerException();
-        }
-        this.addr = openRBNFImpl(type.getType(), loc);
-    }
-    
-    private static native int openRBNFImpl(int type, String loc);
-
-    /**
-     * Open a new rule based number format for the 
-     * default location. The rule passed to the method has to be of the form
-     * described in the ibm icu documentation for RuleBasedNumberFormat.
-     * 
-     * @param rule the rule for the rule based number format
-     */
-    public void open(String rule) {
-        if (rule == null) {
-            throw new NullPointerException();
-        }
-        this.addr = openRBNFImpl(rule, Locale.getDefault().toString());
-    }
-
-    /**
-     * Open a new rule based number format for the 
-     * given location. The rule passed to the method has to be of the form
-     * described in the ibm icu documentation for RuleBasedNumberFormat.
-     * 
-     * @param rule the rule for the rule based number format
-     * @param locale the locale to use for this rule based number format
-     */
-    public void open(String rule, Locale locale) {
-        String loc = locale.toString();
-        if (loc == null || rule == null) {
-            throw new NullPointerException();
-        }
-        this.addr = openRBNFImpl(rule, locale.toString());
-    }
-    
-    private static native int openRBNFImpl(String rule, String loc);
-    
-    /**
-     * close a RuleBasedNumberFormat
-     */
-    public void close() {
-        if(this.addr != 0) {
-            closeRBNFImpl(this.addr);
-            this.addr = 0;
-        }
-    }
-    
-    private static native void closeRBNFImpl(int addr); 
-    
-    @Override
-    public StringBuffer format(long value, StringBuffer buffer, FieldPosition field) {
-
-        if(buffer == null) {
-            throw new NullPointerException();
-        }
-        
-        String fieldType = null;
-        
-        if(field != null) {
-            fieldType = getFieldType(field.getFieldAttribute());
-        }
-        
-        String result = formatRBNFImpl(this.addr, value, field, 
-                fieldType, null);
-        
-        buffer.append(result.toCharArray(), 0, result.length());
-        
-        return buffer;
-    }
-    
-    private static native String formatRBNFImpl(int addr, long value, 
-            FieldPosition field, String fieldType, StringBuffer buffer);
-
-    @Override
-    public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) {
-
-        if(buffer == null) {
-            throw new NullPointerException();
-        }
-        
-        String fieldType = null;
-        
-        if(field != null) {
-            fieldType = getFieldType(field.getFieldAttribute());
-        }
-        
-        String result = formatRBNFImpl(this.addr, value, field, 
-                fieldType, null);
-        
-        buffer.append(result.toCharArray(), 0, result.length());
-        
-        return buffer;
-    }
-    
-    private static native String formatRBNFImpl(int addr, double value, 
-            FieldPosition field, String fieldType, StringBuffer buffer);
-
-    @Override
-    public Number parse(String string, ParsePosition position) {
-        if (string == null || position == null) {
-            throw new NullPointerException();
-        }
-        return parseRBNFImpl(this.addr, string, position, false);
-    }
-    
-    /**
-     * This method has the same functionality 
-     * as {@link #parse(String, ParsePosition)}
-     * But it uses lenient parsing. This means it also accepts strings that
-     * differ from the correct writing (e.g. case or umlaut differences).
-     * 
-     * @param string the string to parse
-     * @param position the ParsePosition, updated on return with the index 
-     *        following the parsed text, or on error the index is unchanged and 
-     *        the error index is set to the index where the error occurred
-     * @return the Number resulting from the parse, or null if there is an error
-     */
-    public Number parseLenient(String string, ParsePosition position) {
-        if (string == null || position == null) {
-            throw new NullPointerException();
-        }
-        return parseRBNFImpl(this.addr, string, position, true);
-    }
-    
-    static native Number parseRBNFImpl(int addr, String string, ParsePosition position, boolean lenient);
-    
-    
-    static private String getFieldType(Format.Field field) {
-        if(field == null) {
-            return null;
-        }
-        if(field.equals(NumberFormat.Field.SIGN)) {
-            return "sign";
-        }
-        if(field.equals(NumberFormat.Field.INTEGER)) {
-            return "integer";
-        }
-        if(field.equals(NumberFormat.Field.FRACTION)) {
-            return "fraction";
-        }
-        if(field.equals(NumberFormat.Field.EXPONENT)) {
-            return "exponent";
-        }
-        if(field.equals(NumberFormat.Field.EXPONENT_SIGN)) {
-            return "exponent_sign";
-        }
-        if(field.equals(NumberFormat.Field.EXPONENT_SYMBOL)) {
-            return "exponent_symbol";
-        }
-        if(field.equals(NumberFormat.Field.CURRENCY)) {
-            return "currency";
-        }
-        if(field.equals(NumberFormat.Field.GROUPING_SEPARATOR)) {
-            return "grouping_separator";
-        }
-        if(field.equals(NumberFormat.Field.DECIMAL_SEPARATOR)) {
-            return "decimal_separator";
-        }
-        if(field.equals(NumberFormat.Field.PERCENT)) {
-            return "percent";
-        }
-        if(field.equals(NumberFormat.Field.PERMILLE)) {
-            return "permille";
-        }
-        return null;
-    }
-}
diff --git a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java b/icu/src/main/java/com/ibm/icu4jni/util/ICU.java
similarity index 67%
rename from icu/src/main/java/com/ibm/icu4jni/util/Resources.java
rename to icu/src/main/java/com/ibm/icu4jni/util/ICU.java
index cbad9a5..b684068 100644
--- a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java
+++ b/icu/src/main/java/com/ibm/icu4jni/util/ICU.java
@@ -16,141 +16,71 @@
 
 package com.ibm.icu4jni.util;
 
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.ListResourceBundle;
 import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
 import java.util.TimeZone;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Logger;
 
 /**
  * Makes ICU data accessible to Java.
- *
- * TODO: move the LocaleData stuff into LocaleData and rename this class.
  */
-public class Resources {
-    // A cache for the locale-specific data.
-    private static final ConcurrentHashMap<String, LocaleData> localeDataCache =
-            new ConcurrentHashMap<String, LocaleData>();
-
+public final class ICU {
     /**
      * Cache for ISO language names.
      */
-    private static String[] isoLanguages = null;
+    private static String[] isoLanguages;
 
     /**
      * Cache for ISO country names.
      */
-    private static String[] isoCountries = null;
-
-    /**
-     * Available locales cache.
-     */
-    private static String[] availableLocales = null;
+    private static String[] isoCountries;
 
     /**
      * Available timezones cache.
      */
-    private static String[] availableTimezones = null;
-
-    /**
-     * Returns a shared LocaleData for the given locale.
-     */
-    public static LocaleData getLocaleData(Locale locale) {
-        if (locale == null) {
-            locale = Locale.getDefault();
-        }
-        String localeName = locale.toString();
-        LocaleData localeData = localeDataCache.get(localeName);
-        if (localeData != null) {
-            return localeData;
-        }
-        localeData = makeLocaleData(locale);
-        boolean absent = (localeDataCache.putIfAbsent(localeName, localeData) == null);
-        return absent ? localeData : localeDataCache.get(localeName);
-    }
-
-    private static LocaleData makeLocaleData(Locale locale) {
-        String language = locale.getLanguage();
-        String country = locale.getCountry();
-        String variant = locale.getVariant();
-        // Start with data from the parent (next-most-specific) locale...
-        LocaleData result = new LocaleData();
-        if (variant.length() > 0) {
-            result.overrideWithDataFrom(getLocaleData(new Locale(language, country, "")));
-        } else if (country.length() > 0) {
-            result.overrideWithDataFrom(getLocaleData(new Locale(language, "", "")));
-        } else if (language.length() > 0) {
-            result.overrideWithDataFrom(getLocaleData(new Locale("", "", "")));
-        }
-        // Override with data from this locale.
-        result.overrideWithDataFrom(initLocaleData(locale));
-        return result;
-    }
+    private static String[] availableTimezones;
 
     /**
      * Returns an array of ISO language names (two-letter codes), fetched either
      * from ICU's database or from our memory cache.
-     * 
+     *
      * @return The array.
      */
     public static String[] getISOLanguages() {
         if (isoLanguages == null) {
             isoLanguages = getISOLanguagesNative();
         }
-
         return isoLanguages.clone();
     }
 
     /**
      * Returns an array of ISO country names (two-letter codes), fetched either
      * from ICU's database or from our memory cache.
-     * 
+     *
      * @return The array.
      */
     public static String[] getISOCountries() {
         if (isoCountries == null) {
             isoCountries = getISOCountriesNative();
         }
-
         return isoCountries.clone();
     }
 
     /**
-     * Returns an array of names of locales that are available in the system,
-     * fetched either from ICU's database or from our memory cache.
-     * 
-     * @return The array.
-     */
-    public static String[] getAvailableLocales() {
-        if (availableLocales == null) {
-            availableLocales = getAvailableLocalesNative();
-        }
-
-        return availableLocales.clone();
-    }
-
-    /**
      * Returns an array of names of timezones that are available in the system,
      * fetched either from the TimeZone class or from our memory cache.
-     * 
+     *
      * @return The array.
      */
     public static String[] getKnownTimezones() {
-        // TODO Drop the Linux ZoneInfo stuff in favor of ICU.
         if (availableTimezones == null) {
             availableTimezones = TimeZone.getAvailableIDs();
         }
-
         return availableTimezones.clone();
     }
 
     /**
      * Returns the display name for the given time zone using the given locale.
-     * 
+     *
      * @param id The time zone ID, for example "Europe/Berlin"
      * @param daylight Indicates whether daylight savings is in use
      * @param style The style, 0 for long, 1 for short
@@ -244,8 +174,7 @@
             result[i][4] = arrayToFill[4][i];
         }
 
-        Logger.getLogger(Resources.class.getSimpleName()).info(
-                "Loaded time zone names for " + locale + " in "
+        Logger.global.info("Loaded time zone names for " + locale + " in "
                 + (System.currentTimeMillis() - start) + "ms.");
 
         return result;
@@ -253,7 +182,7 @@
 
     /**
      * Returns the display names for all given timezones using the given locale.
-     * 
+     *
      * @return An array of time zone strings. Each row represents one time zone.
      *         The first columns holds the ID of the time zone, for example
      *         "Europe/Berlin". The other columns then hold for each row the
@@ -266,14 +195,14 @@
         if (locale == null) {
             locale = defaultLocale;
         }
-        
+
         // If locale == default and the default locale hasn't changed since
         // DefaultTimeZones loaded, return the cached names.
         // TODO: We should force a reboot if the default locale changes.
         if (defaultLocale.equals(locale) && DefaultTimeZones.locale.equals(defaultLocale)) {
             return clone2dStringArray(DefaultTimeZones.names);
         }
-        
+
         return createTimeZoneNamesFor(locale);
     }
 
@@ -285,8 +214,84 @@
         return result;
     }
 
+    /**
+     * Returns the appropriate {@code Locale} given a {@code String} of the form returned
+     * by {@code toString}. This is very lenient, and doesn't care what's between the underscores:
+     * this method can parse strings that {@code Locale.toString} won't produce.
+     * Used to remove duplication.
+     */
+    public static Locale localeFromString(String localeName) {
+        int first = localeName.indexOf('_');
+        int second = localeName.indexOf('_', first + 1);
+        if (first == -1) {
+            // Language only ("ja").
+            return new Locale(localeName);
+        } else if (second == -1) {
+            // Language and country ("ja_JP").
+            return new Locale(localeName.substring(0, first), localeName.substring(first + 1));
+        } else {
+            // Language and country and variant ("ja_JP_TRADITIONAL").
+            return new Locale(localeName.substring(0, first), localeName.substring(first + 1, second), localeName.substring(second + 1));
+        }
+    }
+
+    public static Locale[] localesFromStrings(String[] localeNames) {
+        Locale[] result = new Locale[localeNames.length];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = localeFromString(localeNames[i]);
+        }
+        return result;
+    }
+
+    private static Locale[] availableLocalesCache;
+    public static Locale[] getAvailableLocales() {
+        if (availableLocalesCache == null) {
+            availableLocalesCache = localesFromStrings(getAvailableLocalesNative());
+        }
+        return availableLocalesCache.clone();
+    }
+
+    public static Locale[] getAvailableBreakIteratorLocales() {
+        return localesFromStrings(getAvailableBreakIteratorLocalesNative());
+    }
+
+    public static Locale[] getAvailableCalendarLocales() {
+        return localesFromStrings(getAvailableCalendarLocalesNative());
+    }
+
+    public static Locale[] getAvailableCollatorLocales() {
+        return localesFromStrings(getAvailableCollatorLocalesNative());
+    }
+
+    public static Locale[] getAvailableDateFormatLocales() {
+        return localesFromStrings(getAvailableDateFormatLocalesNative());
+    }
+
+    public static Locale[] getAvailableDateFormatSymbolsLocales() {
+        return getAvailableDateFormatLocales();
+    }
+
+    public static Locale[] getAvailableDecimalFormatSymbolsLocales() {
+        return getAvailableNumberFormatLocales();
+    }
+
+    public static Locale[] getAvailableNumberFormatLocales() {
+        return localesFromStrings(getAvailableNumberFormatLocalesNative());
+    }
+
     // --- Native methods accessing ICU's database ----------------------------
 
+    private static native String[] getAvailableBreakIteratorLocalesNative();
+    private static native String[] getAvailableCalendarLocalesNative();
+    private static native String[] getAvailableCollatorLocalesNative();
+    private static native String[] getAvailableDateFormatLocalesNative();
+    private static native String[] getAvailableLocalesNative();
+    private static native String[] getAvailableNumberFormatLocalesNative();
+
+    public static native String getCurrencyCodeNative(String locale);
+    public static native int getCurrencyFractionDigitsNative(String currencyCode);
+    public static native String getCurrencySymbolNative(String locale, String currencyCode);
+
     public static native String getDisplayCountryNative(String countryCode, String locale);
     public static native String getDisplayLanguageNative(String languageCode, String locale);
     public static native String getDisplayVariantNative(String variantCode, String locale);
@@ -294,13 +299,6 @@
     public static native String getISO3CountryNative(String locale);
     public static native String getISO3LanguageNative(String locale);
 
-    public static native String getCurrencyCodeNative(String locale);
-    public static native String getCurrencySymbolNative(String locale, String currencyCode);
-
-    public static native int getCurrencyFractionDigitsNative(String currencyCode);
-
-    private static native String[] getAvailableLocalesNative();
-
     private static native String[] getISOLanguagesNative();
     private static native String[] getISOCountriesNative();
 
@@ -309,30 +307,5 @@
     private static native String getDisplayTimeZoneNative(String id, boolean isDST, int style,
             String locale);
 
-    private static LocaleData initLocaleData(Locale locale) {
-        LocaleData localeData = new LocaleData();
-        if (!initLocaleDataImpl(locale.toString(), localeData)) {
-            throw new AssertionError("couldn't initialize LocaleData for locale " + locale);
-        }
-        if (localeData.fullTimeFormat != null) {
-            // There are some full time format patterns in ICU that use the pattern character 'v'.
-            // Java doesn't accept this, so we replace it with 'z' which has about the same result
-            // as 'v', the timezone name.
-            // 'v' -> "PT", 'z' -> "PST", v is the generic timezone and z the standard tz
-            // "vvvv" -> "Pacific Time", "zzzz" -> "Pacific Standard Time"
-            localeData.fullTimeFormat = localeData.fullTimeFormat.replace('v', 'z');
-        }
-        if (localeData.numberPattern != null) {
-            // The number pattern might contain positive and negative subpatterns. Arabic, for
-            // example, might look like "#,##0.###;#,##0.###-" because the minus sign should be
-            // written last. Macedonian supposedly looks something like "#,##0.###;(#,##0.###)".
-            // (The negative subpattern is optional, though, and not present in most locales.)
-            // By only swallowing '#'es and ','s after the '.', we ensure that we don't
-            // accidentally eat too much.
-            localeData.integerPattern = localeData.numberPattern.replaceAll("\\.[#,]*", "");
-        }
-        return localeData;
-    }
-
-    private static native boolean initLocaleDataImpl(String locale, LocaleData result);
+    static native boolean initLocaleDataImpl(String locale, LocaleData result);
 }
diff --git a/icu/src/main/java/com/ibm/icu4jni/util/LocaleData.java b/icu/src/main/java/com/ibm/icu4jni/util/LocaleData.java
index 24d3323..e27bd54 100644
--- a/icu/src/main/java/com/ibm/icu4jni/util/LocaleData.java
+++ b/icu/src/main/java/com/ibm/icu4jni/util/LocaleData.java
@@ -17,6 +17,9 @@
 package com.ibm.icu4jni.util;
 
 import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
 
 /**
  * Passes locale-specific from ICU native code to Java.
@@ -25,53 +28,111 @@
  * in the case of arrays. If you ever expose any of these things to user code, you must give
  * them a clone rather than the original.
  */
-public class LocaleData {
+public final class LocaleData {
+    // A cache for the locale-specific data.
+    private static final HashMap<String, LocaleData> localeDataCache = new HashMap<String, LocaleData>();
+
     public Integer firstDayOfWeek;
     public Integer minimalDaysInFirstWeek;
-    
+
     public String[] amPm;
-    
+
     public String[] eras;
-    
+
     public String[] longMonthNames;
     public String[] shortMonthNames;
-    
+
     public String[] longWeekdayNames;
     public String[] shortWeekdayNames;
-    
+
     public String fullTimeFormat;
     public String longTimeFormat;
     public String mediumTimeFormat;
     public String shortTimeFormat;
-    
+
     public String fullDateFormat;
     public String longDateFormat;
     public String mediumDateFormat;
     public String shortDateFormat;
-    
-    public String decimalPatternChars;
-    
+
+    // DecimalFormatSymbols.
+    public char zeroDigit;
+    public char digit;
+    public char decimalSeparator;
+    public char groupingSeparator;
+    public char patternSeparator;
+    public char percent;
+    public char perMill;
+    public char monetarySeparator;
+    public char minusSign;
+    public String exponentSeparator;
     public String infinity;
     public String NaN;
-    
+
     public String currencySymbol;
     public String internationalCurrencySymbol;
-    
+
     public String numberPattern;
     public String integerPattern;
     public String currencyPattern;
     public String percentPattern;
-    
+
+    private LocaleData() {
+    }
+
+    /**
+     * Returns a shared LocaleData for the given locale.
+     */
+    public static LocaleData get(Locale locale) {
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        String localeName = locale.toString();
+        synchronized (localeDataCache) {
+            LocaleData localeData = localeDataCache.get(localeName);
+            if (localeData != null) {
+                return localeData;
+            }
+        }
+        LocaleData newLocaleData = makeLocaleData(locale);
+        synchronized (localeDataCache) {
+            LocaleData localeData = localeDataCache.get(localeName);
+            if (localeData != null) {
+                return localeData;
+            }
+            localeDataCache.put(localeName, newLocaleData);
+            return newLocaleData;
+        }
+    }
+
+    private static LocaleData makeLocaleData(Locale locale) {
+        String language = locale.getLanguage();
+        String country = locale.getCountry();
+        String variant = locale.getVariant();
+        // Start with data from the parent (next-most-specific) locale...
+        LocaleData result = new LocaleData();
+        if (!variant.isEmpty()) {
+            result.overrideWithDataFrom(get(new Locale(language, country, "")));
+        } else if (!country.isEmpty()) {
+            result.overrideWithDataFrom(get(new Locale(language, "", "")));
+        } else if (!language.isEmpty()) {
+            result.overrideWithDataFrom(get(Locale.ROOT));
+        }
+        // Override with data from this locale.
+        result.overrideWithDataFrom(initLocaleData(locale));
+        return result;
+    }
+
     @Override public String toString() {
         return "LocaleData[" +
                 "firstDayOfWeek=" + firstDayOfWeek + "," +
                 "minimalDaysInFirstWeek=" + minimalDaysInFirstWeek + "," +
-                "amPm=" + amPm + "," +
-                "eras=" + eras + "," +
-                "longMonthNames=" + longMonthNames + "," +
-                "shortMonthNames=" + shortMonthNames + "," +
-                "longWeekdayNames=" + longWeekdayNames + "," +
-                "shortWeekdayNames=" + shortWeekdayNames + "," +
+                "amPm=" + Arrays.toString(amPm) + "," +
+                "eras=" + Arrays.toString(eras) + "," +
+                "longMonthNames=" + Arrays.toString(longMonthNames) + "," +
+                "shortMonthNames=" + Arrays.toString(shortMonthNames) + "," +
+                "longWeekdayNames=" + Arrays.toString(longWeekdayNames) + "," +
+                "shortWeekdayNames=" + Arrays.toString(shortWeekdayNames) + "," +
                 "fullTimeFormat=" + fullTimeFormat + "," +
                 "longTimeFormat=" + longTimeFormat + "," +
                 "mediumTimeFormat=" + mediumTimeFormat + "," +
@@ -80,7 +141,16 @@
                 "longDateFormat=" + longDateFormat + "," +
                 "mediumDateFormat=" + mediumDateFormat + "," +
                 "shortDateFormat=" + shortDateFormat + "," +
-                "decimalPatternChars=" + decimalPatternChars + "," +
+                "zeroDigit=" + zeroDigit + "," +
+                "digit=" + digit + "," +
+                "decimalSeparator=" + decimalSeparator + "," +
+                "groupingSeparator=" + groupingSeparator + "," +
+                "patternSeparator=" + patternSeparator + "," +
+                "percent=" + percent + "," +
+                "perMill=" + perMill + "," +
+                "monetarySeparator=" + monetarySeparator + "," +
+                "minusSign=" + minusSign + "," +
+                "exponentSeparator=" + exponentSeparator + "," +
                 "infinity=" + infinity + "," +
                 "NaN=" + NaN + "," +
                 "currencySymbol=" + currencySymbol + "," +
@@ -90,8 +160,8 @@
                 "currencyPattern=" + currencyPattern + "," +
                 "percentPattern=" + percentPattern + "]";
     }
-    
-    public void overrideWithDataFrom(LocaleData overrides) {
+
+    private void overrideWithDataFrom(LocaleData overrides) {
         if (overrides.firstDayOfWeek != null) {
             firstDayOfWeek = overrides.firstDayOfWeek;
         }
@@ -140,8 +210,35 @@
         if (overrides.shortDateFormat != null) {
             shortDateFormat = overrides.shortDateFormat;
         }
-        if (overrides.decimalPatternChars != null) {
-            decimalPatternChars = overrides.decimalPatternChars;
+        if (overrides.zeroDigit != '\0') {
+            zeroDigit = overrides.zeroDigit;
+        }
+        if (overrides.digit != '\0') {
+            digit = overrides.digit;
+        }
+        if (overrides.decimalSeparator != '\0') {
+            decimalSeparator = overrides.decimalSeparator;
+        }
+        if (overrides.groupingSeparator != '\0') {
+            groupingSeparator = overrides.groupingSeparator;
+        }
+        if (overrides.patternSeparator != '\0') {
+            patternSeparator = overrides.patternSeparator;
+        }
+        if (overrides.percent != '\0') {
+            percent = overrides.percent;
+        }
+        if (overrides.perMill != '\0') {
+            perMill = overrides.perMill;
+        }
+        if (overrides.monetarySeparator != '\0') {
+            monetarySeparator = overrides.monetarySeparator;
+        }
+        if (overrides.minusSign != '\0') {
+            minusSign = overrides.minusSign;
+        }
+        if (overrides.exponentSeparator != null) {
+            exponentSeparator = overrides.exponentSeparator;
         }
         if (overrides.NaN != null) {
             NaN = overrides.NaN;
@@ -168,7 +265,7 @@
             percentPattern = overrides.percentPattern;
         }
     }
-    
+
     public String getDateFormat(int style) {
         switch (style) {
         case DateFormat.SHORT:
@@ -182,7 +279,7 @@
         }
         throw new AssertionError();
     }
-    
+
     public String getTimeFormat(int style) {
         switch (style) {
         case DateFormat.SHORT:
@@ -196,4 +293,29 @@
         }
         throw new AssertionError();
     }
+
+    private static LocaleData initLocaleData(Locale locale) {
+        LocaleData localeData = new LocaleData();
+        if (!ICU.initLocaleDataImpl(locale.toString(), localeData)) {
+            throw new AssertionError("couldn't initialize LocaleData for locale " + locale);
+        }
+        if (localeData.fullTimeFormat != null) {
+            // There are some full time format patterns in ICU that use the pattern character 'v'.
+            // Java doesn't accept this, so we replace it with 'z' which has about the same result
+            // as 'v', the timezone name.
+            // 'v' -> "PT", 'z' -> "PST", v is the generic timezone and z the standard tz
+            // "vvvv" -> "Pacific Time", "zzzz" -> "Pacific Standard Time"
+            localeData.fullTimeFormat = localeData.fullTimeFormat.replace('v', 'z');
+        }
+        if (localeData.numberPattern != null) {
+            // The number pattern might contain positive and negative subpatterns. Arabic, for
+            // example, might look like "#,##0.###;#,##0.###-" because the minus sign should be
+            // written last. Macedonian supposedly looks something like "#,##0.###;(#,##0.###)".
+            // (The negative subpattern is optional, though, and not present in most locales.)
+            // By only swallowing '#'es and ','s after the '.', we ensure that we don't
+            // accidentally eat too much.
+            localeData.integerPattern = localeData.numberPattern.replaceAll("\\.[#,]*", "");
+        }
+        return localeData;
+    }
 }
diff --git a/icu/src/main/native/BidiWrapper.cpp b/icu/src/main/native/BidiWrapper.cpp
index 6bc650a0..03efa92 100644
--- a/icu/src/main/native/BidiWrapper.cpp
+++ b/icu/src/main/native/BidiWrapper.cpp
@@ -14,28 +14,52 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "AndroidSystemNatives.h"
+#define LOG_TAG "BidiWrapper"
+
 #include <JNIHelp.h>
 #include "ErrorCode.h"
+#include "UniquePtr.h"
 #include "unicode/ubidi.h"
 #include <stdlib.h>
 #include <string.h>
 
 struct BiDiData {
-    BiDiData(UBiDi* biDi) : mBiDi(biDi), embeddingLevels(NULL) {
+    BiDiData(UBiDi* biDi) : mBiDi(biDi), mEmbeddingLevels(NULL) {
     }
+
     ~BiDiData() {
         ubidi_close(mBiDi);
-        delete[] embeddingLevels;
     }
+
+    UBiDiLevel* embeddingLevels() {
+        return reinterpret_cast<UBiDiLevel*>(&mEmbeddingLevels[0]);
+    }
+
+    void setEmbeddingLevels(jbyte* newEmbeddingLevels) {
+        mEmbeddingLevels.reset(newEmbeddingLevels);
+    }
+
+    UBiDi* uBiDi() {
+        return mBiDi;
+    }
+
+private:
     UBiDi* mBiDi;
-    jbyte* embeddingLevels;
+    UniquePtr<jbyte[]> mEmbeddingLevels;
+
+    // Disallow copy and assignment.
+    BiDiData(const BiDiData&);
+    void operator=(const BiDiData&);
 };
 
 static BiDiData* biDiData(jlong ptr) {
     return reinterpret_cast<BiDiData*>(static_cast<uintptr_t>(ptr));
 }
 
+static UBiDi* uBiDi(jlong ptr) {
+    return reinterpret_cast<BiDiData*>(static_cast<uintptr_t>(ptr))->uBiDi();
+}
+
 static jlong BidiWrapper_ubidi_open(JNIEnv* env, jclass) {
     return reinterpret_cast<uintptr_t>(new BiDiData(ubidi_open()));
 }
@@ -46,72 +70,68 @@
 
 static void BidiWrapper_ubidi_setPara(JNIEnv* env, jclass, jlong ptr, jcharArray text, jint length, jbyte paraLevel, jbyteArray newEmbeddingLevels) {
     BiDiData* data = biDiData(ptr);
-    jbyte* oldEmbeddingLevels = data->embeddingLevels;
     // Copy the new embedding levels from the Java heap to the native heap.
     if (newEmbeddingLevels != NULL) {
-        data->embeddingLevels = new jbyte[length];
-        env->GetByteArrayRegion(newEmbeddingLevels, 0, length, data->embeddingLevels);
+        jbyte* dst;
+        data->setEmbeddingLevels(dst = new jbyte[length]);
+        env->GetByteArrayRegion(newEmbeddingLevels, 0, length, dst);
     } else {
-        data->embeddingLevels = NULL;
+        data->setEmbeddingLevels(NULL);
     }
     UErrorCode err = U_ZERO_ERROR;
-    jchar* _text = env->GetCharArrayElements(text, NULL);
-    ubidi_setPara(data->mBiDi, _text, length, paraLevel, (UBiDiLevel*) data->embeddingLevels, &err);
-    env->ReleaseCharArrayElements(text, _text, 0);
-    delete[] oldEmbeddingLevels;
+    jchar* chars = env->GetCharArrayElements(text, NULL);
+    ubidi_setPara(data->uBiDi(), chars, length, paraLevel, data->embeddingLevels(), &err);
+    env->ReleaseCharArrayElements(text, chars, 0);
     icu4jni_error(env, err);
 }
 
 static jlong BidiWrapper_ubidi_setLine(JNIEnv* env, jclass, jlong ptr, jint start, jint limit) {
     UErrorCode err = U_ZERO_ERROR;
     UBiDi* sized = ubidi_openSized(limit - start, 0, &err);
-    if (icu4jni_error(env, err)) {
+    if (icu4jni_error(env, err) != FALSE) {
         return 0;
     }
-    BiDiData* lineData = new BiDiData(sized);
-    BiDiData* data = biDiData(ptr);
-    ubidi_setLine(data->mBiDi, start, limit, lineData->mBiDi, &err);
+    UniquePtr<BiDiData> lineData(new BiDiData(sized));
+    ubidi_setLine(uBiDi(ptr), start, limit, lineData->uBiDi(), &err);
     icu4jni_error(env, err);
-    return reinterpret_cast<uintptr_t>(lineData);
+    return reinterpret_cast<uintptr_t>(lineData.release());
 }
 
 static jint BidiWrapper_ubidi_getDirection(JNIEnv * env, jclass clazz, jlong ptr) {
-    return ubidi_getDirection(biDiData(ptr)->mBiDi);
+    return ubidi_getDirection(uBiDi(ptr));
 }
 
 static jint BidiWrapper_ubidi_getLength(JNIEnv* env, jclass, jlong ptr) {
-    return ubidi_getLength(biDiData(ptr)->mBiDi);
+    return ubidi_getLength(uBiDi(ptr));
 }
 
 static jbyte BidiWrapper_ubidi_getParaLevel(JNIEnv* env, jclass, jlong ptr) {
-    return ubidi_getParaLevel(biDiData(ptr)->mBiDi);
+    return ubidi_getParaLevel(uBiDi(ptr));
 }
 
 static jbyteArray BidiWrapper_ubidi_getLevels(JNIEnv* env, jclass, jlong ptr) {
-    BiDiData* data = biDiData(ptr);
     UErrorCode err = U_ZERO_ERROR;
-    const UBiDiLevel* levels = ubidi_getLevels(data->mBiDi, &err);
+    const UBiDiLevel* levels = ubidi_getLevels(uBiDi(ptr), &err);
     if (icu4jni_error(env, err)) {
         return NULL;
     }
-    int len = ubidi_getLength(data->mBiDi);
+    int len = ubidi_getLength(uBiDi(ptr));
     jbyteArray result = env->NewByteArray(len);
     env->SetByteArrayRegion(result, 0, len, reinterpret_cast<const jbyte*>(levels));
     return result;
 }
 
 static jint BidiWrapper_ubidi_countRuns(JNIEnv* env, jclass, jlong ptr) {
-    BiDiData* data = biDiData(ptr);
     UErrorCode err = U_ZERO_ERROR;
-    int count = ubidi_countRuns(data->mBiDi, &err);
+    int count = ubidi_countRuns(uBiDi(ptr), &err);
     icu4jni_error(env, err);
     return count;
 }
 
 static jobjectArray BidiWrapper_ubidi_getRuns(JNIEnv* env, jclass, jlong ptr) {
-    BiDiData* data = biDiData(ptr);
+    UBiDi* ubidi = uBiDi(ptr);
     UErrorCode err = U_ZERO_ERROR;
-    int runCount = ubidi_countRuns(data->mBiDi, &err);
+    int runCount = ubidi_countRuns(ubidi, &err);
     if (icu4jni_error(env, err)) {
         return NULL;
     }
@@ -122,7 +142,7 @@
     int start = 0;
     int limit = 0;
     for (int i = 0; i < runCount; ++i) {
-        ubidi_getLogicalRun(data->mBiDi, start, &limit, &level);
+        ubidi_getLogicalRun(ubidi, start, &limit, &level);
         jobject run = env->NewObject(bidiRunClass, bidiRunConstructor, start, limit, level);
         env->SetObjectArrayElement(runs, i, run);
         start = limit;
@@ -131,13 +151,12 @@
 }
 
 static jintArray BidiWrapper_ubidi_reorderVisual(JNIEnv* env, jclass, jbyteArray levels, jint length) {
-    int* local_indexMap = new int[length];
+    UniquePtr<int[]> local_indexMap(new int[length]);
     jbyte* local_levelBytes = env->GetByteArrayElements(levels, NULL);
     UBiDiLevel* local_levels = reinterpret_cast<UBiDiLevel*>(local_levelBytes);
-    ubidi_reorderVisual(local_levels, length, local_indexMap);
+    ubidi_reorderVisual(local_levels, length, &local_indexMap[0]);
     jintArray result = env->NewIntArray(length);
-    env->SetIntArrayRegion(result, 0, length, local_indexMap);
-    delete[] local_indexMap;
+    env->SetIntArrayRegion(result, 0, length, &local_indexMap[0]);
     env->ReleaseByteArrayElements(levels, local_levelBytes, 0);
     return result;
 }
diff --git a/icu/src/main/native/Resources.cpp b/icu/src/main/native/ICU.cpp
similarity index 76%
rename from icu/src/main/native/Resources.cpp
rename to icu/src/main/native/ICU.cpp
index 00bf746..1517932 100644
--- a/icu/src/main/native/Resources.cpp
+++ b/icu/src/main/native/ICU.cpp
@@ -14,13 +14,18 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Resources"
+#define LOG_TAG "ICU"
+
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
+#include "ScopedUtfChars.h"
+#include "UniquePtr.h"
 #include "cutils/log.h"
 #include "unicode/numfmt.h"
 #include "unicode/locid.h"
+#include "unicode/ubrk.h"
 #include "unicode/ucal.h"
+#include "unicode/ucol.h"
+#include "unicode/udat.h"
 #include "unicode/gregocal.h"
 #include "unicode/ucurr.h"
 #include "unicode/calendar.h"
@@ -58,37 +63,33 @@
 
 private:
     UResourceBundle* mBundle;
+
+    // Disallow copy and assignment.
+    ScopedResourceBundle(const ScopedResourceBundle&);
+    void operator=(const ScopedResourceBundle&);
 };
 
-static Locale getLocale(JNIEnv* env, jstring locale) {
-    const char* name = env->GetStringUTFChars(locale, NULL);
-    Locale result = Locale::createFromName(name);
-    env->ReleaseStringUTFChars(locale, name);
-    return result;
+static Locale getLocale(JNIEnv* env, jstring localeName) {
+    return Locale::createFromName(ScopedUtfChars(env, localeName).data());
 }
 
-static jint getCurrencyFractionDigitsNative(JNIEnv* env, jclass clazz, jstring currencyCode) {
+static jint getCurrencyFractionDigitsNative(JNIEnv* env, jclass, jstring currencyCode) {
     UErrorCode status = U_ZERO_ERROR;
-    
-    NumberFormat* fmt = NumberFormat::createCurrencyInstance(status);
+    UniquePtr<NumberFormat> fmt(NumberFormat::createCurrencyInstance(status));
     if (U_FAILURE(status)) {
         return -1;
     }
-
     const jchar* cCode = env->GetStringChars(currencyCode, NULL);
     fmt->setCurrency(cCode, status);
     env->ReleaseStringChars(currencyCode, cCode);
     if (U_FAILURE(status)) {
         return -1;
     }
-    
     // for CurrencyFormats the minimum and maximum fraction digits are the same.
-    int result = fmt->getMinimumFractionDigits(); 
-    delete fmt;
-    return result;
+    return fmt->getMinimumFractionDigits(); 
 }
 
-static jstring getCurrencyCodeNative(JNIEnv* env, jclass clazz, jstring key) {
+static jstring getCurrencyCodeNative(JNIEnv* env, jclass, jstring key) {
     UErrorCode status = U_ZERO_ERROR;
     ScopedResourceBundle supplData(ures_openDirect(NULL, "supplementalData", &status));
     if (U_FAILURE(status)) {
@@ -137,8 +138,7 @@
     return env->NewString(id, length);
 }
 
-static jstring getCurrencySymbolNative(JNIEnv* env, jclass clazz, 
-        jstring locale, jstring currencyCode) {
+static jstring getCurrencySymbolNative(JNIEnv* env, jclass, jstring locale, jstring currencyCode) {
     // LOGI("ENTER getCurrencySymbolNative");
 
     const char* locName = env->GetStringUTFChars(locale, NULL);
@@ -170,8 +170,7 @@
     return (currSymbL == 0) ? NULL : env->NewString(currSymbU, currSymbL);
 }
 
-static jstring getDisplayCountryNative(JNIEnv* env, jclass clazz, 
-        jstring targetLocale, jstring locale) {
+static jstring getDisplayCountryNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
 
     Locale loc = getLocale(env, locale);
     Locale targetLoc = getLocale(env, targetLocale);
@@ -181,8 +180,7 @@
     return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring getDisplayLanguageNative(JNIEnv* env, jclass clazz, 
-        jstring targetLocale, jstring locale) {
+static jstring getDisplayLanguageNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
 
     Locale loc = getLocale(env, locale);
     Locale targetLoc = getLocale(env, targetLocale);
@@ -192,23 +190,20 @@
     return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring getDisplayVariantNative(JNIEnv* env, jclass clazz, 
-        jstring targetLocale, jstring locale) {
-
+static jstring getDisplayVariantNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) {
     Locale loc = getLocale(env, locale);
     Locale targetLoc = getLocale(env, targetLocale);
-
     UnicodeString str;
     targetLoc.getDisplayVariant(loc, str);
     return env->NewString(str.getBuffer(), str.length());
 }
 
-static jstring getISO3CountryNative(JNIEnv* env, jclass clazz, jstring locale) {
+static jstring getISO3CountryNative(JNIEnv* env, jclass, jstring locale) {
     Locale loc = getLocale(env, locale);
     return env->NewStringUTF(loc.getISO3Country());
 }
 
-static jstring getISO3LanguageNative(JNIEnv* env, jclass clazz, jstring locale) {
+static jstring getISO3LanguageNative(JNIEnv* env, jclass, jstring locale) {
     Locale loc = getLocale(env, locale);
     return env->NewStringUTF(loc.getISO3Language());
 }
@@ -227,25 +222,50 @@
     return result;
 }
 
-static jobjectArray getISOCountriesNative(JNIEnv* env, jclass clazz) {
+static jobjectArray getISOCountriesNative(JNIEnv* env, jclass) {
     return toStringArray(env, Locale::getISOCountries());
 }
 
-static jobjectArray getISOLanguagesNative(JNIEnv* env, jclass clazz) {
+static jobjectArray getISOLanguagesNative(JNIEnv* env, jclass) {
     return toStringArray(env, Locale::getISOLanguages());
 }
 
-static jobjectArray getAvailableLocalesNative(JNIEnv* env, jclass clazz) {
-    size_t count = uloc_countAvailable();
+template <typename Counter, typename Getter>
+static jobjectArray getAvailableLocales(JNIEnv* env, Counter* counter, Getter* getter) {
+    size_t count = (*counter)();
     jobjectArray result = env->NewObjectArray(count, string_class, NULL);
     for (size_t i = 0; i < count; ++i) {
-        jstring s = env->NewStringUTF(uloc_getAvailable(i));
+        jstring s = env->NewStringUTF((*getter)(i));
         env->SetObjectArrayElement(result, i, s);
         env->DeleteLocalRef(s);
     }
     return result;
 }
 
+static jobjectArray getAvailableLocalesNative(JNIEnv* env, jclass) {
+    return getAvailableLocales(env, uloc_countAvailable, uloc_getAvailable);
+}
+
+static jobjectArray getAvailableBreakIteratorLocalesNative(JNIEnv* env, jclass) {
+    return getAvailableLocales(env, ubrk_countAvailable, ubrk_getAvailable);
+}
+
+static jobjectArray getAvailableCalendarLocalesNative(JNIEnv* env, jclass) {
+    return getAvailableLocales(env, ucal_countAvailable, ucal_getAvailable);
+}
+
+static jobjectArray getAvailableCollatorLocalesNative(JNIEnv* env, jclass) {
+    return getAvailableLocales(env, ucol_countAvailable, ucol_getAvailable);
+}
+
+static jobjectArray getAvailableDateFormatLocalesNative(JNIEnv* env, jclass) {
+    return getAvailableLocales(env, udat_countAvailable, udat_getAvailable);
+}
+
+static jobjectArray getAvailableNumberFormatLocalesNative(JNIEnv* env, jclass) {
+    return getAvailableLocales(env, unum_countAvailable, unum_getAvailable);
+}
+
 static TimeZone* timeZoneFromId(JNIEnv* env, jstring id) {
     const jchar* chars = env->GetStringChars(id, NULL);
     const UnicodeString zoneID(reinterpret_cast<const UChar*>(chars), env->GetStringLength(id));
@@ -259,9 +279,7 @@
     return env->NewString(str.getBuffer(), str.length());
 }
 
-static void getTimeZonesNative(JNIEnv* env, jclass clazz,
-        jobjectArray outerArray, jstring locale) {
-
+static void getTimeZonesNative(JNIEnv* env, jclass, jobjectArray outerArray, jstring locale) {
     // get all timezone objects
     jobjectArray zoneIdArray = (jobjectArray) env->GetObjectArrayElement(outerArray, 0);
     int count = env->GetArrayLength(zoneIdArray);
@@ -331,18 +349,13 @@
     }
 }
 
-static jstring getDisplayTimeZoneNative(JNIEnv* env, jclass clazz,
-        jstring zoneId, jboolean isDST, jint style, jstring localeId) {
-
-    TimeZone* zone = timeZoneFromId(env, zoneId);
+static jstring getDisplayTimeZoneNative(JNIEnv* env, jclass, jstring zoneId, jboolean isDST, jint style, jstring localeId) {
+    UniquePtr<TimeZone> zone(timeZoneFromId(env, zoneId));
     Locale locale = getLocale(env, localeId);
-
     // Try to get the display name of the TimeZone according to the Locale
     UnicodeString displayName;
     zone->getDisplayName((UBool)isDST, (style == 0 ? TimeZone::SHORT : TimeZone::LONG), locale, displayName);
-    jstring result = env->NewString(displayName.getBuffer(), displayName.length());
-    delete zone;
-    return result;
+    return env->NewString(displayName.getBuffer(), displayName.length());
 }
 
 static bool getDayIntVector(JNIEnv* env, UResourceBundle* gregorian, int* values) {
@@ -511,62 +524,18 @@
     return getWeekdayNames(env, gregorian, false);
 }
 
-static jstring getDecimalPatternChars(JNIEnv* env, UResourceBundle* rootElems) {
-    UErrorCode status = U_ZERO_ERROR;
-
-    int zeroL, digitL, decSepL, groupL, listL, percentL, permillL, expL, currSepL, minusL;
-
-    const jchar* zero = ures_getStringByIndex(rootElems, 4, &zeroL, &status);
-    const jchar* digit = ures_getStringByIndex(rootElems, 5, &digitL, &status);
-    const jchar* decSep = ures_getStringByIndex(rootElems, 0, &decSepL, &status);
-    const jchar* group = ures_getStringByIndex(rootElems, 1, &groupL, &status);
-    const jchar* list = ures_getStringByIndex(rootElems, 2, &listL, &status);
-    const jchar* percent = ures_getStringByIndex(rootElems, 3, &percentL, &status);
-    const jchar* permill = ures_getStringByIndex(rootElems, 8, &permillL, &status);
-    const jchar* exp = ures_getStringByIndex(rootElems, 7, &expL, &status);
-    const jchar* currSep = ures_getStringByIndex(rootElems, 0, &currSepL, &status);
-    const jchar* minus = ures_getStringByIndex(rootElems, 6, &minusL, &status);
-
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-
-    jchar patternChars[11];
-    patternChars[0] = 0;
-
-    u_strncat(patternChars, zero, 1);
-    u_strncat(patternChars, digit, 1);
-    u_strncat(patternChars, decSep, 1);
-    u_strncat(patternChars, group, 1);
-    u_strncat(patternChars, list, 1);
-    u_strncat(patternChars, percent, 1);
-    u_strncat(patternChars, permill, 1);
-    u_strncat(patternChars, exp, 1);
-    u_strncat(patternChars, currSep, 1);
-    u_strncat(patternChars, minus, 1);
-
-    return env->NewString(patternChars, 10);
-}
-
 static jstring getIntCurrencyCode(JNIEnv* env, jstring locale) {
-    const char* locStr = env->GetStringUTFChars(locale, NULL);
+    ScopedUtfChars localeChars(env, locale);
 
     // Extract the 2-character country name.
-    if (strlen(locStr) < 5) {
-        env->ReleaseStringUTFChars(locale, locStr);
+    if (strlen(localeChars.data()) < 5) {
         return NULL;
     }
-    if (locStr[3] < 'A' || locStr[3] > 'Z' || locStr[4] < 'A' || locStr[4] > 'Z') {
-        env->ReleaseStringUTFChars(locale, locStr);
+    if (localeChars[3] < 'A' || localeChars[3] > 'Z' || localeChars[4] < 'A' || localeChars[4] > 'Z') {
         return NULL;
     }
 
-    char country[3] = {0,0,0};
-    country[0] = locStr[3];
-    country[1] = locStr[4];
-
-    env->ReleaseStringUTFChars(locale, locStr);
-
+    char country[3] = { localeChars[3], localeChars[4], 0 };
     return getCurrencyCodeNative(env, NULL, env->NewStringUTF(country));
 }
 
@@ -600,10 +569,25 @@
     const UChar* chars = ures_getStringByIndex(bundle, index, &charCount, &status);
     if (U_SUCCESS(status)) {
         setStringField(env, obj, fieldName, env->NewString(chars, charCount));
+    } else {
+        LOGE("Error setting String field %s from ICU resource: %s", fieldName, u_errorName(status));
     }
 }
 
-static jboolean initLocaleDataImpl(JNIEnv* env, jclass clazz, jstring locale, jobject localeData) {
+static void setCharField(JNIEnv* env, jobject obj, const char* fieldName, UResourceBundle* bundle, int index) {
+    UErrorCode status = U_ZERO_ERROR;
+    int charCount;
+    const UChar* chars = ures_getStringByIndex(bundle, index, &charCount, &status);
+    if (U_SUCCESS(status)) {
+        jclass localeDataClass = env->FindClass("com/ibm/icu4jni/util/LocaleData");
+        jfieldID fid = env->GetFieldID(localeDataClass, fieldName, "C");
+        env->SetCharField(obj, fid, chars[0]);
+    } else {
+        LOGE("Error setting char field %s from ICU resource: %s", fieldName, u_errorName(status));
+    }
+}
+
+static jboolean initLocaleDataImpl(JNIEnv* env, jclass, jstring locale, jobject localeData) {
     const char* loc = env->GetStringUTFChars(locale, NULL);
     UErrorCode status = U_ZERO_ERROR;
     ScopedResourceBundle root(ures_openU(NULL, loc, &status));
@@ -655,7 +639,16 @@
 
     ScopedResourceBundle numberElements(ures_getByKey(root.get(), "NumberElements", NULL, &status));
     if (U_SUCCESS(status) && ures_getSize(numberElements.get()) >= 11) {
-        setStringField(env, localeData, "decimalPatternChars", getDecimalPatternChars(env, numberElements.get()));
+        setCharField(env, localeData, "zeroDigit", numberElements.get(), 4);
+        setCharField(env, localeData, "digit", numberElements.get(), 5);
+        setCharField(env, localeData, "decimalSeparator", numberElements.get(), 0);
+        setCharField(env, localeData, "groupingSeparator", numberElements.get(), 1);
+        setCharField(env, localeData, "patternSeparator", numberElements.get(), 2);
+        setCharField(env, localeData, "percent", numberElements.get(), 3);
+        setCharField(env, localeData, "perMill", numberElements.get(), 8);
+        setCharField(env, localeData, "monetarySeparator", numberElements.get(), 0);
+        setCharField(env, localeData, "minusSign", numberElements.get(), 6);
+        setStringField(env, localeData, "exponentSeparator", numberElements.get(), 7);
         setStringField(env, localeData, "infinity", numberElements.get(), 9);
         setStringField(env, localeData, "NaN", numberElements.get(), 10);
     }
@@ -664,7 +657,7 @@
     jstring internationalCurrencySymbol = getIntCurrencyCode(env, locale);
     jstring currencySymbol = NULL;
     if (internationalCurrencySymbol != NULL) {
-        currencySymbol = getCurrencySymbolNative(env, clazz, locale, internationalCurrencySymbol);
+        currencySymbol = getCurrencySymbolNative(env, NULL, locale, internationalCurrencySymbol);
     } else {
         internationalCurrencySymbol = env->NewStringUTF("XXX");
     }
@@ -686,45 +679,26 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    {"getCurrencyFractionDigitsNative", "(Ljava/lang/String;)I",
-            (void*) getCurrencyFractionDigitsNative},
-    {"getCurrencyCodeNative", "(Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getCurrencyCodeNative},
-    {"getCurrencySymbolNative", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getCurrencySymbolNative},
-    {"getDisplayCountryNative",
-            "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getDisplayCountryNative},
-    {"getDisplayLanguageNative",
-            "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getDisplayLanguageNative},
-    {"getDisplayVariantNative",
-            "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getDisplayVariantNative},
-    {"getISO3CountryNative",
-            "(Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getISO3CountryNative},
-    {"getISO3LanguageNative",
-            "(Ljava/lang/String;)Ljava/lang/String;",
-            (void*) getISO3LanguageNative},
-    {"getISOCountriesNative", "()[Ljava/lang/String;",
-            (void*) getISOCountriesNative},
-    {"getISOLanguagesNative", "()[Ljava/lang/String;",
-            (void*) getISOLanguagesNative},
-    {"getAvailableLocalesNative", "()[Ljava/lang/String;",
-            (void*) getAvailableLocalesNative},
-    {"getTimeZonesNative",
-            "([[Ljava/lang/String;Ljava/lang/String;)V",
-            (void*) getTimeZonesNative},
-    {"getDisplayTimeZoneNative",
-            "(Ljava/lang/String;ZILjava/lang/String;)Ljava/lang/String;",
-            (void*) getDisplayTimeZoneNative},
-    {"initLocaleDataImpl",
-            "(Ljava/lang/String;Lcom/ibm/icu4jni/util/LocaleData;)Z",
-            (void*) initLocaleDataImpl},
+    {"getAvailableBreakIteratorLocalesNative", "()[Ljava/lang/String;", (void*) getAvailableBreakIteratorLocalesNative},
+    {"getAvailableCalendarLocalesNative", "()[Ljava/lang/String;", (void*) getAvailableCalendarLocalesNative},
+    {"getAvailableCollatorLocalesNative", "()[Ljava/lang/String;", (void*) getAvailableCollatorLocalesNative},
+    {"getAvailableDateFormatLocalesNative", "()[Ljava/lang/String;", (void*) getAvailableDateFormatLocalesNative},
+    {"getAvailableLocalesNative", "()[Ljava/lang/String;", (void*) getAvailableLocalesNative},
+    {"getAvailableNumberFormatLocalesNative", "()[Ljava/lang/String;", (void*) getAvailableNumberFormatLocalesNative},
+    {"getCurrencyCodeNative", "(Ljava/lang/String;)Ljava/lang/String;", (void*) getCurrencyCodeNative},
+    {"getCurrencyFractionDigitsNative", "(Ljava/lang/String;)I", (void*) getCurrencyFractionDigitsNative},
+    {"getCurrencySymbolNative", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) getCurrencySymbolNative},
+    {"getDisplayCountryNative", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) getDisplayCountryNative},
+    {"getDisplayLanguageNative", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) getDisplayLanguageNative},
+    {"getDisplayTimeZoneNative", "(Ljava/lang/String;ZILjava/lang/String;)Ljava/lang/String;", (void*) getDisplayTimeZoneNative},
+    {"getDisplayVariantNative", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) getDisplayVariantNative},
+    {"getISO3CountryNative", "(Ljava/lang/String;)Ljava/lang/String;", (void*) getISO3CountryNative},
+    {"getISO3LanguageNative", "(Ljava/lang/String;)Ljava/lang/String;", (void*) getISO3LanguageNative},
+    {"getISOCountriesNative", "()[Ljava/lang/String;", (void*) getISOCountriesNative},
+    {"getISOLanguagesNative", "()[Ljava/lang/String;", (void*) getISOLanguagesNative},
+    {"getTimeZonesNative", "([[Ljava/lang/String;Ljava/lang/String;)V", (void*) getTimeZonesNative},
+    {"initLocaleDataImpl", "(Ljava/lang/String;Lcom/ibm/icu4jni/util/LocaleData;)Z", (void*) initLocaleDataImpl},
 };
-
 int register_com_ibm_icu4jni_util_Resources(JNIEnv* env) {
     jclass stringclass = env->FindClass("java/lang/String");
     if (stringclass == NULL) {
@@ -732,6 +706,5 @@
     }
     string_class = (jclass) env->NewGlobalRef(stringclass);
 
-    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/util/Resources",
-            gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/util/ICU", gMethods, NELEM(gMethods));
 }
diff --git a/icu/src/main/native/NativeBreakIterator.cpp b/icu/src/main/native/NativeBreakIterator.cpp
index 600f501..85ada2d 100644
--- a/icu/src/main/native/NativeBreakIterator.cpp
+++ b/icu/src/main/native/NativeBreakIterator.cpp
@@ -14,33 +14,22 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "NativeBreakIterator"
+
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 #include "ErrorCode.h"
+#include "ScopedUtfChars.h"
 #include "unicode/ubrk.h"
 #include "unicode/putil.h"
 #include <stdlib.h>
 
-static jobjectArray getAvailableLocalesImpl(JNIEnv* env, jclass) {
-    jclass stringClass = env->FindClass("java/lang/String");
-    if (stringClass == NULL) {
-        return NULL;
-    }
-    size_t count = ubrk_countAvailable();
-    jobjectArray result = env->NewObjectArray(count, stringClass, NULL);
-    for (size_t i = 0; i < count; ++i) {
-        jstring s = env->NewStringUTF(ubrk_getAvailable(i));
-        env->SetObjectArrayElement(result, i, s);
-        env->DeleteLocalRef(s);
-    }
-    return result;
-}
-
 static jint getIterator(JNIEnv* env, jstring locale, UBreakIteratorType type) {
     UErrorCode status = U_ZERO_ERROR;
-    const char* localeChars = env->GetStringUTFChars(locale, NULL);
-    UBreakIterator* it = ubrk_open(type, localeChars, NULL, 0, &status);
-    env->ReleaseStringUTFChars(locale, localeChars);
+    ScopedUtfChars localeChars(env, locale);
+    if (!localeChars.data()) {
+        return 0;
+    }
+    UBreakIterator* it = ubrk_open(type, localeChars.data(), NULL, 0, &status);
     icu4jni_error(env, status);
     return reinterpret_cast<uintptr_t>(it);
 }
@@ -137,7 +126,6 @@
     { "currentImpl", "(I)I", (void*) currentImpl },
     { "firstImpl", "(I)I", (void*) firstImpl },
     { "followingImpl", "(II)I", (void*) followingImpl },
-    { "getAvailableLocalesImpl", "()[Ljava/lang/String;", (void*) getAvailableLocalesImpl },
     { "getCharacterInstanceImpl", "(Ljava/lang/String;)I", (void*) getCharacterInstanceImpl },
     { "getLineInstanceImpl", "(Ljava/lang/String;)I", (void*) getLineInstanceImpl },
     { "getSentenceInstanceImpl", "(Ljava/lang/String;)I", (void*) getSentenceInstanceImpl },
diff --git a/icu/src/main/native/NativeCollation.cpp b/icu/src/main/native/NativeCollation.cpp
index 52c1c7c..263a525 100644
--- a/icu/src/main/native/NativeCollation.cpp
+++ b/icu/src/main/native/NativeCollation.cpp
@@ -7,8 +7,9 @@
 *******************************************************************************
 */
 
+#define LOG_TAG "NativeCollation"
+
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 #include "ErrorCode.h"
 #include "unicode/ucol.h"
 #include "unicode/ucoleitr.h"
@@ -84,31 +85,16 @@
     return result;
 }
 
-/**
-* Universal attribute getter
-* @param env JNI environment
-* @param obj RuleBasedCollatorJNI object
-* @param address address of the C collator
-* @param type type of attribute to be set
-* @return attribute value
-* @exception thrown when error occurs while getting attribute value
-*/
-static jint getAttribute(JNIEnv *env, jclass obj, jint address,
-        jint type) {
-
+static jint getAttribute(JNIEnv *env, jclass, jint address, jint type) {
     const UCollator *collator = (const UCollator *)(int)address;
-    UErrorCode status = U_ZERO_ERROR;
-    if(collator){
-        jint result = (jint)ucol_getAttribute(collator, (UColAttribute)type, 
-                                            &status);
-        if (icu4jni_error(env, status) != FALSE){
-            return (jint)UCOL_DEFAULT;
-        }
-        return result;
-    }else{
-        icu4jni_error(env,U_ILLEGAL_ARGUMENT_ERROR);
+    if (!collator) {
+        icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR);
+        return 0;
     }
-    return (jint)UCOL_DEFAULT;
+    UErrorCode status = U_ZERO_ERROR;
+    jint result = (jint)ucol_getAttribute(collator, (UColAttribute)type, &status);
+    icu4jni_error(env, status);
+    return result;
 }
 
 /** 
@@ -463,23 +449,11 @@
   return result;
 }
 
-/**
-* Universal attribute setter.
-* @param env JNI environment
-* @param obj RuleBasedCollatorJNI object
-* @param address address of the C collator
-* @param type type of attribute to be set
-* @param value attribute value
-* @exception thrown when error occurs while setting attribute value
-*/
-static void setAttribute(JNIEnv *env, jclass obj, jint address,
-        jint type, jint value) {
-
-  UCollator *collator = (UCollator *)(int)address;
-  UErrorCode status = U_ZERO_ERROR;
-  ucol_setAttribute(collator, (UColAttribute)type, (UColAttributeValue)value, 
-                    &status);
-   icu4jni_error(env, status);
+static void setAttribute(JNIEnv *env, jclass, jint address, jint type, jint value) {
+    UCollator *collator = (UCollator *)(int)address;
+    UErrorCode status = U_ZERO_ERROR;
+    ucol_setAttribute(collator, (UColAttribute)type, (UColAttributeValue)value, &status);
+    icu4jni_error(env, status);
 }
 
 /**
@@ -523,24 +497,7 @@
    icu4jni_error(env, status);
 }
 
-static jobjectArray getAvailableLocalesImpl(JNIEnv *env, jclass clazz) {
-    jclass stringClass = env->FindClass("java/lang/String");
-    if (stringClass == NULL) {
-        return NULL;
-    }
-    size_t count = ucol_countAvailable();
-    jobjectArray result = env->NewObjectArray(count, stringClass, NULL);
-    for (size_t i = 0; i < count; ++i) {
-        jstring s = env->NewStringUTF(ucol_getAvailable(i));
-        env->SetObjectArrayElement(result, i, s);
-        env->DeleteLocalRef(s);
-    }
-    return result;
-}
-
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "getAvailableLocalesImpl", "()[Ljava/lang/String;", (void*) getAvailableLocalesImpl },
     { "openCollator", "()I", (void*) openCollator__ },
     { "openCollator", "(Ljava/lang/String;)I", (void*) openCollator__Ljava_lang_String_2 },
     { "openCollatorFromRules", "(Ljava/lang/String;II)I", (void*) openCollatorFromRules },
@@ -564,7 +521,6 @@
     { "getOffset", "(I)I", (void*) getOffset },
     { "setOffset", "(II)V", (void*) setOffset }
 };
-
 int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv *_env) { 
     return jniRegisterNativeMethods(_env, "com/ibm/icu4jni/text/NativeCollation",
                 gMethods, NELEM(gMethods));
diff --git a/icu/src/main/native/NativeConverter.cpp b/icu/src/main/native/NativeConverter.cpp
index f704e8f..3f5a186 100644
--- a/icu/src/main/native/NativeConverter.cpp
+++ b/icu/src/main/native/NativeConverter.cpp
@@ -15,14 +15,17 @@
  * @author: Ram Viswanadha
  */
 
-#include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
-#include "unicode/utypes.h"   /* Basic ICU data types */
-#include "unicode/ucnv.h"     /* C   Converter API    */
-#include "unicode/ustring.h"  /* some more string functions*/
-#include "unicode/ucnv_cb.h"  /* for callback functions */
-#include "unicode/uset.h"     /* for contains function */
+#define LOG_TAG "NativeConverter"
+
 #include "ErrorCode.h"
+#include "JNIHelp.h"
+#include "ScopedUtfChars.h"
+#include "UniquePtr.h"
+#include "unicode/ucnv.h"
+#include "unicode/ucnv_cb.h"
+#include "unicode/uset.h"
+#include "unicode/ustring.h"
+#include "unicode/utypes.h"
 #include <stdlib.h>
 #include <string.h>
 
@@ -30,52 +33,24 @@
 #define com_ibm_icu4jni_converters_NativeConverter_SKIP_CALLBACK 1L
 #define com_ibm_icu4jni_converters_NativeConverter_SUBSTITUTE_CALLBACK 2L
 
-// BEGIN android-removed
-// #define UTF_16BE "UTF-16BE" 
-// #define UTF_16 "UTF-16" 
-// END android-removed
-	 	  
 /* Prototype of callback for substituting user settable sub chars */
 static void JNI_TO_U_CALLBACK_SUBSTITUTE
- (const void *,UConverterToUnicodeArgs *,const char* ,int32_t ,UConverterCallbackReason ,UErrorCode * );
+        (const void *,UConverterToUnicodeArgs *,const char* ,int32_t ,UConverterCallbackReason ,UErrorCode * );
 
-/**
- * Opens the ICU converter
- * @param env environment handle for JNI 
- * @param jClass handle for the class
- * @param handle buffer to recieve ICU's converter address
- * @param converterName name of the ICU converter
- */
-static jlong openConverter (JNIEnv *env, jclass jClass, jstring converterName) {
-
-    UConverter* conv=NULL;
-    UErrorCode errorCode = U_ZERO_ERROR;
-
-    const char* cnvName= (const char*) env->GetStringUTFChars(converterName,NULL);
-    if(cnvName) {
-        int count = env->GetStringUTFLength(converterName);
-
-        conv = ucnv_open(cnvName,&errorCode);
-    }
-    env->ReleaseStringUTFChars(converterName,cnvName);
-
-    if (icu4jni_error(env, errorCode) != FALSE) {
+static jlong openConverter(JNIEnv* env, jclass, jstring converterName) {
+    ScopedUtfChars converterNameChars(env, converterName);
+    if (!converterNameChars.data()) {
         return 0;
     }
-
+    UErrorCode errorCode = U_ZERO_ERROR;
+    UConverter* conv = ucnv_open(converterNameChars.data(), &errorCode);
+    icu4jni_error(env, errorCode);
     return (jlong) conv;
 }
 
-/**
- * Closes the ICU converter
- * @param env environment handle for JNI 
- * @param jClass handle for the class
- * @param handle address of ICU converter
- */
-static void closeConverter (JNIEnv *env, jclass jClass, jlong handle) {
-     
+static void closeConverter(JNIEnv* env, jclass, jlong handle) {
     UConverter* cnv = (UConverter*)(long)handle;
-    if(cnv) {
+    if (cnv) {
         // BEGIN android-added
         // Free up any contexts created in setCallback[Encode|Decode]()
         UConverterToUCallback toAction;
@@ -101,92 +76,6 @@
 }
 
 /**
- * Sets the substution mode for from Unicode conversion. Currently only 
- * two modes are supported: substitute or report
- * @param env environment handle for JNI 
- * @param jClass handle for the class
- * @param handle address of ICU converter
- * @param mode the mode to set 
- */
-static jint setSubstitutionModeCharToByte (JNIEnv *env, jclass jClass, jlong handle, jboolean mode) {
-    
-    UConverter* conv = (UConverter*)(long)handle;
-    UErrorCode errorCode =U_ZERO_ERROR;
-
-    if(conv) {
-        
-        UConverterFromUCallback fromUOldAction ;
-        void* fromUOldContext;
-        void* fromUNewContext=NULL;
-        if(mode) {
-
-            ucnv_setFromUCallBack(conv,
-               UCNV_FROM_U_CALLBACK_SUBSTITUTE,
-               fromUNewContext,
-               &fromUOldAction,
-               (const void**)&fromUOldContext,
-               &errorCode);
-
-        }
-        else{
-
-            ucnv_setFromUCallBack(conv,
-               UCNV_FROM_U_CALLBACK_STOP,
-               fromUNewContext,
-               &fromUOldAction,
-               (const void**)&fromUOldContext,
-               &errorCode);
-         
-        }
-        return errorCode;
-    }
-    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
-    return errorCode;
-}
-/**
- * Sets the substution mode for to Unicode conversion. Currently only 
- * two modes are supported: substitute or report
- * @param env environment handle for JNI 
- * @param jClass handle for the class
- * @param handle address of ICU converter
- * @param mode the mode to set 
- */
-static jint setSubstitutionModeByteToChar (JNIEnv *env, jclass jClass, jlong handle, jboolean mode) {
-    
-    UConverter* conv = (UConverter*)handle;
-    UErrorCode errorCode =U_ZERO_ERROR;
-
-    if(conv) {
-        
-        UConverterToUCallback toUOldAction ;
-        void* toUOldContext;
-        void* toUNewContext=NULL;
-        if(mode) {
-
-            ucnv_setToUCallBack(conv,
-               UCNV_TO_U_CALLBACK_SUBSTITUTE,
-               toUNewContext,
-               &toUOldAction,
-               (const void**)&toUOldContext,
-               &errorCode);
-
-        }
-        else{
-
-            ucnv_setToUCallBack(conv,
-               UCNV_TO_U_CALLBACK_STOP,
-               toUNewContext,
-               &toUOldAction,
-               (const void**)&toUOldContext,
-               &errorCode);
-         
-        }
-        return errorCode;
-    }
-    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
-    return errorCode;
-}
-/**
  * Converts a buffer of Unicode code units to target encoding 
  * @param env environment handle for JNI 
  * @param jClass handle for the class
@@ -198,7 +87,7 @@
  * @param data buffer to recieve state of the current conversion
  * @param flush boolean that specifies end of source input
  */
-static jint convertCharToByte(JNIEnv *env, jclass jClass, jlong handle,  jcharArray source,  jint sourceEnd, jbyteArray target, jint targetEnd, jintArray data, jboolean flush) {
+static jint convertCharToByte(JNIEnv *env, jclass, jlong handle,  jcharArray source,  jint sourceEnd, jbyteArray target, jint targetEnd, jintArray data, jboolean flush) {
 
     UErrorCode errorCode =U_ZERO_ERROR;
     UConverter* cnv = (UConverter*)handle;
@@ -245,9 +134,9 @@
     return errorCode;
 }
 
-static jint encode(JNIEnv *env, jclass jClass, jlong handle, jcharArray source, jint sourceEnd, jbyteArray target, jint targetEnd, jintArray data, jboolean flush) {
+static jint encode(JNIEnv *env, jclass, jlong handle, jcharArray source, jint sourceEnd, jbyteArray target, jint targetEnd, jintArray data, jboolean flush) {
    
-    UErrorCode ec = UErrorCode(convertCharToByte(env, jClass,handle,source,sourceEnd, target,targetEnd,data,flush));
+    UErrorCode ec = UErrorCode(convertCharToByte(env, NULL,handle,source,sourceEnd, target,targetEnd,data,flush));
     UConverter* cnv = (UConverter*)handle;
     jint* myData = (jint*) env->GetPrimitiveArrayCritical(data,NULL);
 
@@ -263,7 +152,7 @@
 
             if(U_SUCCESS(errorCode)) {
                 myData[2] = count;
-            }	  
+            }
         }
     }
     env->ReleasePrimitiveArrayCritical(data,(jint*)myData,0);
@@ -282,7 +171,7 @@
  * @param data buffer to recieve state of the current conversion
  * @param flush boolean that specifies end of source input
  */
-static jint convertByteToChar(JNIEnv *env, jclass jClass, jlong handle, jbyteArray source, jint sourceEnd, jcharArray target, jint targetEnd, jintArray data, jboolean flush) {
+static jint convertByteToChar(JNIEnv *env, jclass, jlong handle, jbyteArray source, jint sourceEnd, jcharArray target, jint targetEnd, jintArray data, jboolean flush) {
 
     UErrorCode errorCode =U_ZERO_ERROR;
     UConverter* cnv = (UConverter*)handle;
@@ -330,9 +219,9 @@
     return errorCode;
 }
 
-static jint decode(JNIEnv *env, jclass jClass, jlong handle, jbyteArray source, jint sourceEnd, jcharArray target, jint targetEnd, jintArray data, jboolean flush) {
+static jint decode(JNIEnv *env, jclass, jlong handle, jbyteArray source, jint sourceEnd, jcharArray target, jint targetEnd, jintArray data, jboolean flush) {
 
-    jint ec = convertByteToChar(env, jClass,handle,source,sourceEnd, target,targetEnd,data,flush);
+    jint ec = convertByteToChar(env, NULL,handle,source,sourceEnd, target,targetEnd,data,flush);
 
     jint* myData = (jint*) env->GetPrimitiveArrayCritical(data,NULL);
     UConverter* cnv = (UConverter*)handle;
@@ -354,89 +243,42 @@
     env->ReleasePrimitiveArrayCritical(data,(jint*)myData,0);
     return ec;
 }
-static void resetByteToChar(JNIEnv *env, jclass jClass, jlong handle) {
 
+static void resetByteToChar(JNIEnv* env, jclass, jlong handle) {
     UConverter* cnv = (UConverter*)handle;
-    if(cnv) {
+    if (cnv) {
         ucnv_resetToUnicode(cnv);
     }
 }
 
-static void resetCharToByte(JNIEnv *env, jclass jClass, jlong handle) {
-
+static void resetCharToByte(JNIEnv* env, jclass, jlong handle) {
     UConverter* cnv = (UConverter*)handle;
-    if(cnv) {
+    if (cnv) {
         ucnv_resetFromUnicode(cnv);
     }
-
 }
 
-static jint countInvalidBytes (JNIEnv *env, jclass jClass, jlong handle, jintArray length) {
-
+static jint getMaxBytesPerChar(JNIEnv *env, jclass, jlong handle) {
     UConverter* cnv = (UConverter*)handle;
-    UErrorCode errorCode = U_ZERO_ERROR;
-    if(cnv) {
-        char invalidChars[32];
-
-        jint* len = (jint*) env->GetPrimitiveArrayCritical(length, NULL);
-        if(len) {
-            ucnv_getInvalidChars(cnv,invalidChars,(int8_t*)len,&errorCode);
-        }
-        env->ReleasePrimitiveArrayCritical(length,(jint*)len,0);
-        return errorCode;
-    }
-    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
-    return errorCode;
-
+    return (cnv != NULL) ? ucnv_getMaxCharSize(cnv) : -1;
 }
 
-
-static jint countInvalidChars(JNIEnv *env, jclass jClass, jlong handle, jintArray length) {
-
-    UErrorCode errorCode =U_ZERO_ERROR;
+static jint getMinBytesPerChar(JNIEnv *env, jclass, jlong handle) {
     UConverter* cnv = (UConverter*)handle;
-    UChar invalidUChars[32];
-    if(cnv) {
-        jint* len = (jint*) env->GetPrimitiveArrayCritical(length, NULL);
-        if(len) {
-            ucnv_getInvalidUChars(cnv,invalidUChars,(int8_t*)len,&errorCode);
-        }
-        env->ReleasePrimitiveArrayCritical(length,(jint*)len,0);
-        return errorCode;
-    }
-    errorCode = U_ILLEGAL_ARGUMENT_ERROR;
-    return errorCode;
-
+    return (cnv != NULL) ? ucnv_getMinCharSize(cnv) : -1;
 }
 
-static jint getMaxBytesPerChar(JNIEnv *env, jclass jClass, jlong handle) {
-
+static jfloat getAveBytesPerChar(JNIEnv *env, jclass, jlong handle) {
     UConverter* cnv = (UConverter*)handle;
-    if(cnv) {
-        return (jint)ucnv_getMaxCharSize(cnv);
-    }
-    return -1;
-}
-
-static jint getMinBytesPerChar(JNIEnv *env, jclass jClass, jlong handle) {
-
-    UConverter* cnv = (UConverter*)handle;
-    if(cnv) {
-        return (jint)ucnv_getMinCharSize(cnv);
-    }
-    return -1;
-}
-static jfloat getAveBytesPerChar(JNIEnv *env, jclass jClass, jlong handle) {
-
-    UConverter* cnv = (UConverter*)handle;
-    if(cnv) {
+    if (cnv) {
          jfloat max = (jfloat)ucnv_getMaxCharSize(cnv);
          jfloat min = (jfloat)ucnv_getMinCharSize(cnv);
          return (jfloat) ( (max+min)/2 );
     }
     return -1;
 }
-static jint flushByteToChar(JNIEnv *env, jclass jClass,jlong handle, jcharArray target, jint targetEnd, jintArray data) {
+
+static jint flushByteToChar(JNIEnv *env, jclass,jlong handle, jcharArray target, jint targetEnd, jintArray data) {
 
     UErrorCode errorCode =U_ZERO_ERROR;
     UConverter* cnv = (UConverter*)handle;
@@ -477,7 +319,7 @@
     return errorCode;
 }
 
-static jint flushCharToByte (JNIEnv *env, jclass jClass, jlong handle, jbyteArray target, jint targetEnd, jintArray data) {
+static jint flushCharToByte (JNIEnv *env, jclass, jlong handle, jbyteArray target, jint targetEnd, jintArray data) {
           
     UErrorCode errorCode =U_ZERO_ERROR;
     UConverter* cnv = (UConverter*)handle;
@@ -519,30 +361,26 @@
 }
 
 static void toChars(const UChar* us, char* cs, int32_t length) {
-    UChar u;
-    while(length>0) {
-        u=*us++;
+    while (length > 0) {
+        UChar u = *us++;
         *cs++=(char)u;
         --length;
     }
 }
-static jint setSubstitutionBytes(JNIEnv *env, jclass jClass, jlong handle, jbyteArray subChars, jint length) {
-
+static jint setSubstitutionBytes(JNIEnv *env, jclass, jlong handle, jbyteArray subChars, jint length) {
     UConverter* cnv = (UConverter*) handle;
     UErrorCode errorCode = U_ZERO_ERROR;
-    if(cnv) {
+    if (cnv) {
         jbyte* u_subChars = reinterpret_cast<jbyte*>(env->GetPrimitiveArrayCritical(subChars, NULL));
-        if(u_subChars) {
-            char* mySubChars = new char[length];
-             toChars((UChar*)u_subChars,&mySubChars[0],length);
-             ucnv_setSubstChars(cnv,mySubChars, (char)length,&errorCode);
-             if(U_FAILURE(errorCode)) {
+        if (u_subChars) {
+            char mySubChars[length];
+            toChars((UChar*)u_subChars,&mySubChars[0],length);
+            ucnv_setSubstChars(cnv,mySubChars, (char)length,&errorCode);
+            if(U_FAILURE(errorCode)) {
                 env->ReleasePrimitiveArrayCritical(subChars,mySubChars,0);
                 return errorCode;
-             }
-             delete[] mySubChars;
-        }
-        else{   
+            }
+        } else{
            errorCode =  U_ILLEGAL_ARGUMENT_ERROR;
         }
         env->ReleasePrimitiveArrayCritical(subChars,u_subChars,0);
@@ -596,7 +434,7 @@
     }
     return U_MEMORY_ALLOCATION_ERROR;
 }
-static jint setSubstitutionChars(JNIEnv *env, jclass jClass, jlong handle, jcharArray subChars, jint length) {
+static jint setSubstitutionChars(JNIEnv *env, jclass, jlong handle, jcharArray subChars, jint length) {
 
     UErrorCode errorCode = U_ZERO_ERROR;
     UConverter* cnv = (UConverter*) handle;
@@ -647,7 +485,7 @@
     return;
 }
 
-static jboolean canEncode(JNIEnv *env, jclass jClass, jlong handle, jint codeUnit) {
+static jboolean canEncode(JNIEnv *env, jclass, jlong handle, jint codeUnit) {
     
     UErrorCode errorCode =U_ZERO_ERROR;
     UConverter* cnv = (UConverter*)handle;
@@ -672,311 +510,123 @@
     return (jboolean)FALSE;
 }
 
-
-static jboolean canDecode(JNIEnv *env, jclass jClass, jlong handle, jbyteArray source) {
-    
-    UErrorCode errorCode =U_ZERO_ERROR;
-    UConverter* cnv = (UConverter*)handle;
-    if(cnv) {
-        jint len = env->GetArrayLength(source);
-        jbyte* cSource =(jbyte*) env->GetPrimitiveArrayCritical(source, NULL);
-        if(cSource) {
-            const char* cSourceLimit = reinterpret_cast<const char*>(cSource+len);
-
-            /* Assume that we need at most twice the length of source */
-            UChar* target = (UChar*) malloc(sizeof(UChar)* (len<<1));
-            UChar* targetLimit = target + (len<<1);
-            if(target) {
-                ucnv_toUnicode(cnv,&target,targetLimit, (const char**)&cSource,
-                        cSourceLimit,NULL, TRUE,&errorCode);
-
-                if(U_SUCCESS(errorCode)) {
-                    free(target);
-                    env->ReleasePrimitiveArrayCritical(source,cSource,0);
-                    return (jboolean)TRUE;
-                }
-            }
-            free(target);
-        }
-        env->ReleasePrimitiveArrayCritical(source,cSource,0);
-    }
-    return (jboolean)FALSE;
-}
-
-static int32_t copyString(char* dest, int32_t destCapacity, int32_t startIndex,
-           const char* src, UErrorCode* status) {
-    int32_t srcLen = 0, i=0;
-    if(U_FAILURE(*status)) {
-        return 0;
-    }
-    if(dest == NULL || src == NULL || destCapacity < startIndex) { 
-        *status = U_ILLEGAL_ARGUMENT_ERROR;
-        return 0;
-    }
-    srcLen = strlen(src);
-    if(srcLen >= destCapacity) {
-        *status = U_BUFFER_OVERFLOW_ERROR;
-        return 0;
-    }
-    for(i=0; i < srcLen; i++) {
-        dest[startIndex++] = src[i];
-    }
-    /* null terminate the buffer */
-    dest[startIndex] = 0; /* no bounds check already made sure that we have enough room */
-    return startIndex;
-}
-
-static int32_t getJavaCanonicalName1(const char* icuCanonicalName,
-                     char* canonicalName, int32_t capacity, 
-                     UErrorCode* status) {
- /*
- If a charset listed in the IANA Charset Registry is supported by an implementation 
- of the Java platform then its canonical name must be the name listed in the registry. 
- Many charsets are given more than one name in the registry, in which case the registry 
- identifies one of the names as MIME-preferred. If a charset has more than one registry 
- name then its canonical name must be the MIME-preferred name and the other names in 
- the registry must be valid aliases. If a supported charset is not listed in the IANA 
- registry then its canonical name must begin with one of the strings "X-" or "x-".
+/*
+ * If a charset listed in the IANA Charset Registry is supported by an implementation
+ * of the Java platform then its canonical name must be the name listed in the registry.
+ * Many charsets are given more than one name in the registry, in which case the registry
+ * identifies one of the names as MIME-preferred. If a charset has more than one registry
+ * name then its canonical name must be the MIME-preferred name and the other names in
+ * the registry must be valid aliases. If a supported charset is not listed in the IANA
+ * registry then its canonical name must begin with one of the strings "X-" or "x-".
  */
-    int32_t retLen = 0;
+static jstring getJavaCanonicalName(JNIEnv *env, const char* icuCanonicalName) {
+    UErrorCode status = U_ZERO_ERROR;
+
+    // Check to see if this is a well-known MIME or IANA name.
     const char* cName = NULL;
-    /* find out the alias with MIME tag */
-    if((cName =ucnv_getStandardName(icuCanonicalName, "MIME", status)) !=  NULL) {
-        retLen = copyString(canonicalName, capacity, 0, cName, status);
-        /* find out the alias with IANA tag */
-    }else if((cName =ucnv_getStandardName(icuCanonicalName, "IANA", status)) !=  NULL) {
-        retLen = copyString(canonicalName, capacity, 0, cName, status);
-    }else {
-        /*  
-            check to see if an alias already exists with x- prefix, if yes then 
-            make that the canonical name
-        */
-        int32_t aliasNum = ucnv_countAliases(icuCanonicalName,status);
-        int32_t i=0;
-        const char* name;
-        for(i=0;i<aliasNum;i++) {
-            name = ucnv_getAlias(icuCanonicalName,(uint16_t)i, status);
-            if(name != NULL && name[0]=='x' && name[1]=='-') {
-                retLen = copyString(canonicalName, capacity, 0, name, status);
-                break;
-            }
-        }
-        /* last resort just append x- to any of the alias and 
-            make it the canonical name */
-        if(retLen == 0 && U_SUCCESS(*status)) {
-            name = ucnv_getStandardName(icuCanonicalName, "UTR22", status);
-            if(name == NULL && strchr(icuCanonicalName, ',')!= NULL) {
-                name = ucnv_getAlias(icuCanonicalName, 1, status);
-                if(*status == U_INDEX_OUTOFBOUNDS_ERROR) {
-                    *status = U_ZERO_ERROR;
-                }
-            }
-            /* if there is no UTR22 canonical name .. then just return itself*/
-            if(name == NULL) {                
-                name = icuCanonicalName;
-            }
-            if(capacity >= 2) {
-                strcpy(canonicalName,"x-");
-            }
-            retLen = copyString(canonicalName, capacity, 2, name, status);
+    if ((cName = ucnv_getStandardName(icuCanonicalName, "MIME", &status)) != NULL) {
+        return env->NewStringUTF(cName);
+    } else if ((cName = ucnv_getStandardName(icuCanonicalName, "IANA", &status)) != NULL) {
+        return env->NewStringUTF(cName);
+    }
+
+    // Check to see if an alias already exists with "x-" prefix, if yes then
+    // make that the canonical name.
+    int32_t aliasCount = ucnv_countAliases(icuCanonicalName, &status);
+    for (int i = 0; i < aliasCount; ++i) {
+        const char* name = ucnv_getAlias(icuCanonicalName, i, &status);
+        if (name != NULL && name[0] == 'x' && name[1] == '-') {
+            return env->NewStringUTF(name);
         }
     }
-    return retLen;
+
+    // As a last resort, prepend "x-" to any alias and make that the canonical name.
+    status = U_ZERO_ERROR;
+    const char* name = ucnv_getStandardName(icuCanonicalName, "UTR22", &status);
+    if (name == NULL && strchr(icuCanonicalName, ',') != NULL) {
+        name = ucnv_getAlias(icuCanonicalName, 1, &status);
+    }
+    // If there is no UTR22 canonical name then just return the original name.
+    if (name == NULL) {
+        name = icuCanonicalName;
+    }
+    UniquePtr<char[]> result(new char[2 + strlen(name) + 1]);
+    strcpy(&result[0], "x-");
+    strcat(&result[0], name);
+    return env->NewStringUTF(&result[0]);
 }
 
-static jobjectArray getAvailable(JNIEnv *env, jclass jClass) {
-   
-    jobjectArray ret;
-    int32_t i = 0;
+static jobjectArray getAvailableCharsetNames(JNIEnv *env, jclass) {
     int32_t num = ucnv_countAvailable();
-    UErrorCode error = U_ZERO_ERROR;
-    const char* name =NULL;
-    char canonicalName[256]={0};
-    ret= env->NewObjectArray(num, env->FindClass("java/lang/String"),
-            env->NewStringUTF(""));
+    jobjectArray result = env->NewObjectArray(num, env->FindClass("java/lang/String"), NULL);
+    for (int i = 0; i < num; ++i) {
+        const char* name = ucnv_getAvailableName(i);
+        jstring javaCanonicalName = getJavaCanonicalName(env, name);
+        env->SetObjectArrayElement(result, i, javaCanonicalName);
+        env->DeleteLocalRef(javaCanonicalName);
+    }
+    return result;
+}
 
-    for(i=0;i<num;i++) {
-        name = ucnv_getAvailableName(i);
-        getJavaCanonicalName1(name, canonicalName, 256, &error);   
-#if DEBUG
-        if(U_FAILURE(error)) {
-            printf("An error occurred retrieving index %i. Error: %s. \n", i, u_errorName(error));
+static jobjectArray getAliases(JNIEnv* env, const char* icuCanonicalName) {
+    // Get an upper bound on the number of aliases...
+    const char* myEncName = icuCanonicalName;
+    UErrorCode error = U_ZERO_ERROR;
+    int32_t aliasCount = ucnv_countAliases(myEncName, &error);
+    if (aliasCount == 0 && myEncName[0] == 'x' && myEncName[1] == '-') {
+        myEncName = myEncName + 2;
+        aliasCount = ucnv_countAliases(myEncName, &error);
+    }
+    if (!U_SUCCESS(error)) {
+        return NULL;
+    }
+
+    // Collect the aliases we want...
+    const char* aliasArray[aliasCount];
+    int actualAliasCount = 0;
+    for(int i = 0; i < aliasCount; ++i) {
+        const char* name = ucnv_getAlias(myEncName, (uint16_t) i, &error);
+        if (!U_SUCCESS(error)) {
+            return NULL;
         }
-
-        printf("canonical name for %s\n", canonicalName);
-#endif
-        // BEGIN android-changed
-        jstring canonName = env->NewStringUTF(canonicalName);
-        env->SetObjectArrayElement(ret,i,canonName);
-        env->DeleteLocalRef(canonName);
-        // END android-changed
-        /*printf("canonical name : %s  at %i\n", name,i); */
-        canonicalName[0]='\0';/* nul terminate */
-    }
-    return (ret);
-}
-
-static jint countAliases(JNIEnv *env, jclass jClass,jstring enc) {
-    
-    UErrorCode error = U_ZERO_ERROR;
-    jint num =0;
-    const char* encName = env->GetStringUTFChars(enc,NULL);
-    
-    if(encName) {
-        num = ucnv_countAliases(encName,&error);
-    }
-    
-    env->ReleaseStringUTFChars(enc,encName);
-
-    return num;
-}
-
-
-static jobjectArray getAliases(JNIEnv *env, jclass jClass, jstring enc) {
-
-    jobjectArray ret=NULL;
-    int32_t aliasNum = 0;
-    UErrorCode error = U_ZERO_ERROR;
-    const char* encName = env->GetStringUTFChars(enc,NULL);
-    int i=0;
-    int j=0;
-    const char* aliasArray[50];
-    // BEGIN android-removed
-    // int32_t utf16AliasNum = 0; 
-    // END android-removed
-
-    
-    if(encName) {
-        const char* myEncName = encName;
-        aliasNum = ucnv_countAliases(myEncName,&error);
-
-        // BEGIN android-removed
-        // /* special case for UTF-16. In java UTF-16 is always BE*/ 
-        // if(strcmp(myEncName, UTF_16BE)==0) { 
-        //     utf16AliasNum=ucnv_countAliases(UTF_16,&error); 
-        // }
-        // END android-removed
-
-        if(aliasNum==0 && encName[0] == 0x78 /*x*/ && encName[1]== 0x2d /*-*/) {
-            myEncName = encName+2;
-            aliasNum = ucnv_countAliases(myEncName,&error);
+        // TODO: why do we ignore these ones?
+        if (strchr(name, '+') == 0 && strchr(name, ',') == 0) {
+            aliasArray[actualAliasCount++]= name;
         }
-        if(U_SUCCESS(error)) {
-            for(i=0,j=0;i<aliasNum;i++) {
-                const char* name = ucnv_getAlias(myEncName,(uint16_t)i,&error);
-                if(strchr(name,'+')==0 && strchr(name,',')==0) {
-                    aliasArray[j++]= name;
-                }
-            }
-
-            // BEGIN android-removed
-            // if(utf16AliasNum>0) {
-            //     for(i=0;i<utf16AliasNum;i++) {
-            //         const char* name = ucnv_getAlias(UTF_16,(uint16_t)i,&error);
-            //         if(strchr(name,'+')==0 && strchr(name,',')==0) {
-            //             aliasArray[j++]= name;
-            //         }
-            //     }
-            // }
-            // END android-removed
-
-            ret =  (jobjectArray)env->NewObjectArray(j,
-                    env->FindClass("java/lang/String"), env->NewStringUTF(""));
-            for(;--j>=0;) {
-                 // BEGIN android-changed
-                 jstring alias = env->NewStringUTF(aliasArray[j]);
-                 env->SetObjectArrayElement(ret, j, alias);
-                 env->DeleteLocalRef(alias);
-                 // END android-changed
-            }
-        }            
     }
-    env->ReleaseStringUTFChars(enc,encName);
 
-    return (ret);
+    // Convert our C++ char*[] into a Java String[]...
+    jobjectArray result = env->NewObjectArray(actualAliasCount, env->FindClass("java/lang/String"), NULL);
+    for (int i = 0; i < actualAliasCount; ++i) {
+        jstring alias = env->NewStringUTF(aliasArray[i]);
+        env->SetObjectArrayElement(result, i, alias);
+        env->DeleteLocalRef(alias);
+    }
+    return result;
 }
 
-static jstring getCanonicalName(JNIEnv *env, jclass jClass,jstring enc) {
-
+static const char* getICUCanonicalName(const char* name) {
     UErrorCode error = U_ZERO_ERROR;
-    const char* encName = env->GetStringUTFChars(enc,NULL);
-    const char* canonicalName = "";
-    // BEGIN android-changed
-    jstring ret = NULL;
-    if(encName) {
-        canonicalName = ucnv_getAlias(encName,0,&error);
-        if(canonicalName !=NULL && strstr(canonicalName,",")!=0) {
-            canonicalName = ucnv_getAlias(canonicalName,1,&error);
-        }
-        ret = (env->NewStringUTF(canonicalName));
-        env->ReleaseStringUTFChars(enc,encName);
-    }
-    // END android-changed
-    return ret;
-}
-
-static jstring getICUCanonicalName(JNIEnv *env, jclass jClass, jstring enc) {
-
-    UErrorCode error = U_ZERO_ERROR;
-    const char* encName = env->GetStringUTFChars(enc,NULL);
     const char* canonicalName = NULL;
-    jstring ret = NULL;
-    if(encName) {
-        // BEGIN android-removed
-        // if(strcmp(encName,"UTF-16")==0) {
-        //     ret = (env->NewStringUTF(UTF_16BE));
-        // }else
-        // END android-removed
-        if((canonicalName = ucnv_getCanonicalName(encName, "MIME", &error))!=NULL) {
-            ret = (env->NewStringUTF(canonicalName));
-        }else if((canonicalName = ucnv_getCanonicalName(encName, "IANA", &error))!=NULL) {
-            ret = (env->NewStringUTF(canonicalName));
-        }else if((canonicalName = ucnv_getCanonicalName(encName, "", &error))!=NULL) {
-            ret = (env->NewStringUTF(canonicalName));
-        }else if((canonicalName =  ucnv_getAlias(encName, 0, &error)) != NULL) {
-            /* we have some aliases in the form x-blah .. match those first */
-            ret = (env->NewStringUTF(canonicalName));
-        }else if( ret ==NULL && strstr(encName, "x-") == encName) {
-            /* check if the converter can be opened with the encName given */
-            UConverter* conv = NULL;
-            error = U_ZERO_ERROR;
-            conv = ucnv_open(encName+2, &error);
-            if(conv!=NULL) {
-                ret = (env->NewStringUTF(encName+2));
-            }else{
-                /* unsupported encoding */
-                ret = (env->NewStringUTF(""));
-            }
+    if ((canonicalName = ucnv_getCanonicalName(name, "MIME", &error)) != NULL) {
+        return canonicalName;
+    } else if((canonicalName = ucnv_getCanonicalName(name, "IANA", &error)) != NULL) {
+        return canonicalName;
+    } else if((canonicalName = ucnv_getCanonicalName(name, "", &error)) != NULL) {
+        return canonicalName;
+    } else if((canonicalName =  ucnv_getAlias(name, 0, &error)) != NULL) {
+        /* we have some aliases in the form x-blah .. match those first */
+        return canonicalName;
+    } else if (strstr(name, "x-") == name) {
+        /* check if the converter can be opened with the name given */
+        error = U_ZERO_ERROR;
+        UConverter* conv = ucnv_open(name + 2, &error);
+        if (conv != NULL) {
             ucnv_close(conv);
-        }else{
-            /* unsupported encoding */
-           ret = (env->NewStringUTF(""));
+            return name + 2;
         }
     }
-    env->ReleaseStringUTFChars(enc,encName);
-    return ret;
-}
-
-static jstring getJavaCanonicalName2(JNIEnv *env, jclass jClass, jstring icuCanonName) {
- /*
- If a charset listed in the IANA Charset Registry is supported by an implementation 
- of the Java platform then its canonical name must be the name listed in the registry. 
- Many charsets are given more than one name in the registry, in which case the registry 
- identifies one of the names as MIME-preferred. If a charset has more than one registry 
- name then its canonical name must be the MIME-preferred name and the other names in 
- the registry must be valid aliases. If a supported charset is not listed in the IANA 
- registry then its canonical name must begin with one of the strings "X-" or "x-".
- */
-    UErrorCode error = U_ZERO_ERROR;
-    const char* icuCanonicalName = env->GetStringUTFChars(icuCanonName,NULL);
-    char cName[UCNV_MAX_CONVERTER_NAME_LENGTH] = {0};
-    jstring ret;
-    if(icuCanonicalName && icuCanonicalName[0] != 0) {
-        getJavaCanonicalName1(icuCanonicalName, cName, UCNV_MAX_CONVERTER_NAME_LENGTH, &error);
-    }
-    ret = (env->NewStringUTF(cName));
-    env->ReleaseStringUTFChars(icuCanonName,icuCanonicalName);
-    return ret;
+    return NULL;
 }
 
 #define SUBS_ARRAY_CAPACITY 256
@@ -1021,10 +671,11 @@
                     *status = U_ILLEGAL_ARGUMENT_ERROR;
                     return;
             }
-            if(realCB==NULL) {
+            if (realCB == NULL) {
                 *status = U_INTERNAL_PROGRAM_ERROR;
+            } else {
+                realCB(context, fromArgs, codeUnits, length, codePoint, reason, status);
             }
-            realCB(context, fromArgs, codeUnits, length, codePoint, reason, status);
         }
     }      
 }
@@ -1056,7 +707,7 @@
     }
 }
 
-static jint setCallbackEncode(JNIEnv *env, jclass jClass, jlong handle, jint onMalformedInput, jint onUnmappableInput, jbyteArray subChars, jint length) {
+static jint setCallbackEncode(JNIEnv *env, jclass, jlong handle, jint onMalformedInput, jint onUnmappableInput, jbyteArray subChars, jint length) {
 
     UConverter* conv = (UConverter*)handle;
     UErrorCode errorCode =U_ZERO_ERROR;
@@ -1176,15 +827,16 @@
                     *status = U_ILLEGAL_ARGUMENT_ERROR;
                     return;
             }
-            if(realCB==NULL) {
+            if (realCB == NULL) {
                 *status = U_INTERNAL_PROGRAM_ERROR;
+            } else {
+                realCB(context, args, codeUnits, length, reason, status);
             }
-            realCB(context, args, codeUnits, length, reason, status);
         }
     }      
 }
 
-static jint setCallbackDecode(JNIEnv *env, jclass jClass, jlong handle, jint onMalformedInput, jint onUnmappableInput, jcharArray subChars, jint length) {
+static jint setCallbackDecode(JNIEnv *env, jclass, jlong handle, jint onMalformedInput, jint onUnmappableInput, jcharArray subChars, jint length) {
     
     UConverter* conv = (UConverter*)handle;
     UErrorCode errorCode =U_ZERO_ERROR;
@@ -1234,132 +886,134 @@
     return U_ILLEGAL_ARGUMENT_ERROR;
 }
 
-static jlong safeClone(JNIEnv *env, jclass, jlong address) {
-    UConverter* source = reinterpret_cast<UConverter*>(static_cast<uintptr_t>(address));
-    if (!source) {
-        return NULL;
-    }
-    UErrorCode status = U_ZERO_ERROR;
-    jint bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
-    UConverter* conv = ucnv_safeClone(source, NULL, &bufferSize, &status);
-    icu4jni_error(env, status);
-    return reinterpret_cast<uintptr_t>(conv);
-}
-
-static jint getMaxCharsPerByte(JNIEnv *env, jclass jClass, jlong handle) {
+static jint getMaxCharsPerByte(JNIEnv *env, jclass, jlong handle) {
     /*
      * currently we know that max number of chars per byte is 2
      */
     return 2;
 }
 
-static jfloat getAveCharsPerByte(JNIEnv *env, jclass jClass, jlong handle) {
-    jfloat ret = 0;
-    ret = (jfloat)( 1/(jfloat)getMaxBytesPerChar(env, jClass, handle));
-    return ret;
+static jfloat getAveCharsPerByte(JNIEnv *env, jclass, jlong handle) {
+    return (1 / (jfloat) getMaxBytesPerChar(env, NULL, handle));
 }
 
-static void toUChars(const char* cs, UChar* us, int32_t length) {
-    char c;
-    while(length>0) {
-        c=*cs++;
-        *us++=(char)c;
-        --length;
-    }
-}
-
-static jbyteArray getSubstitutionBytes(JNIEnv *env, jclass jClass, jlong handle) {
-
+static jbyteArray getSubstitutionBytes(JNIEnv *env, jclass, jlong handle) {
     const UConverter * cnv = (const UConverter *) handle;
-    UErrorCode status = U_ZERO_ERROR;
-    char subBytes[10];
-    int8_t len =(char)10;
-    jbyteArray arr;
-    if(cnv) {
+    if (cnv) {
+        UErrorCode status = U_ZERO_ERROR;
+        char subBytes[10];
+        int8_t len =(char)10;
         ucnv_getSubstChars(cnv,subBytes,&len,&status);
         if(U_SUCCESS(status)) {
-            arr = (env->NewByteArray(len));
-            if(arr) {
+            jbyteArray arr = env->NewByteArray(len);
+            if (arr) {
                 env->SetByteArrayRegion(arr,0,len,(jbyte*)subBytes);
             }
             return arr;
         }
     }
-    return (env->NewByteArray(0));
+    return env->NewByteArray(0);
 }
 
-static jboolean contains( JNIEnv *env, jclass jClass, jlong handle1, jlong handle2) {
+static jboolean contains(JNIEnv* env, jclass, jlong handle1, jlong handle2) {
     UErrorCode status = U_ZERO_ERROR;
     const UConverter * cnv1 = (const UConverter *) handle1;
     const UConverter * cnv2 = (const UConverter *) handle2;
-    USet* set1;
-    USet* set2;
     UBool bRet = 0;
     
     if(cnv1 != NULL && cnv2 != NULL) {
-	    /* open charset 1 */
-        set1 = uset_open(1, 2);
+        /* open charset 1 */
+        USet* set1 = uset_open(1, 2);
         ucnv_getUnicodeSet(cnv1, set1, UCNV_ROUNDTRIP_SET, &status);
 
         if(U_SUCCESS(status)) {
             /* open charset 2 */
             status = U_ZERO_ERROR;
-            set2 = uset_open(1, 2);
+            USet* set2 = uset_open(1, 2);
             ucnv_getUnicodeSet(cnv2, set2, UCNV_ROUNDTRIP_SET, &status);
 
             /* contains?      */
             if(U_SUCCESS(status)) {
                 bRet = uset_containsAll(set1, set2);
-	            uset_close(set2);
+                uset_close(set2);
             }
             uset_close(set1);
         }
     }
-	return bRet;
+    return bRet;
 }
 
-/*
- * JNI registration
- */
+static jobject charsetForName(JNIEnv* env, jclass, jstring charsetName) {
+    ScopedUtfChars charsetNameChars(env, charsetName);
+    if (!charsetNameChars.data()) {
+        return NULL;
+    }
+    // Get ICU's canonical name for this charset.
+    const char* icuCanonicalName = getICUCanonicalName(charsetNameChars.data());
+    if (icuCanonicalName == NULL) {
+        return NULL;
+    }
+    // Get Java's canonical name for this charset.
+    jstring javaCanonicalName = getJavaCanonicalName(env, icuCanonicalName);
+    if (env->ExceptionOccurred()) {
+        return NULL;
+    }
+
+    // Check that this charset is supported.
+    // ICU doesn't offer any "isSupported", so we just open and immediately close.
+    // We ignore the UErrorCode because ucnv_open returning NULL is all the information we need.
+    UErrorCode dummy = U_ZERO_ERROR;
+    UConverter* conv = ucnv_open(icuCanonicalName, &dummy);
+    if (conv == NULL) {
+        return NULL;
+    }
+    ucnv_close(conv);
+
+    // Get the aliases for this charset.
+    jobjectArray aliases = getAliases(env, icuCanonicalName);
+    if (env->ExceptionOccurred()) {
+        return NULL;
+    }
+
+    // Construct the CharsetICU object.
+    jclass charsetClass = env->FindClass("com/ibm/icu4jni/charset/CharsetICU");
+    if (env->ExceptionOccurred()) {
+        return NULL;
+    }
+    jmethodID charsetConstructor = env->GetMethodID(charsetClass, "<init>",
+            "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
+    if (env->ExceptionOccurred()) {
+        return NULL;
+    }
+    return env->NewObject(charsetClass, charsetConstructor,
+            javaCanonicalName, env->NewStringUTF(icuCanonicalName), aliases);
+}
+
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "convertByteToChar", "(J[BI[CI[IZ)I", (void*) convertByteToChar },
+    { "canEncode", "(JI)Z", (void*) canEncode },
+    { "charsetForName", "(Ljava/lang/String;)Ljava/nio/charset/Charset;", (void*) charsetForName },
+    { "closeConverter", "(J)V", (void*) closeConverter },
+    { "contains", "(JJ)Z", (void*) contains },
     { "decode", "(J[BI[CI[IZ)I", (void*) decode },
-    { "convertCharToByte", "(J[CI[BI[IZ)I", (void*) convertCharToByte },
     { "encode", "(J[CI[BI[IZ)I", (void*) encode },
-    { "flushCharToByte", "(J[BI[I)I", (void*) flushCharToByte },
     { "flushByteToChar", "(J[CI[I)I", (void*) flushByteToChar },
+    { "flushCharToByte", "(J[BI[I)I", (void*) flushCharToByte },
+    { "getAvailableCharsetNames", "()[Ljava/lang/String;", (void*) getAvailableCharsetNames },
+    { "getAveBytesPerChar", "(J)F", (void*) getAveBytesPerChar },
+    { "getAveCharsPerByte", "(J)F", (void*) getAveCharsPerByte },
+    { "getMaxBytesPerChar", "(J)I", (void*) getMaxBytesPerChar },
+    { "getMaxCharsPerByte", "(J)I", (void*) getMaxCharsPerByte },
+    { "getMinBytesPerChar", "(J)I", (void*) getMinBytesPerChar },
+    { "getSubstitutionBytes", "(J)[B", (void*) getSubstitutionBytes },
     { "openConverter", "(Ljava/lang/String;)J", (void*) openConverter },
     { "resetByteToChar", "(J)V", (void*) resetByteToChar },
     { "resetCharToByte", "(J)V", (void*) resetCharToByte },
-    { "closeConverter", "(J)V", (void*) closeConverter },
-    { "setSubstitutionChars", "(J[CI)I", (void*) setSubstitutionChars },
-    { "setSubstitutionBytes", "(J[BI)I", (void*) setSubstitutionBytes },
-    { "setSubstitutionModeCharToByte", "(JZ)I", (void*) setSubstitutionModeCharToByte },
-    { "setSubstitutionModeByteToChar", "(JZ)I", (void*) setSubstitutionModeByteToChar },
-    { "countInvalidBytes", "(J[I)I", (void*) countInvalidBytes },
-    { "countInvalidChars", "(J[I)I", (void*) countInvalidChars },
-    { "getMaxBytesPerChar", "(J)I", (void*) getMaxBytesPerChar },
-    { "getMinBytesPerChar", "(J)I", (void*) getMinBytesPerChar },
-    { "getAveBytesPerChar", "(J)F", (void*) getAveBytesPerChar },
-    { "getMaxCharsPerByte", "(J)I", (void*) getMaxCharsPerByte },
-    { "getAveCharsPerByte", "(J)F", (void*) getAveCharsPerByte },
-    { "contains", "(JJ)Z", (void*) contains },
-    { "getSubstitutionBytes", "(J)[B", (void*) getSubstitutionBytes },
-    { "canEncode", "(JI)Z", (void*) canEncode },
-    { "canDecode", "(J[B)Z", (void*) canDecode },
-    { "getAvailable", "()[Ljava/lang/String;", (void*) getAvailable },
-    { "countAliases", "(Ljava/lang/String;)I", (void*) countAliases },
-    { "getAliases", "(Ljava/lang/String;)[Ljava/lang/String;", (void*) getAliases },
-    { "getCanonicalName", "(Ljava/lang/String;)Ljava/lang/String;", (void*) getCanonicalName },
-    { "getICUCanonicalName", "(Ljava/lang/String;)Ljava/lang/String;", (void*) getICUCanonicalName },
-    { "getJavaCanonicalName", "(Ljava/lang/String;)Ljava/lang/String;", (void*) getJavaCanonicalName2 },
     { "setCallbackDecode", "(JII[CI)I", (void*) setCallbackDecode },
     { "setCallbackEncode", "(JII[BI)I", (void*) setCallbackEncode },
-    { "safeClone", "(J)J", (void*) safeClone }
+    { "setSubstitutionBytes", "(J[BI)I", (void*) setSubstitutionBytes },
+    { "setSubstitutionChars", "(J[CI)I", (void*) setSubstitutionChars },
 };
-
-int register_com_ibm_icu4jni_converters_NativeConverter(JNIEnv *_env) {
-    return jniRegisterNativeMethods(_env, "com/ibm/icu4jni/charset/NativeConverter",
+int register_com_ibm_icu4jni_converters_NativeConverter(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/charset/NativeConverter",
                 gMethods, NELEM(gMethods));
 }
diff --git a/icu/src/main/native/NativeDecimalFormat.cpp b/icu/src/main/native/NativeDecimalFormat.cpp
index 413ffdd..8f39a39 100644
--- a/icu/src/main/native/NativeDecimalFormat.cpp
+++ b/icu/src/main/native/NativeDecimalFormat.cpp
@@ -15,8 +15,8 @@
  */
 
 #define LOG_TAG "NativeDecimalFormat"
+
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 #include "cutils/log.h"
 #include "unicode/unum.h"
 #include "unicode/numfmt.h"
@@ -103,10 +103,16 @@
     return static_cast<jint>(reinterpret_cast<uintptr_t>(fmt));
 }
 
-static void closeDecimalFormatImpl(JNIEnv *env, jclass clazz, jint addr) {
+static void closeDecimalFormatImpl(JNIEnv* env, jclass, jint addr) {
     delete toDecimalFormat(addr);
 }
 
+static void setRoundingMode(JNIEnv* env, jclass, jint addr, jint mode, jdouble increment) {
+    DecimalFormat* fmt = toDecimalFormat(addr);
+    fmt->setRoundingMode(static_cast<DecimalFormat::ERoundingMode>(mode));
+    fmt->setRoundingIncrement(increment);
+}
+
 static void setSymbol(JNIEnv* env, jclass, jint addr, jint symbol, jstring s) {
     const UChar* chars = env->GetStringChars(s, NULL);
     const int32_t charCount = env->GetStringLength(s);
@@ -579,7 +585,6 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     {"applyPatternImpl", "(IZLjava/lang/String;)V", (void*) applyPatternImpl},
     {"cloneDecimalFormatImpl", "(I)I", (void*) cloneDecimalFormatImpl},
     {"closeDecimalFormatImpl", "(I)V", (void*) closeDecimalFormatImpl},
@@ -593,11 +598,11 @@
     {"setAttribute", "(III)V", (void*) setAttribute},
     {"setDecimalFormatSymbols", "(ILjava/lang/String;CCCLjava/lang/String;Ljava/lang/String;CCLjava/lang/String;CCCC)V", (void*) setDecimalFormatSymbols},
     {"setSymbol", "(IILjava/lang/String;)V", (void*) setSymbol},
+    {"setRoundingMode", "(IID)V", (void*) setRoundingMode},
     {"setTextAttribute", "(IILjava/lang/String;)V", (void*) setTextAttribute},
     {"toPatternImpl", "(IZ)Ljava/lang/String;", (void*) toPatternImpl},
 };
 int register_com_ibm_icu4jni_text_NativeDecimalFormat(JNIEnv* env) {
-    return jniRegisterNativeMethods(env,
-            "com/ibm/icu4jni/text/NativeDecimalFormat", gMethods,
+    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeDecimalFormat", gMethods,
             NELEM(gMethods));
 }
diff --git a/icu/src/main/native/NativeIDN.cpp b/icu/src/main/native/NativeIDN.cpp
new file mode 100644
index 0000000..e8052fc
--- /dev/null
+++ b/icu/src/main/native/NativeIDN.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NativeIDN"
+
+#include "ErrorCode.h"
+#include "JNIHelp.h"
+#include "ScopedJavaUnicodeString.h"
+#include "unicode/uidna.h"
+
+static bool isLabelSeparator(const UChar ch) {
+    switch (ch) {
+    case 0x3002: // ideographic full stop
+    case 0xff0e: // fullwidth full stop
+    case 0xff61: // halfwidth ideographic full stop
+        return true;
+    default:
+        return false;
+    }
+}
+
+static jstring convertImpl(JNIEnv* env, jclass, jstring s, jint flags, jboolean toAscii) {
+    ScopedJavaUnicodeString sus(env, s);
+    const UChar* src = sus.unicodeString().getBuffer();
+    const size_t srcLength = sus.unicodeString().length();
+    UChar dst[256];
+    UErrorCode status = U_ZERO_ERROR;
+    size_t resultLength = toAscii
+            ? uidna_IDNToASCII(src, srcLength, &dst[0], sizeof(dst), flags, NULL, &status)
+            : uidna_IDNToUnicode(src, srcLength, &dst[0], sizeof(dst), flags, NULL, &status);
+    if (U_FAILURE(status)) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", u_errorName(status));
+        return NULL;
+    }
+    if (!toAscii) {
+        // ICU only translates separators to ASCII for toASCII.
+        // Java expects the translation for toUnicode too.
+        // We may as well do this here, while the string is still mutable.
+        for (size_t i = 0; i < resultLength; ++i) {
+            if (isLabelSeparator(dst[i])) {
+                dst[i] = '.';
+            }
+        }
+    }
+    return env->NewString(&dst[0], resultLength);
+}
+
+static JNINativeMethod gMethods[] = {
+    {"convertImpl", "(Ljava/lang/String;IZ)Ljava/lang/String;", (void*) convertImpl},
+};
+int register_com_ibm_icu4jni_text_NativeIDN(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeIDN", gMethods, NELEM(gMethods));
+}
diff --git a/icu/src/main/native/NativeNormalizer.cpp b/icu/src/main/native/NativeNormalizer.cpp
index b09b26e..257cf9b 100644
--- a/icu/src/main/native/NativeNormalizer.cpp
+++ b/icu/src/main/native/NativeNormalizer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "NativeNormalizer"
+
 #include "ErrorCode.h"
 #include "JNIHelp.h"
 #include "ScopedJavaUnicodeString.h"
@@ -39,11 +41,10 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     {"normalizeImpl", "(Ljava/lang/String;I)Ljava/lang/String;", (void*) normalizeImpl},
     {"isNormalizedImpl", "(Ljava/lang/String;I)Z", (void*) isNormalizedImpl},
 };
-extern "C" int register_com_ibm_icu4jni_text_NativeNormalizer(JNIEnv* env) {
-    return jniRegisterNativeMethods(env,
-            "com/ibm/icu4jni/text/NativeNormalizer", gMethods, NELEM(gMethods));
+int register_com_ibm_icu4jni_text_NativeNormalizer(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/ibm/icu4jni/text/NativeNormalizer",
+            gMethods, NELEM(gMethods));
 }
diff --git a/icu/src/main/native/NativeRegEx.cpp b/icu/src/main/native/NativeRegEx.cpp
index 7b3cafc..511f1e4 100644
--- a/icu/src/main/native/NativeRegEx.cpp
+++ b/icu/src/main/native/NativeRegEx.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "AndroidSystemNatives.h"
+#define LOG_TAG "NativeRegEx"
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/icu/src/main/native/RuleBasedNumberFormat.cpp b/icu/src/main/native/RuleBasedNumberFormat.cpp
deleted file mode 100644
index c7486e1..0000000
--- a/icu/src/main/native/RuleBasedNumberFormat.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- 
-#include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
-#include "unicode/numfmt.h"
-#include "unicode/rbnf.h"
-#include "unicode/fmtable.h"
-#include "unicode/ustring.h"
-#include "unicode/locid.h"
-#include "ErrorCode.h"
-#include <stdlib.h>
-#include <string.h>
-
-static jint openRBNFImpl1(JNIEnv* env, jclass clazz, 
-        jint type, jstring locale) {
-
-    // LOGI("ENTER openRBNFImpl1");
-
-    // the errorcode returned by unum_open
-    UErrorCode status = U_ZERO_ERROR;
-
-    // prepare the locale string for the call to unum_open
-    const char *localeChars = env->GetStringUTFChars(locale, NULL);
-
-    URBNFRuleSetTag style;
-    if(type == 0) {
-        style = URBNF_SPELLOUT;
-    } else if(type == 1) {
-        style = URBNF_ORDINAL;
-    } else if(type == 2) {
-        style = URBNF_DURATION;
-    } else if(type == 3) {
-        style = URBNF_COUNT;
-    } else {
-        icu4jni_error(env, U_ILLEGAL_ARGUMENT_ERROR);
-    }
-    
-    Locale loc = Locale::createFromName(localeChars);
-
-    // open a default type number format
-    RuleBasedNumberFormat *fmt = new RuleBasedNumberFormat(style, loc, status);
-
-    // release the allocated strings
-    env->ReleaseStringUTFChars(locale, localeChars);
-
-    // check for an error
-    if (icu4jni_error(env, status) != FALSE) {
-        return 0;
-    }
-
-    // return the handle to the number format
-    return (long) fmt;
-
-}
-
-static jint openRBNFImpl2(JNIEnv* env, jclass clazz, 
-        jstring rule, jstring locale) {
-
-    // LOGI("ENTER openRBNFImpl2");
-
-    // the errorcode returned by unum_open
-    UErrorCode status = U_ZERO_ERROR;
-
-    // prepare the pattern string for the call to unum_open
-    const UChar *ruleChars = env->GetStringChars(rule, NULL);
-    int ruleLen = env->GetStringLength(rule);
-
-    // prepare the locale string for the call to unum_open
-    const char *localeChars = env->GetStringUTFChars(locale, NULL);
-
-    // open a rule based number format
-    UNumberFormat *fmt = unum_open(UNUM_PATTERN_RULEBASED, ruleChars, ruleLen, 
-                localeChars, NULL, &status);
-
-    // release the allocated strings
-    env->ReleaseStringChars(rule, ruleChars);
-    env->ReleaseStringUTFChars(locale, localeChars);
-
-    // check for an error
-    if (icu4jni_error(env, status) != FALSE) {
-        return 0;
-    }
-
-    // return the handle to the number format
-    return (long) fmt;
-
-}
-
-static void closeRBNFImpl(JNIEnv *env, jclass clazz, jint addr) {
-
-    // LOGI("ENTER closeRBNFImpl");
-
-    // get the pointer to the number format    
-    RuleBasedNumberFormat *fmt = (RuleBasedNumberFormat *)(int)addr;
-
-    // close this number format
-    delete fmt;
-}
-
-static jstring formatLongRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jlong value, 
-        jobject field, jstring fieldType, jobject attributes) {
-
-    // LOGI("ENTER formatLongRBNFImpl");
-
-    const char * fieldPositionClassName = "java/text/FieldPosition";
-    const char * stringBufferClassName = "java/lang/StringBuffer";
-    jclass fieldPositionClass = env->FindClass(fieldPositionClassName);
-    jclass stringBufferClass = env->FindClass(stringBufferClassName);
-    jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass, 
-            "setBeginIndex", "(I)V");
-    jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass, 
-            "setEndIndex", "(I)V");
-    jmethodID appendMethodID = env->GetMethodID(stringBufferClass, 
-            "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
-
-    const char * fieldName = NULL;
-
-    if(fieldType != NULL) {
-        fieldName = env->GetStringUTFChars(fieldType, NULL);
-    }
-
-    uint32_t reslenneeded;
-    int64_t val = value;
-    UChar *result = NULL;
-
-    FieldPosition fp;
-    fp.setField(FieldPosition::DONT_CARE);
-
-    UErrorCode status = U_ZERO_ERROR;
-
-    RuleBasedNumberFormat *fmt = (RuleBasedNumberFormat *)(int)addr;
-
-    UnicodeString res;
-
-    fmt->format(val, res, fp);
-
-    reslenneeded = res.extract(NULL, 0, status);
-
-    if(status==U_BUFFER_OVERFLOW_ERROR) {
-        status=U_ZERO_ERROR;
-
-        result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));    
-
-        res.extract(result, reslenneeded + 1, status);
-    }
-    if (icu4jni_error(env, status) != FALSE) {
-        free(result);
-        return NULL;
-    }
-
-    if(fieldType != NULL) {
-        env->ReleaseStringUTFChars(fieldType, fieldName);
-    }
-
-    jstring resulting = env->NewString(result, reslenneeded);
-
-    free(result);
-
-    return resulting;
-}
-
-static jstring formatDoubleRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jdouble value, 
-        jobject field, jstring fieldType, jobject attributes) {
-
-    // LOGI("ENTER formatDoubleRBNFImpl");
-
-    const char * fieldPositionClassName = "java/text/FieldPosition";
-    const char * stringBufferClassName = "java/lang/StringBuffer";
-    jclass fieldPositionClass = env->FindClass(fieldPositionClassName);
-    jclass stringBufferClass = env->FindClass(stringBufferClassName);
-    jmethodID setBeginIndexMethodID = env->GetMethodID(fieldPositionClass, 
-            "setBeginIndex", "(I)V");
-    jmethodID setEndIndexMethodID = env->GetMethodID(fieldPositionClass, 
-            "setEndIndex", "(I)V");
-    jmethodID appendMethodID = env->GetMethodID(stringBufferClass, 
-            "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
-
-    const char * fieldName = NULL;
-
-    if(fieldType != NULL) {
-        fieldName = env->GetStringUTFChars(fieldType, NULL);
-    }
-
-    uint32_t reslenneeded;
-    double val = value;
-    UChar *result = NULL;
-
-    FieldPosition fp;
-    fp.setField(FieldPosition::DONT_CARE);
-
-    UErrorCode status = U_ZERO_ERROR;
-
-    RuleBasedNumberFormat *fmt = (RuleBasedNumberFormat *)(int)addr;
-
-    UnicodeString res;
-
-    fmt->format(val, res, fp);
-
-    reslenneeded = res.extract(NULL, 0, status);
-
-    if(status==U_BUFFER_OVERFLOW_ERROR) {
-        status=U_ZERO_ERROR;
-
-        result = (UChar*)malloc(sizeof(UChar) * (reslenneeded + 1));    
-
-        res.extract(result, reslenneeded + 1, status);
-    }
-    if (icu4jni_error(env, status) != FALSE) {
-        free(result);
-        return NULL;
-    }
-
-    if(fieldType != NULL) {
-        env->ReleaseStringUTFChars(fieldType, fieldName);
-    }
-
-    jstring resulting = env->NewString(result, reslenneeded);
-
-    free(result);
-
-    return resulting;
-}
-
-static jobject parseRBNFImpl(JNIEnv *env, jclass clazz, jint addr, jstring text, 
-        jobject position, jboolean lenient) {
-
-    // LOGI("ENTER parseRBNFImpl");
-    
-    // TODO: cache these?
-    jclass parsePositionClass = env->FindClass("java/text/ParsePosition");
-    jclass longClass =  env->FindClass("java/lang/Long");
-    jclass doubleClass =  env->FindClass("java/lang/Double");
-
-    jmethodID getIndexMethodID = env->GetMethodID(parsePositionClass, 
-            "getIndex", "()I");
-    jmethodID setIndexMethodID = env->GetMethodID(parsePositionClass, 
-            "setIndex", "(I)V");
-    jmethodID setErrorIndexMethodID = env->GetMethodID(parsePositionClass, 
-            "setErrorIndex", "(I)V");
-
-    jmethodID longInitMethodID = env->GetMethodID(longClass, "<init>", "(J)V");
-    jmethodID dblInitMethodID = env->GetMethodID(doubleClass, "<init>", "(D)V");
-
-    // make sure the ParsePosition is valid. Actually icu4c would parse a number 
-    // correctly even if the parsePosition is set to -1, but since the RI fails 
-    // for that case we have to fail too
-    int parsePos = env->CallIntMethod(position, getIndexMethodID, NULL);
-    const int strlength = env->GetStringLength(text);
-    if(parsePos < 0 || parsePos > strlength) {
-        return NULL;
-    }
-    
-    Formattable res;
-    
-    jchar *str = (UChar *)env->GetStringChars(text, NULL);
-    
-    const UnicodeString src((UChar*)str, strlength, strlength);
-    ParsePosition pp;
-    
-    pp.setIndex(parsePos);
-    
-    UNumberFormat *fmt = (UNumberFormat *)(int)addr;
-    if(lenient) {
-        unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_TRUE);
-    }
-    
-    ((const NumberFormat*)fmt)->parse(src, res, pp);
-
-    if(lenient) {
-        unum_setAttribute(fmt, UNUM_LENIENT_PARSE, JNI_FALSE);
-    }
-    
-    env->ReleaseStringChars(text, str);
-
-    if(pp.getErrorIndex() == -1) {
-        parsePos = pp.getIndex();
-    } else {
-        env->CallVoidMethod(position, setErrorIndexMethodID, 
-                (jint) pp.getErrorIndex());        
-        return NULL;
-    }
-
-    Formattable::Type numType = res.getType();
-    if (numType == Formattable::kDouble) {
-        double resultDouble = res.getDouble();
-        env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
-        return env->NewObject(doubleClass, dblInitMethodID,
-                              (jdouble) resultDouble);
-    } else if (numType == Formattable::kLong) {
-        long resultLong = res.getLong();
-        env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
-        return env->NewObject(longClass, longInitMethodID, (jlong) resultLong);
-    } else if (numType == Formattable::kInt64) {
-        int64_t resultInt64 = res.getInt64();
-        env->CallVoidMethod(position, setIndexMethodID, (jint) parsePos);
-        return env->NewObject(longClass, longInitMethodID, (jlong) resultInt64);
-    } else {
-        return NULL;
-    }
-}
-
-static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    {"openRBNFImpl", "(ILjava/lang/String;)I", (void*) openRBNFImpl1},
-    {"openRBNFImpl", "(Ljava/lang/String;Ljava/lang/String;)I", 
-            (void*) openRBNFImpl2},
-    {"closeRBNFImpl", "(I)V", (void*) closeRBNFImpl},
-    {"formatRBNFImpl", 
-            "(IJLjava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;)Ljava/lang/String;", 
-            (void*) formatLongRBNFImpl},
-    {"formatRBNFImpl",
-            "(IDLjava/text/FieldPosition;Ljava/lang/String;Ljava/lang/StringBuffer;)Ljava/lang/String;", 
-            (void*) formatDoubleRBNFImpl},
-    {"parseRBNFImpl", 
-            "(ILjava/lang/String;Ljava/text/ParsePosition;Z)Ljava/lang/Number;", 
-            (void*) parseRBNFImpl},
-};
-int register_com_ibm_icu4jni_text_NativeRBNF(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, 
-            "com/ibm/icu4jni/text/RuleBasedNumberFormat", gMethods, 
-            NELEM(gMethods));
-}
diff --git a/icu/src/main/native/ScopedJavaUnicodeString.h b/icu/src/main/native/ScopedJavaUnicodeString.h
index 44952b4..b108a6b 100644
--- a/icu/src/main/native/ScopedJavaUnicodeString.h
+++ b/icu/src/main/native/ScopedJavaUnicodeString.h
@@ -22,9 +22,7 @@
 
 // A smart pointer that provides access to an ICU UnicodeString given a JNI
 // jstring. We give ICU a direct pointer to the characters on the Java heap.
-// It's clever enough to copy-on-write if necessary, but we only provide
-// const UnicodeString access anyway because attempted write access seems
-// likely to be an error.
+// It's clever enough to copy-on-write if necessary.
 class ScopedJavaUnicodeString {
 public:
     ScopedJavaUnicodeString(JNIEnv* env, jstring s) : mEnv(env), mString(s) {
@@ -37,7 +35,11 @@
         mEnv->ReleaseStringChars(mString, mChars);
     }
 
-    const UnicodeString& unicodeString() {
+    const UnicodeString& unicodeString() const {
+        return mUnicodeString;
+    }
+
+    UnicodeString& unicodeString() {
         return mUnicodeString;
     }
 
@@ -46,6 +48,10 @@
     jstring mString;
     const UChar* mChars;
     UnicodeString mUnicodeString;
+
+    // Disallow copy and assignment.
+    ScopedJavaUnicodeString(const ScopedJavaUnicodeString&);
+    void operator=(const ScopedJavaUnicodeString&);
 };
 
 #endif  // SCOPED_JAVA_UNICODE_STRING_H_included
diff --git a/icu/src/main/native/UCharacter.cpp b/icu/src/main/native/UCharacter.cpp
index 3fd8151..1c5af48 100644
--- a/icu/src/main/native/UCharacter.cpp
+++ b/icu/src/main/native/UCharacter.cpp
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2006 The Android Open Source Project
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,8 +14,12 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "UCharacter"
+
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
+#include "ScopedJavaUnicodeString.h"
+#include "ScopedUtfChars.h"
+#include "unicode/locid.h"
 #include "unicode/uchar.h"
 #include <math.h>
 #include <stdlib.h>
@@ -37,12 +41,12 @@
 }
 
 static jint getNumericValueImpl(JNIEnv*, jclass, jint codePoint){
-    // The letters A-Z in their uppercase ('\u0041' through '\u005A'), 
-    //                          lowercase ('\u0061' through '\u007A'), 
-    //             and full width variant ('\uFF21' through '\uFF3A' 
-    //                                 and '\uFF41' through '\uFF5A') forms 
-    // have numeric values from 10 through 35. This is independent of the 
-    // Unicode specification, which does not assign numeric values to these 
+    // The letters A-Z in their uppercase ('\u0041' through '\u005A'),
+    //                          lowercase ('\u0061' through '\u007A'),
+    //             and full width variant ('\uFF21' through '\uFF3A'
+    //                                 and '\uFF41' through '\uFF5A') forms
+    // have numeric values from 10 through 35. This is independent of the
+    // Unicode specification, which does not assign numeric values to these
     // char values.
     if (codePoint >= 0x41 && codePoint <= 0x5A) {
         return codePoint - 0x37;
@@ -66,15 +70,15 @@
     }
 
     return result;
-} 
-    
+}
+
 static jboolean isDefinedImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isdefined(codePoint);
-} 
+}
 
 static jboolean isDigitImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isdigit(codePoint);
-} 
+}
 
 static jboolean isIdentifierIgnorableImpl(JNIEnv*, jclass, jint codePoint) {
     // Java also returns TRUE for U+0085 Next Line (it omits U+0085 from whitespace ISO controls)
@@ -82,31 +86,31 @@
         return JNI_TRUE;
     }
     return u_isIDIgnorable(codePoint);
-} 
+}
 
 static jboolean isLetterImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isalpha(codePoint);
-} 
+}
 
 static jboolean isLetterOrDigitImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isalnum(codePoint);
-} 
+}
 
 static jboolean isSpaceCharImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isJavaSpaceChar(codePoint);
-} 
+}
 
 static jboolean isTitleCaseImpl(JNIEnv*, jclass, jint codePoint) {
     return u_istitle(codePoint);
-} 
+}
 
 static jboolean isUnicodeIdentifierPartImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isIDPart(codePoint);
-} 
+}
 
 static jboolean isUnicodeIdentifierStartImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isIDStart(codePoint);
-} 
+}
 
 static jboolean isWhitespaceImpl(JNIEnv*, jclass, jint codePoint) {
     // Java omits U+0085
@@ -114,27 +118,43 @@
         return JNI_FALSE;
     }
     return u_isWhitespace(codePoint);
-} 
+}
 
 static jint toLowerCaseImpl(JNIEnv*, jclass, jint codePoint) {
     return u_tolower(codePoint);
-} 
+}
 
 static jint toTitleCaseImpl(JNIEnv*, jclass, jint codePoint) {
     return u_totitle(codePoint);
-} 
+}
 
 static jint toUpperCaseImpl(JNIEnv*, jclass, jint codePoint) {
     return u_toupper(codePoint);
-} 
+}
+
+static jstring toLowerCaseStringImpl(JNIEnv* env, jclass, jstring javaString, jstring localeName) {
+    ScopedJavaUnicodeString scopedString(env, javaString);
+    UnicodeString& s(scopedString.unicodeString());
+    UnicodeString original(s);
+    s.toLower(Locale::createFromName(ScopedUtfChars(env, localeName).data()));
+    return s == original ? javaString : env->NewString(s.getBuffer(), s.length());
+}
+
+static jstring toUpperCaseStringImpl(JNIEnv* env, jclass, jstring javaString, jstring localeName) {
+    ScopedJavaUnicodeString scopedString(env, javaString);
+    UnicodeString& s(scopedString.unicodeString());
+    UnicodeString original(s);
+    s.toUpper(Locale::createFromName(ScopedUtfChars(env, localeName).data()));
+    return s == original ? javaString : env->NewString(s.getBuffer(), s.length());
+}
 
 static jboolean isUpperCaseImpl(JNIEnv*, jclass, jint codePoint) {
     return u_isupper(codePoint);
-} 
+}
 
 static jboolean isLowerCaseImpl(JNIEnv*, jclass, jint codePoint) {
     return u_islower(codePoint);
-} 
+}
 
 static int forNameImpl(JNIEnv* env, jclass, jstring blockName) {
     if (blockName == NULL) {
@@ -151,11 +171,7 @@
     return ublock_getCode(codePoint);
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "digit", "(II)I", (void*) digitImpl },
     { "forName", "(Ljava/lang/String;)I", (void*) forNameImpl },
     { "getDirectionality", "(I)B", (void*) getDirectionalityImpl },
@@ -178,8 +194,9 @@
     { "toLowerCase", "(I)I", (void*) toLowerCaseImpl },
     { "toTitleCase", "(I)I", (void*) toTitleCaseImpl },
     { "toUpperCase", "(I)I", (void*) toUpperCaseImpl },
-}; 
-
+    { "toLowerCase", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) toLowerCaseStringImpl },
+    { "toUpperCase", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) toUpperCaseStringImpl },
+};
 int register_com_ibm_icu4jni_lang_UCharacter(JNIEnv* env) {
     return jniRegisterNativeMethods(env, "com/ibm/icu4jni/lang/UCharacter",
                 gMethods, NELEM(gMethods));
diff --git a/icu/src/main/native/sub.mk b/icu/src/main/native/sub.mk
index 41260cf..599c102 100644
--- a/icu/src/main/native/sub.mk
+++ b/icu/src/main/native/sub.mk
@@ -5,14 +5,14 @@
 LOCAL_SRC_FILES := \
 	BidiWrapper.cpp \
 	ErrorCode.cpp \
+	ICU.cpp \
 	NativeBreakIterator.cpp \
 	NativeCollation.cpp \
 	NativeConverter.cpp \
 	NativeDecimalFormat.cpp \
+	NativeIDN.cpp \
 	NativeNormalizer.cpp \
 	NativeRegEx.cpp \
-	RuleBasedNumberFormat.cpp \
-	Resources.cpp \
 	UCharacter.cpp
 
 LOCAL_C_INCLUDES += \
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java b/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
deleted file mode 100644
index 4112d0b..0000000
--- a/icu/src/test/java/com/ibm/icu4jni/util/ResourcesTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ibm.icu4jni.util;
-
-public class ResourcesTest extends junit.framework.TestCase {
-    public void test_getISOLanguages() throws Exception {
-        // Check that corrupting our array doesn't affect other callers.
-        assertNotNull(Resources.getISOLanguages()[0]);
-        Resources.getISOLanguages()[0] = null;
-        assertNotNull(Resources.getISOLanguages()[0]);
-    }
-
-    public void test_getISOCountries() throws Exception {
-        // Check that corrupting our array doesn't affect other callers.
-        assertNotNull(Resources.getISOCountries()[0]);
-        Resources.getISOCountries()[0] = null;
-        assertNotNull(Resources.getISOCountries()[0]);
-    }
-
-    public void test_getAvailableLocales() throws Exception {
-        // Check that corrupting our array doesn't affect other callers.
-        assertNotNull(Resources.getAvailableLocales()[0]);
-        Resources.getAvailableLocales()[0] = null;
-        assertNotNull(Resources.getAvailableLocales()[0]);
-    }
-
-    public void test_getKnownTimezones() throws Exception {
-        // Check that corrupting our array doesn't affect other callers.
-        assertNotNull(Resources.getKnownTimezones()[0]);
-        Resources.getKnownTimezones()[0] = null;
-        assertNotNull(Resources.getKnownTimezones()[0]);
-    }
-
-    public void test_getDisplayTimeZones() throws Exception {
-        // Check that corrupting our array doesn't affect other callers.
-        assertNotNull(Resources.getDisplayTimeZones(null)[0]);
-        Resources.getDisplayTimeZones(null)[0] = null;
-        assertNotNull(Resources.getDisplayTimeZones(null)[0]);
-        // getDisplayTimezones actually returns a String[][] rather than a String[].
-        assertNotNull(Resources.getDisplayTimeZones(null)[0][0]);
-        Resources.getDisplayTimeZones(null)[0][0] = null;
-        assertNotNull(Resources.getDisplayTimeZones(null)[0][0]);
-    }
-}
diff --git a/include/LocalArray.h b/include/LocalArray.h
index 74c9085..2ab708a 100644
--- a/include/LocalArray.h
+++ b/include/LocalArray.h
@@ -66,6 +66,10 @@
     char mOnStackBuffer[STACK_BYTE_COUNT];
     char* mPtr;
     size_t mSize;
+
+    // Disallow copy and assignment.
+    LocalArray(const LocalArray&);
+    void operator=(const LocalArray&);
 };
 
 #endif // LOCAL_ARRAY_H_included
diff --git a/include/ScopedByteArray.h b/include/ScopedByteArray.h
index bcbee99..6955b70 100644
--- a/include/ScopedByteArray.h
+++ b/include/ScopedByteArray.h
@@ -48,6 +48,10 @@
     JNIEnv* mEnv;
     jbyteArray mByteArray;
     jbyte* mBytes;
+
+    // Disallow copy and assignment.
+    ScopedByteArray(const ScopedByteArray&);
+    void operator=(const ScopedByteArray&);
 };
 
 #endif  // SCOPED_BYTE_ARRAY_H_included
diff --git a/include/ScopedFd.h b/include/ScopedFd.h
index 30feabd..d2b7935 100644
--- a/include/ScopedFd.h
+++ b/include/ScopedFd.h
@@ -37,6 +37,10 @@
 
 private:
     int fd;
+
+    // Disallow copy and assignment.
+    ScopedFd(const ScopedFd&);
+    void operator=(const ScopedFd&);
 };
 
 #endif  // SCOPED_FD_H_included
diff --git a/include/ScopedLocalFrame.h b/include/ScopedLocalFrame.h
new file mode 100644
index 0000000..35b6ad8
--- /dev/null
+++ b/include/ScopedLocalFrame.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SCOPED_LOCAL_FRAME_H_included
+#define SCOPED_LOCAL_FRAME_H_included
+
+#include "JNIHelp.h"
+
+class ScopedLocalFrame {
+public:
+    ScopedLocalFrame(JNIEnv* env) : mEnv(env) {
+        mEnv->PushLocalFrame(128);
+    }
+
+    ~ScopedLocalFrame() {
+        mEnv->PopLocalFrame(NULL);
+    }
+
+private:
+    JNIEnv* mEnv;
+
+    // Disallow copy and assignment.
+    ScopedLocalFrame(const ScopedLocalFrame&);
+    void operator=(const ScopedLocalFrame&);
+};
+
+#endif  // SCOPED_LOCAL_FRAME_H_included
diff --git a/include/ScopedUtfChars.h b/include/ScopedUtfChars.h
new file mode 100644
index 0000000..8bc3e66
--- /dev/null
+++ b/include/ScopedUtfChars.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SCOPED_UTF_CHARS_H_included
+#define SCOPED_UTF_CHARS_H_included
+
+#include "JNIHelp.h"
+
+// A smart pointer that provides read-only access to a Java string's UTF chars.
+class ScopedUtfChars {
+public:
+    ScopedUtfChars(JNIEnv* env, jstring s)
+    : mEnv(env), mString(s), mUtfChars(NULL)
+    {
+        mUtfChars = env->GetStringUTFChars(s, NULL);
+    }
+
+    ~ScopedUtfChars() {
+        if (mUtfChars) {
+            mEnv->ReleaseStringUTFChars(mString, mUtfChars);
+        }
+    }
+
+    const char* data() const {
+        return mUtfChars;
+    }
+
+    // Element access.
+    const char& operator[](size_t n) const {
+        return mUtfChars[n];
+    }
+
+private:
+    JNIEnv* mEnv;
+    jstring mString;
+    const char* mUtfChars;
+
+    // Disallow copy and assignment.
+    ScopedUtfChars(const ScopedUtfChars&);
+    void operator=(const ScopedUtfChars&);
+};
+
+#endif  // SCOPED_UTF_CHARS_H_included
diff --git a/logging/src/main/java/java/util/logging/ErrorManager.java b/logging/src/main/java/java/util/logging/ErrorManager.java
index 708ddfa..6570fa7 100644
--- a/logging/src/main/java/java/util/logging/ErrorManager.java
+++ b/logging/src/main/java/java/util/logging/ErrorManager.java
@@ -17,8 +17,6 @@
 
 package java.util.logging;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * An error reporting facility for {@link Handler} implementations to record any
  * error that may happen during logging. {@code Handlers} should report errors
@@ -98,15 +96,12 @@
             }
             called = true;
         }
-        System.err.println(this.getClass().getName()
-                + ": " + FAILURES[errorCode]); //$NON-NLS-1$
+        System.err.println(this.getClass().getName() + ": " + FAILURES[errorCode]);
         if (message != null) {
-            // logging.1E=Error message - {0}
-            System.err.println(Messages.getString("logging.1E", message)); //$NON-NLS-1$
+            System.err.println("Error message - " + message);
         }
         if (exception != null) {
-            // logging.1F=Exception - {0}
-            System.err.println(Messages.getString("logging.1F", exception)); //$NON-NLS-1$
+            System.err.println("Exception - " + exception);
         }
     }
 }
diff --git a/logging/src/main/java/java/util/logging/FileHandler.java b/logging/src/main/java/java/util/logging/FileHandler.java
index dd7790e..3d61d7d 100644
--- a/logging/src/main/java/java/util/logging/FileHandler.java
+++ b/logging/src/main/java/java/util/logging/FileHandler.java
@@ -29,8 +29,6 @@
 import java.security.PrivilegedAction;
 import java.util.Hashtable;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * A {@code FileHandler} writes logging records into a specified file or a
  * rotating set of files.
@@ -216,12 +214,8 @@
                 break;
             }
         }
-        // BEGIN android-modified
-        output = new MeasureOutputStream(
-                new BufferedOutputStream(
-                        new FileOutputStream(fileName, append), 8192),
-                files[0].length());
-        // END android-modified
+        output = new MeasureOutputStream(new BufferedOutputStream(
+                new FileOutputStream(fileName, append)), files[0].length());
         setOutputStream(output);
     }
 
@@ -232,9 +226,8 @@
         String className = this.getClass().getName();
         pattern = (null == p) ? getStringProperty(className + ".pattern",
                 DEFAULT_PATTERN) : p;
-        if (null == pattern || "".equals(pattern)) {
-            // logging.19=Pattern cannot be empty
-            throw new NullPointerException(Messages.getString("logging.19"));
+        if (pattern == null || pattern.isEmpty()) {
+            throw new NullPointerException("Pattern cannot be empty or null");
         }
         append = (null == a) ? getBooleanProperty(className + ".append",
                 DEFAULT_APPEND) : a.booleanValue();
@@ -256,16 +249,10 @@
             files[i - 1].renameTo(files[i]);
         }
         try {
-            // BEGIN android-modified
-            output = new MeasureOutputStream(
-                    new BufferedOutputStream(
-                            new FileOutputStream(files[0]),
-                            8192));
-            // END android-modified
+            output = new MeasureOutputStream(new BufferedOutputStream(
+                    new FileOutputStream(files[0])));
         } catch (FileNotFoundException e1) {
-            // logging.1A=Error happened when open log file.
-            this.getErrorManager().error(Messages.getString("logging.1A"), //$NON-NLS-1$
-                    e1, ErrorManager.OPEN_FAILURE);
+            this.getErrorManager().error("Error opening log file", e1, ErrorManager.OPEN_FAILURE);
         }
         setOutputStream(output);
     }
@@ -409,12 +396,10 @@
      *             if the pattern is {@code null}.
      */
     public FileHandler(String pattern) throws IOException {
-        if (pattern.equals("")) { //$NON-NLS-1$
-            // logging.19=Pattern cannot be empty
-            throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+        if (pattern.isEmpty()) {
+            throw new IllegalArgumentException("Pattern cannot be empty");
         }
-        init(pattern, null, Integer.valueOf(DEFAULT_LIMIT), Integer
-                .valueOf(DEFAULT_COUNT));
+        init(pattern, null, Integer.valueOf(DEFAULT_LIMIT), Integer.valueOf(DEFAULT_COUNT));
     }
 
     /**
@@ -443,10 +428,9 @@
      *             if {@code pattern} is {@code null}.
      */
     public FileHandler(String pattern, boolean append) throws IOException {
-        if (pattern.equals("")) { //$NON-NLS-1$
-            throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+        if (pattern.isEmpty()) {
+            throw new IllegalArgumentException("Pattern cannot be empty");
         }
-
         init(pattern, Boolean.valueOf(append), Integer.valueOf(DEFAULT_LIMIT),
                 Integer.valueOf(DEFAULT_COUNT));
     }
@@ -481,13 +465,11 @@
      *             if {@code pattern} is {@code null}.
      */
     public FileHandler(String pattern, int limit, int count) throws IOException {
-        if (pattern.equals("")) { //$NON-NLS-1$
-            throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+        if (pattern.isEmpty()) {
+            throw new IllegalArgumentException("Pattern cannot be empty");
         }
         if (limit < 0 || count < 1) {
-            // logging.1B=The limit and count property must be larger than 0 and
-            // 1, respectively
-            throw new IllegalArgumentException(Messages.getString("logging.1B")); //$NON-NLS-1$
+            throw new IllegalArgumentException("limit < 0 || count < 1");
         }
         init(pattern, null, Integer.valueOf(limit), Integer.valueOf(count));
     }
@@ -524,18 +506,14 @@
      * @throws NullPointerException
      *             if {@code pattern} is {@code null}.
      */
-    public FileHandler(String pattern, int limit, int count, boolean append)
-            throws IOException {
-        if (pattern.equals("")) { //$NON-NLS-1$
-            throw new IllegalArgumentException(Messages.getString("logging.19")); //$NON-NLS-1$
+    public FileHandler(String pattern, int limit, int count, boolean append) throws IOException {
+        if (pattern.isEmpty()) {
+            throw new IllegalArgumentException("Pattern cannot be empty");
         }
         if (limit < 0 || count < 1) {
-            // logging.1B=The limit and count property must be larger than 0 and
-            // 1, respectively
-            throw new IllegalArgumentException(Messages.getString("logging.1B")); //$NON-NLS-1$
+            throw new IllegalArgumentException("limit < 0 || count < 1");
         }
-        init(pattern, Boolean.valueOf(append), Integer.valueOf(limit), Integer
-                .valueOf(count));
+        init(pattern, Boolean.valueOf(append), Integer.valueOf(limit), Integer.valueOf(count));
     }
 
     /**
diff --git a/logging/src/main/java/java/util/logging/Handler.java b/logging/src/main/java/java/util/logging/Handler.java
index a5b92a0..d1aaef2 100644
--- a/logging/src/main/java/java/util/logging/Handler.java
+++ b/logging/src/main/java/java/util/logging/Handler.java
@@ -22,8 +22,6 @@
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * A {@code Handler} object accepts a logging request and exports the desired
  * messages to a target, for example, a file, the console, etc. It can be
@@ -98,11 +96,7 @@
 
     // print error message in some format
     void printInvalidPropMessage(String key, String value, Exception e) {
-        // logging.12=Invalid property value for
-        String msg = new StringBuilder().append(
-                Messages.getString("logging.12")) //$NON-NLS-1$
-                .append(prefix).append(":").append(key).append("/").append( //$NON-NLS-1$//$NON-NLS-2$
-                        value).toString();
+        String msg = "Invalid property value for " + prefix + ":" + key + "/" + value;
         errorMan.error(msg, e, ErrorManager.GENERIC_FAILURE);
     }
 
@@ -286,21 +280,16 @@
      * @throws UnsupportedEncodingException
      *             if the specified encoding is not supported by the runtime.
      */
-    void internalSetEncoding(String newEncoding)
-            throws UnsupportedEncodingException {
+    void internalSetEncoding(String newEncoding) throws UnsupportedEncodingException {
         // accepts "null" because it indicates using default encoding
-        if (null == newEncoding) {
+        if (newEncoding == null) {
             this.encoding = null;
         } else {
             if (Charset.isSupported(newEncoding)) {
                 this.encoding = newEncoding;
             } else {
-                // logging.13=The encoding "{0}" is not supported.
-                throw new UnsupportedEncodingException(Messages.getString(
-                        "logging.13", //$NON-NLS-1$
-                        newEncoding));
+                throw new UnsupportedEncodingException(newEncoding);
             }
-
         }
     }
 
diff --git a/logging/src/main/java/java/util/logging/Level.java b/logging/src/main/java/java/util/logging/Level.java
index f988127..2c7ac53 100644
--- a/logging/src/main/java/java/util/logging/Level.java
+++ b/logging/src/main/java/java/util/logging/Level.java
@@ -17,6 +17,7 @@
 
 package java.util.logging;
 
+import dalvik.system.VMStack;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.Serializable;
@@ -26,11 +27,6 @@
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-// BEGIN android-changed
-import dalvik.system.VMStack;
-// END android-changed
-
 /**
  * {@code Level} objects are used to indicate the level of logging. There are a
  * set of predefined logging levels, each associated with an integer value.
@@ -107,8 +103,7 @@
      */
     public static Level parse(String name) throws IllegalArgumentException {
         if (name == null) {
-            // logging.1C=The 'name' parameter is null.
-            throw new NullPointerException(Messages.getString("logging.1C")); //$NON-NLS-1$
+            throw new NullPointerException("name == null");
         }
 
         boolean isNameAnInt;
@@ -142,9 +137,7 @@
         }
 
         if (!isNameAnInt) {
-            // logging.1D=Cannot parse this name: {0}
-            throw new IllegalArgumentException(Messages.getString(
-                    "logging.1D", name)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Cannot parse name '" + name + "'");
         }
 
         return new Level(name, nameAsInt);
@@ -207,8 +200,7 @@
      */
     protected Level(String name, int level, String resourceBundleName) {
         if (name == null) {
-            // logging.1C=The 'name' parameter is null.
-            throw new NullPointerException(Messages.getString("logging.1C")); //$NON-NLS-1$
+            throw new NullPointerException("name == null");
         }
         this.name = name;
         this.value = level;
diff --git a/logging/src/main/java/java/util/logging/LogManager.java b/logging/src/main/java/java/util/logging/LogManager.java
index 6cba849..c07f6bf 100644
--- a/logging/src/main/java/java/util/logging/LogManager.java
+++ b/logging/src/main/java/java/util/logging/LogManager.java
@@ -23,8 +23,6 @@
 // javax.management support (MBeans) has been dropped.
 // END android-note
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.io.BufferedInputStream;
@@ -126,11 +124,10 @@
 public class LogManager {
 
     /** The line separator of the underlying OS. */
-    private static final String lineSeparator = getPrivilegedSystemProperty("line.separator"); //$NON-NLS-1$
+    private static final String lineSeparator = getPrivilegedSystemProperty("line.separator");
 
     /** The shared logging permission. */
-    private static final LoggingPermission perm = new LoggingPermission(
-            "control", null); //$NON-NLS-1$
+    private static final LoggingPermission perm = new LoggingPermission("control", null);
 
     /** The singleton instance. */
     static LogManager manager;
@@ -138,7 +135,7 @@
     /**
      * The {@code String} value of the {@link LoggingMXBean}'s ObjectName.
      */
-    public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; //$NON-NLS-1$
+    public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
 
     /**
      * Get the {@code LoggingMXBean} instance. this implementation always throws
@@ -147,39 +144,7 @@
      * @return the {@code LoggingMXBean} instance
      */
     public static LoggingMXBean getLoggingMXBean() {
-      // BEGIN android-added
-      throw new UnsupportedOperationException();
-      // END android-added
-      // BEGIN android-removed
-      // try {
-      //     ObjectName loggingMXBeanName = new ObjectName(LOGGING_MXBEAN_NAME);
-      //     MBeanServer platformBeanServer = ManagementFactory
-      //             .getPlatformMBeanServer();
-      //     Set<?> loggingMXBeanSet = platformBeanServer.queryMBeans(
-      //             loggingMXBeanName, null);
-      //
-      //     if (loggingMXBeanSet.size() != 1) {
-      //         // logging.21=There Can Be Only One logging MX bean.
-      //         throw new AssertionError(Messages.getString("logging.21")); //$NON-NLS-1$
-      //     }
-      //
-      //     Iterator<?> i = loggingMXBeanSet.iterator();
-      //     ObjectInstance loggingMXBeanOI = (ObjectInstance) i.next();
-      //     String lmxbcn = loggingMXBeanOI.getClassName();
-      //     Class<?> lmxbc = Class.forName(lmxbcn);
-      //     Method giMethod = lmxbc.getDeclaredMethod("getInstance"); //$NON-NLS-1$
-      //     giMethod.setAccessible(true);
-      //     LoggingMXBean lmxb = (LoggingMXBean) giMethod.invoke(null,
-      //             new Object[] {});
-      //
-      //     return lmxb;
-      // } catch (Exception e) {
-      //     // TODO
-      //     // e.printStackTrace();
-      // }
-      // // logging.22=Exception occurred while getting the logging MX bean.
-      // throw new AssertionError(Messages.getString("logging.22")); //$NON-NLS-1$
-      // END android-removed
+        throw new UnsupportedOperationException();
     }
 
     // FIXME: use weak reference to avoid heap memory leak
@@ -195,8 +160,7 @@
         // init LogManager singleton instance
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
-                String className = System
-                        .getProperty("java.util.logging.manager"); //$NON-NLS-1$
+                String className = System.getProperty("java.util.logging.manager");
 
                 if (null != className) {
                     manager = (LogManager) getInstanceByClass(className);
@@ -213,7 +177,7 @@
                 }
 
                 // if global logger has been initialized, set root as its parent
-                Logger root = new Logger("", null); //$NON-NLS-1$
+                Logger root = new Logger("", null);
                 root.setLevel(Level.INFO);
                 Logger.global.setParent(root);
 
@@ -313,14 +277,14 @@
             if (parent != null) {
                 setParent(logger, parent);
                 break;
-            } else if (getProperty(parentName + ".level") != null || //$NON-NLS-1$
-                    getProperty(parentName + ".handlers") != null) { //$NON-NLS-1$
+            } else if (getProperty(parentName + ".level") != null ||
+                    getProperty(parentName + ".handlers") != null) {
                 parent = Logger.getLogger(parentName);
                 setParent(logger, parent);
                 break;
             }
         }
-        if (parent == null && null != (parent = loggers.get(""))) { //$NON-NLS-1$
+        if (parent == null && null != (parent = loggers.get(""))) {
             setParent(logger, parent);
         }
 
@@ -403,20 +367,16 @@
      */
     public void readConfiguration() throws IOException {
         // check config class
-        String configClassName = System
-                .getProperty("java.util.logging.config.class"); //$NON-NLS-1$
+        String configClassName = System.getProperty("java.util.logging.config.class");
         if (null == configClassName
                 || null == getInstanceByClass(configClassName)) {
             // if config class failed, check config file
-            String configFile = System
-                    .getProperty("java.util.logging.config.file"); //$NON-NLS-1$
+            String configFile = System.getProperty("java.util.logging.config.file");
 
             if (null == configFile) {
                 // if cannot find configFile, use default logging.properties
-                configFile = new StringBuilder().append(
-                        System.getProperty("java.home")).append(File.separator) //$NON-NLS-1$
-                        .append("lib").append(File.separator).append( //$NON-NLS-1$
-                                "logging.properties").toString(); //$NON-NLS-1$
+                configFile = System.getProperty("java.home") + File.separator + "lib" +
+                        File.separator + "logging.properties";
             }
 
             InputStream input = null;
@@ -427,13 +387,11 @@
 
                 // BEGIN android-added
                 try {
-                    input = new BufferedInputStream(
-                            new FileInputStream(configFile), 8192);
+                    input = new BufferedInputStream(new FileInputStream(configFile));
                 } catch (Exception ex) {
                     // consult fixed resource as a last resort
                     input = new BufferedInputStream(
-                            getClass().getResourceAsStream(
-                                    "logging.properties"), 8192);
+                            getClass().getResourceAsStream("logging.properties"));
                 }
                 // END android-added
                 readConfiguration(input);
@@ -460,17 +418,14 @@
     // use SystemClassLoader to load class from system classpath
     static Object getInstanceByClass(final String className) {
         try {
-            Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(
-                    className);
+            Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(className);
             return clazz.newInstance();
         } catch (Exception e) {
             try {
-                Class<?> clazz = Thread.currentThread().getContextClassLoader()
-                        .loadClass(className);
+                Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
                 return clazz.newInstance();
             } catch (Exception innerE) {
-                // logging.20=Loading class "{0}" failed
-                System.err.println(Messages.getString("logging.20", className)); //$NON-NLS-1$
+                System.err.println("Loading class '" + className + "' failed");
                 System.err.println(innerE);
                 return null;
             }
@@ -492,9 +447,9 @@
         }
 
         // parse property "config" and apply setting
-        String configs = props.getProperty("config"); //$NON-NLS-1$
+        String configs = props.getProperty("config");
         if (null != configs) {
-            StringTokenizer st = new StringTokenizer(configs, " "); //$NON-NLS-1$
+            StringTokenizer st = new StringTokenizer(configs, " ");
             while (st.hasMoreTokens()) {
                 String configerName = st.nextToken();
                 getInstanceByClass(configerName);
@@ -504,7 +459,7 @@
         // set levels for logger
         Collection<Logger> allLoggers = loggers.values();
         for (Logger logger : allLoggers) {
-            String property = props.getProperty(logger.getName() + ".level"); //$NON-NLS-1$
+            String property = props.getProperty(logger.getName() + ".level");
             if (null != property) {
                 logger.setLevel(Level.parse(property));
             }
@@ -555,7 +510,7 @@
                 logger.reset();
             }
         }
-        Logger root = loggers.get(""); //$NON-NLS-1$
+        Logger root = loggers.get("");
         if (null != root) {
             root.setLevel(Level.INFO);
         }
diff --git a/logging/src/main/java/java/util/logging/LogRecord.java b/logging/src/main/java/java/util/logging/LogRecord.java
index f810e12..d4466bf 100644
--- a/logging/src/main/java/java/util/logging/LogRecord.java
+++ b/logging/src/main/java/java/util/logging/LogRecord.java
@@ -24,8 +24,6 @@
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * A {@code LogRecord} object represents a logging request. It is passed between
  * the logging framework and individual logging handlers. Client applications
@@ -154,9 +152,8 @@
      *             if {@code level} is {@code null}.
      */
     public LogRecord(Level level, String msg) {
-        if (null == level) {
-            // logging.4=The 'level' parameter is null.
-            throw new NullPointerException(Messages.getString("logging.4")); //$NON-NLS-1$
+        if (level == null) {
+            throw new NullPointerException("level == null");
         }
         this.level = level;
         this.message = msg;
@@ -200,9 +197,8 @@
      *             if {@code level} is {@code null}.
      */
     public void setLevel(Level level) {
-        if (null == level) {
-            // logging.4=The 'level' parameter is null.
-            throw new NullPointerException(Messages.getString("logging.4")); //$NON-NLS-1$
+        if (level == null) {
+            throw new NullPointerException("level == null");
         }
         this.level = level;
     }
@@ -489,9 +485,7 @@
         byte minor = in.readByte();
         // only check MAJOR version
         if (major != MAJOR) {
-            // logging.5=Different version - {0}.{1}
-            throw new IOException(Messages.getString("logging.5", //$NON-NLS-1$
-                    Byte.valueOf(major), Byte.valueOf(minor)));
+            throw new IOException("Different version " + Byte.valueOf(major) + "." + Byte.valueOf(minor));
         }
 
         int length = in.readInt();
diff --git a/logging/src/main/java/java/util/logging/Logger.java b/logging/src/main/java/java/util/logging/Logger.java
index e4f317d..8271022 100644
--- a/logging/src/main/java/java/util/logging/Logger.java
+++ b/logging/src/main/java/java/util/logging/Logger.java
@@ -26,8 +26,6 @@
 
 import dalvik.system.DalvikLogHandler;
 import dalvik.system.DalvikLogging;
-import org.apache.harmony.logging.internal.nls.Messages;
-
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -39,18 +37,23 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
- * Loggers are used to log records to certain outputs, including file, console,
- * etc. They use various handlers to actually do the output-dependent
+ * Loggers are used to log records to a variety of destinations such as log files or
+ * the console. They use instances of {@link Handler} to actually do the destination-specific
  * operations.
- * <p>
- * Client applications can get named loggers by calling the {@code getLogger}
+ *
+ * <p>Client applications can get named loggers by calling the {@code getLogger}
  * methods. They can also get anonymous loggers by calling the
  * {@code getAnonymousLogger} methods. Named loggers are organized in a
  * namespace hierarchy managed by a log manager. The naming convention is
- * usually the same as java package's naming convention, that is using
- * dot-separated strings. Anonymous loggers do not belong to any namespace.
- * <p>
- * Loggers "inherit" log level setting from their parent if their own level is
+ * usually the Java package naming convention. Anonymous loggers do not belong to any namespace.
+ *
+ * <p>Developers should use named loggers to enable logging to be controlled on a
+ * per-{@code Logger} granularity. The recommended idiom is to create and assign the logger to
+ * a {@code static final} field. This ensures that there's always a strong reference to the logger,
+ * preventing it from being garbage collected. In particular, {@link LogManager#addLogger(Logger)}
+ * will <i>not</i> keep your logger live.
+ *
+ * <p>Loggers "inherit" log level setting from their parent if their own level is
  * set to {@code null}. This is also true for the resource bundle. The logger's
  * resource bundle is used to localize the log messages if no resource bundle
  * name is given when a log method is called. If {@code getUseParentHandlers()}
@@ -60,9 +63,9 @@
  * {@code null}.
  * <p>
  * When loading a given resource bundle, the logger first tries to use the
- * context classloader. If that fails, it tries the system classloader. And if
+ * context {@code ClassLoader}. If that fails, it tries the system {@code ClassLoader}. And if
  * that still fails, it searches up the class stack and uses each class's
- * classloader to try to locate the resource bundle.
+ * {@code ClassLoader} to try to locate the resource bundle.
  * <p>
  * Some log methods accept log requests that do not specify the source class and
  * source method. In these cases, the logging framework will automatically infer
@@ -90,8 +93,22 @@
     };
     // END android-only
 
-    /** The global logger is provided as convenience for casual use. */
-    public final static Logger global = new Logger("global", null); //$NON-NLS-1$
+    /**
+     * The name of the global logger. Before using this, see the discussion of how to use
+     * {@code Logger} in the class documentation.
+     * @since 1.6
+     * @hide
+     */
+    public static final String GLOBAL_LOGGER_NAME = "global";
+
+    /**
+     * The global logger is provided as convenience for casual use.
+     * @deprecated deadlock-prone. Use {@code Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)} as
+     * a direct replacement, but see the discussion of how to use {@code Logger} in the class
+     * documentation.
+     */
+    @Deprecated
+    public final static Logger global = new Logger(GLOBAL_LOGGER_NAME, null);
 
     /**
      * When converting the concurrent collection of handlers to an array, we
@@ -321,9 +338,8 @@
                 // Failed to load using the current class's classloader, ignore
             }
         }
-        // logging.8=Failed to load the specified resource bundle "{0}".
-        throw new MissingResourceException(Messages.getString("logging.8", //$NON-NLS-1$
-                resourceBundleName), resourceBundleName, null);
+        throw new MissingResourceException("Failed to load the specified resource bundle \"" +
+                resourceBundleName + "\"", resourceBundleName, null);
     }
 
     /**
@@ -375,11 +391,7 @@
             if (current.equals(resourceBundleName)) {
                 return;
             } else {
-                // logging.9=The specified resource bundle name "{0}" is
-                // inconsistent with the existing one "{1}".
-                throw new IllegalArgumentException(Messages.getString(
-                        "logging.9", //$NON-NLS-1$
-                        resourceBundleName, current));
+                throw new IllegalArgumentException("Resource bundle name '" + resourceBundleName + "' is inconsistent with the existing '" + current + "'");
             }
         }
 
@@ -439,8 +451,7 @@
      */
     public void addHandler(Handler handler) {
         if (handler == null) {
-            // logging.A=The 'handler' parameter is null.
-            throw new NullPointerException(Messages.getString("logging.A")); //$NON-NLS-1$
+            throw new NullPointerException("handler == null");
         }
         // Anonymous loggers can always add handlers
         if (this.isNamed) {
@@ -636,8 +647,7 @@
      */
     public void setParent(Logger parent) {
         if (parent == null) {
-            // logging.B=The 'parent' parameter is null.
-            throw new NullPointerException(Messages.getString("logging.B")); //$NON-NLS-1$
+            throw new NullPointerException("parent == null");
         }
 
         // even anonymous loggers are checked
diff --git a/logging/src/main/java/java/util/logging/LoggingPermission.java b/logging/src/main/java/java/util/logging/LoggingPermission.java
index aa41a2c..5ca9cc9 100644
--- a/logging/src/main/java/java/util/logging/LoggingPermission.java
+++ b/logging/src/main/java/java/util/logging/LoggingPermission.java
@@ -21,8 +21,6 @@
 import java.security.BasicPermission;
 import java.security.Guard;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * The permission required to control the logging when run with a
  * {@code SecurityManager}.
@@ -51,14 +49,11 @@
      */
     public LoggingPermission(String name, String actions) {
         super(name, actions);
-        if (!"control".equals(name)) { //$NON-NLS-1$
-            // logging.6=Name must be "control".
-            throw new IllegalArgumentException(Messages.getString("logging.6")); //$NON-NLS-1$
+        if (!"control".equals(name)) {
+            throw new IllegalArgumentException("name must be \"control\"");
         }
-        if (null != actions && !"".equals(actions)) { //$NON-NLS-1$
-            // logging.7=Actions must be either null or the empty string.
-            throw new IllegalArgumentException(Messages.getString("logging.7")); //$NON-NLS-1$
+        if (actions != null && !actions.isEmpty()) {
+            throw new IllegalArgumentException("actions != null && !actions.isEmpty()");
         }
     }
-
 }
diff --git a/logging/src/main/java/java/util/logging/MemoryHandler.java b/logging/src/main/java/java/util/logging/MemoryHandler.java
index 3312083..c1b36c8 100644
--- a/logging/src/main/java/java/util/logging/MemoryHandler.java
+++ b/logging/src/main/java/java/util/logging/MemoryHandler.java
@@ -20,8 +20,6 @@
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * A {@code Handler} put the description of log events into a cycled memory
  * buffer.
@@ -92,7 +90,7 @@
         super();
         String className = this.getClass().getName();
         // init target
-        final String targetName = manager.getProperty(className + ".target"); //$NON-NLS-1$
+        final String targetName = manager.getProperty(className + ".target");
         try {
             Class<?> targetClass = AccessController
                     .doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
@@ -107,12 +105,10 @@
                     });
             target = (Handler) targetClass.newInstance();
         } catch (Exception e) {
-            // logging.10=Cannot load target handler:{0}
-            throw new RuntimeException(Messages.getString("logging.10", //$NON-NLS-1$
-                    targetName));
+            throw new RuntimeException("Cannot load target handler '" + targetName + "'");
         }
         // init size
-        String sizeString = manager.getProperty(className + ".size"); //$NON-NLS-1$
+        String sizeString = manager.getProperty(className + ".size");
         if (null != sizeString) {
             try {
                 size = Integer.parseInt(sizeString);
@@ -120,20 +116,20 @@
                     size = DEFAULT_SIZE;
                 }
             } catch (Exception e) {
-                printInvalidPropMessage(className + ".size", sizeString, e); //$NON-NLS-1$
+                printInvalidPropMessage(className + ".size", sizeString, e);
             }
         }
         // init push level
-        String pushName = manager.getProperty(className + ".push"); //$NON-NLS-1$
+        String pushName = manager.getProperty(className + ".push");
         if (null != pushName) {
             try {
                 push = Level.parse(pushName);
             } catch (Exception e) {
-                printInvalidPropMessage(className + ".push", pushName, e); //$NON-NLS-1$
+                printInvalidPropMessage(className + ".push", pushName, e);
             }
         }
         // init other properties which are common for all Handler
-        initProperties("ALL", null, "java.util.logging.SimpleFormatter", null); //$NON-NLS-1$//$NON-NLS-2$
+        initProperties("ALL", null, "java.util.logging.SimpleFormatter", null);
         buffer = new LogRecord[size];
     }
 
@@ -157,15 +153,14 @@
      */
     public MemoryHandler(Handler target, int size, Level pushLevel) {
         if (size <= 0) {
-            // logging.11=Size must be positive.
-            throw new IllegalArgumentException(Messages.getString("logging.11")); //$NON-NLS-1$
+            throw new IllegalArgumentException("size <= 0");
         }
         target.getLevel();
         pushLevel.intValue();
         this.target = target;
         this.size = size;
         this.push = pushLevel;
-        initProperties("ALL", null, "java.util.logging.SimpleFormatter", null); //$NON-NLS-1$//$NON-NLS-2$
+        initProperties("ALL", null, "java.util.logging.SimpleFormatter", null);
         buffer = new LogRecord[size];
     }
 
diff --git a/logging/src/main/java/java/util/logging/SocketHandler.java b/logging/src/main/java/java/util/logging/SocketHandler.java
index 38cfd64..fb854fe 100644
--- a/logging/src/main/java/java/util/logging/SocketHandler.java
+++ b/logging/src/main/java/java/util/logging/SocketHandler.java
@@ -21,8 +21,6 @@
 import java.io.IOException;
 import java.net.Socket;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * A handler that writes log messages to a socket connection.
  * <p>
@@ -110,35 +108,28 @@
     // Initialize the socket connection and prepare the output stream
     private void initSocket(String host, String port) throws IOException {
         // check the validity of the host name
-        if (null == host || "".equals(host)) { //$NON-NLS-1$
-            // logging.C=Illegal host argument.
-            throw new IllegalArgumentException(Messages.getString("logging.C")); //$NON-NLS-1$
+        if (host == null || host.isEmpty()) {
+            throw new IllegalArgumentException("host == null || host.isEmpty()");
         }
         // check the validity of the port number
         int p = 0;
         try {
             p = Integer.parseInt(port);
         } catch (NumberFormatException e) {
-            // logging.D=Illegal port argument.
-            throw new IllegalArgumentException(Messages.getString("logging.D")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Illegal port argument");
         }
         if (p <= 0) {
-            // logging.D=Illegal port argument.
-            throw new IllegalArgumentException(Messages.getString("logging.D")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Illegal port argument");
         }
         // establish the network connection
         try {
             this.socket = new Socket(host, p);
         } catch (IOException e) {
-            // logging.E=Failed to establish the network connection.
-            getErrorManager().error(Messages.getString("logging.E"), e, //$NON-NLS-1$
+            getErrorManager().error("Failed to establish the network connection", e,
                     ErrorManager.OPEN_FAILURE);
             throw e;
         }
-        // BEGIN android-modified
-        super.internalSetOutputStream(new BufferedOutputStream(this.socket
-                        .getOutputStream(), 8192));
-        // END android-modified
+        super.internalSetOutputStream(new BufferedOutputStream(this.socket.getOutputStream()));
     }
 
     /**
@@ -157,8 +148,7 @@
                 this.socket = null;
             }
         } catch (Exception e) {
-            // logging.F=Exception occurred when closing the socket handler.
-            getErrorManager().error(Messages.getString("logging.F"), e, //$NON-NLS-1$
+            getErrorManager().error("Exception occurred when closing the socket handler", e,
                     ErrorManager.CLOSE_FAILURE);
         }
     }
diff --git a/logging/src/main/java/java/util/logging/StreamHandler.java b/logging/src/main/java/java/util/logging/StreamHandler.java
index 7049d45..2a67b98 100644
--- a/logging/src/main/java/java/util/logging/StreamHandler.java
+++ b/logging/src/main/java/java/util/logging/StreamHandler.java
@@ -22,8 +22,6 @@
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 
-import org.apache.harmony.logging.internal.nls.Messages;
-
 /**
  * A {@code StreamHandler} object writes log messages to an output stream, that
  * is, objects of the class {@link java.io.OutputStream}.
@@ -63,8 +61,7 @@
      * does not have an associated output stream.
      */
     public StreamHandler() {
-        initProperties("INFO", null, "java.util.logging.SimpleFormatter", //$NON-NLS-1$//$NON-NLS-2$
-                null);
+        initProperties("INFO", null, "java.util.logging.SimpleFormatter", null);
         this.os = null;
         this.writer = null;
         this.writerNotInitialized = true;
@@ -110,19 +107,17 @@
     public StreamHandler(OutputStream os, Formatter formatter) {
         this();
         if (os == null) {
-            // logging.2=The OutputStream parameter is null
-            throw new NullPointerException(Messages.getString("logging.2")); //$NON-NLS-1$
+            throw new NullPointerException("os == null");
         }
         if (formatter == null) {
-            // logging.3=The Formatter parameter is null.
-            throw new NullPointerException(Messages.getString("logging.3")); //$NON-NLS-1$
+            throw new NullPointerException("formatter == null");
         }
         this.os = os;
         internalSetFormatter(formatter);
     }
 
     // initialize the writer
-    private void initializeWritter() {
+    private void initializeWriter() {
         this.writerNotInitialized = false;
         if (null == getEncoding()) {
             this.writer = new OutputStreamWriter(this.os);
@@ -144,8 +139,7 @@
         try {
             this.writer.write(s);
         } catch (Exception e) {
-            // logging.14=Exception occurred when writing to the output stream.
-            getErrorManager().error(Messages.getString("logging.14"), e, //$NON-NLS-1$
+            getErrorManager().error("Exception occurred when writing to the output stream", e,
                     ErrorManager.WRITE_FAILURE);
         }
     }
@@ -231,7 +225,7 @@
     void close(boolean closeStream) {
         if (null != this.os) {
             if (this.writerNotInitialized) {
-                initializeWritter();
+                initializeWriter();
             }
             write(getFormatter().getTail(this));
             try {
@@ -242,8 +236,7 @@
                     this.os = null;
                 }
             } catch (Exception e) {
-                // logging.15=Exception occurred when closing the output stream.
-                getErrorManager().error(Messages.getString("logging.15"), e, //$NON-NLS-1$
+                getErrorManager().error("Exception occurred when closing the output stream", e,
                         ErrorManager.CLOSE_FAILURE);
             }
         }
@@ -278,9 +271,7 @@
                     this.os.flush();
                 }
             } catch (Exception e) {
-                // logging.16=Exception occurred while flushing the output
-                // stream.
-                getErrorManager().error(Messages.getString("logging.16"), //$NON-NLS-1$
+                getErrorManager().error("Exception occurred when flushing the output stream",
                         e, ErrorManager.FLUSH_FAILURE);
             }
         }
@@ -306,22 +297,19 @@
         try {
             if (this.isLoggable(record)) {
                 if (this.writerNotInitialized) {
-                    initializeWritter();
+                    initializeWriter();
                 }
                 String msg = null;
                 try {
                     msg = getFormatter().format(record);
                 } catch (Exception e) {
-                    // logging.17=Exception occurred while formatting the log
-                    // record.
-                    getErrorManager().error(Messages.getString("logging.17"), //$NON-NLS-1$
+                    getErrorManager().error("Exception occurred when formatting the log record",
                             e, ErrorManager.FORMAT_FAILURE);
                 }
                 write(msg);
             }
         } catch (Exception e) {
-            // logging.18=Exception occurred while logging the record.
-            getErrorManager().error(Messages.getString("logging.18"), e, //$NON-NLS-1$
+            getErrorManager().error("Exception occurred when logging the record", e,
                     ErrorManager.GENERIC_FAILURE);
         }
     }
diff --git a/logging/src/main/java/java/util/logging/package.html b/logging/src/main/java/java/util/logging/package.html
index c523c7a..d7ed252 100644
--- a/logging/src/main/java/java/util/logging/package.html
+++ b/logging/src/main/java/java/util/logging/package.html
@@ -5,6 +5,5 @@
       supports different levels of importance of a message that needs to be
       logged. The output written to the target can be filtered by this level.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java b/logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java
deleted file mode 100644
index 87535ae..0000000
--- a/logging/src/main/java/org/apache/harmony/logging/internal/nls/Messages.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.logging.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.logging.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.logging.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties b/logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties
deleted file mode 100644
index da3945e..0000000
--- a/logging/src/main/java/org/apache/harmony/logging/internal/nls/messages.properties
+++ /dev/null
@@ -1,52 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-logging.0=This method is not currently implemented.
-logging.1=Invalid level name: {0}.
-logging.10=Cannot load target handler:{0}
-logging.11=Size must be positive.
-logging.12=Invalid property value for 
-logging.13=The encoding "{0}" is not supported.
-logging.14=Exception occurred when writing to the output stream.
-logging.15=Exception occurred when closing the output stream.
-logging.16=Exception occurred while flushing the output stream.
-logging.17=Exception occurred while formatting the log record.
-logging.18=Exception occurred while logging the record.
-logging.19=Pattern cannot be empty
-logging.1A=Error happened when open log file.
-logging.1B=The limit and count property must be larger than 0 and 1, respectively
-logging.1C=The 'name' parameter is null.
-logging.1D=Cannot parse this name: {0}
-logging.1E=Error message - {0}
-logging.1F=Exception - {0}
-logging.2=The OutputStream parameter is null
-logging.20=Loading class "{0}" failed
-logging.21=There Can Be Only One logging MX bean.
-logging.22=Exception occurred while getting the logging MX bean.
-logging.3=The Formatter parameter is null.
-logging.4=The 'level' parameter is null.
-logging.5=Different version - {0}.{1}
-logging.6=Name must be "control".
-logging.7=Actions must be either null or the empty string.
-logging.8=Failed to load the specified resource bundle "{0}".
-logging.9=The specified resource bundle name "{0}" is inconsistent with the existing one "{1}".
-logging.A=The 'handler' parameter is null.
-logging.B=The 'parent' parameter is null.
-logging.C=Illegal host argument.
-logging.D=Illegal port argument.
-logging.E=Failed to establish the network connection.
-logging.F=Exception occured when closing the socket handler.
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java
index 1094f25..7807768 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/AllTests.java
@@ -25,8 +25,7 @@
 public class AllTests {
 
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "Suite for org.apache.harmony.logging.tests.java.util.logging");
+        TestSuite suite = new TestSuite("Suite for org.apache.harmony.logging.tests.java.util.logging");
         // $JUnit-BEGIN$
         suite.addTestSuite(ConsoleHandlerTest.class);
         suite.addTestSuite(ErrorManagerTest.class);
@@ -45,7 +44,6 @@
         suite.addTestSuite(SocketHandlerTest.class);
         suite.addTestSuite(StreamHandlerTest.class);
         suite.addTestSuite(XMLFormatterTest.class);
-        suite.addTestSuite(MessagesTest.class);
         // $JUnit-END$
         return suite;
     }
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java
index 91de2a5..b2204a3 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ConsoleHandlerTest.java
@@ -17,17 +17,11 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargets;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.security.Permission;
-import java.util.Currency;
 import java.util.Properties;
 import java.util.logging.ConsoleHandler;
 import java.util.logging.Filter;
@@ -48,638 +42,542 @@
 /**
  * Test class java.util.logging.ConsoleHandler
  */
-@TestTargetClass(ConsoleHandler.class) 
 public class ConsoleHandlerTest extends TestCase {
 
-    private final static String INVALID_LEVEL = "impossible_level";
+	private final static String INVALID_LEVEL = "impossible_level";
 
-    private final PrintStream err = System.err;
+	private final PrintStream err = System.err;
 
-    private OutputStream errSubstituteStream = null;
+	private OutputStream errSubstituteStream = null;
 
-    private static String className = ConsoleHandlerTest.class.getName();
+	private static String className = ConsoleHandlerTest.class.getName();
 
-    /*
-     * @see TestCase#setUp()
-     */
-    protected void setUp() throws Exception {
-        super.setUp();
-        errSubstituteStream = new MockOutputStream();
-        System.setErr(new PrintStream(errSubstituteStream));
-        LogManager.getLogManager().reset();
-    }
+	/*
+	 * @see TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		errSubstituteStream = new MockOutputStream();
+		System.setErr(new PrintStream(errSubstituteStream));
+		LogManager.getLogManager().reset();
+	}
 
-    /*
-     * @see TestCase#tearDown()
-     */
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        LogManager.getLogManager().reset();
-        CallVerificationStack.getInstance().clear();
-        System.setErr(err);
-    }
+	/*
+	 * @see TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		LogManager.getLogManager().reset();
+		CallVerificationStack.getInstance().clear();
+		System.setErr(err);
+	}
 
-    /*
-     * Test the constructor with no relevant log manager properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with no relevant log manager properties are set.",
-        method = "ConsoleHandler",
-        args = {}
-    )
-    public void testConstructor_NoProperties() {
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.level"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.filter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.formatter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.encoding"));
+	/*
+	 * Test the constructor with no relevant log manager properties are set.
+	 */
+	public void testConstructor_NoProperties() {
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.level"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.filter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.formatter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.encoding"));
 
-        ConsoleHandler h = new ConsoleHandler();
-        assertSame(h.getLevel(), Level.INFO);
-        assertTrue(h.getFormatter() instanceof SimpleFormatter);
-        assertNull(h.getFilter());
-        assertSame(h.getEncoding(), null);
-    }
+		ConsoleHandler h = new ConsoleHandler();
+		assertSame(h.getLevel(), Level.INFO);
+		assertTrue(h.getFormatter() instanceof SimpleFormatter);
+		assertNull(h.getFilter());
+		assertSame(h.getEncoding(), null);
+	}
 
-    /*
-     * Test the constructor with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with insufficient privilege.",
-        method = "ConsoleHandler",
-        args = {}
-    )
-    public void testConstructor_InsufficientPrivilege() {
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.level"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.filter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.formatter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.encoding"));
+	/*
+	 * Test the constructor with insufficient privilege.
+	 */
+	public void testConstructor_InsufficientPrivilege() {
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.level"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.filter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.formatter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.encoding"));
 
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        // set a normal value
-        try {
-            ConsoleHandler h = new ConsoleHandler();
-            assertSame(h.getLevel(), Level.INFO);
-            assertTrue(h.getFormatter() instanceof SimpleFormatter);
-            assertNull(h.getFilter());
-            assertSame(h.getEncoding(), null);
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		// set a normal value
+		try {
+			ConsoleHandler h = new ConsoleHandler();
+			assertSame(h.getLevel(), Level.INFO);
+			assertTrue(h.getFormatter() instanceof SimpleFormatter);
+			assertNull(h.getFilter());
+			assertSame(h.getEncoding(), null);
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Test the constructor with valid relevant log manager properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with valid relevant log manager properties are set.",
-        method = "ConsoleHandler",
-        args = {}
-    )
-    public void testConstructor_ValidProperties() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.level", "FINE");
-        p.put("java.util.logging.ConsoleHandler.filter", className
-                + "$MockFilter");
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        p.put("java.util.logging.ConsoleHandler.encoding", "iso-8859-1");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with valid relevant log manager properties are set.
+	 */
+	public void testConstructor_ValidProperties() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.level", "FINE");
+		p.put("java.util.logging.ConsoleHandler.filter", className
+				+ "$MockFilter");
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		p.put("java.util.logging.ConsoleHandler.encoding", "iso-8859-1");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.level"), "FINE");
-        assertEquals(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.encoding"), "iso-8859-1");
-        ConsoleHandler h = new ConsoleHandler();
-        assertSame(h.getLevel(), Level.parse("FINE"));
-        assertTrue(h.getFormatter() instanceof MockFormatter);
-        assertTrue(h.getFilter() instanceof MockFilter);
-        assertEquals(h.getEncoding(), "iso-8859-1");
-    }
+		assertEquals(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.level"), "FINE");
+		assertEquals(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.encoding"), "iso-8859-1");
+		ConsoleHandler h = new ConsoleHandler();
+		assertSame(h.getLevel(), Level.parse("FINE"));
+		assertTrue(h.getFormatter() instanceof MockFormatter);
+		assertTrue(h.getFilter() instanceof MockFilter);
+		assertEquals(h.getEncoding(), "iso-8859-1");
+	}
 
-    /*
-     * Test the constructor with invalid relevant log manager properties are
-     * set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with invalid relevant log manager properties are set.",
-        method = "ConsoleHandler",
-        args = {}
-    )
-    public void testConstructor_InvalidProperties() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.level", INVALID_LEVEL);
-        p.put("java.util.logging.ConsoleHandler.filter", className);
-        p.put("java.util.logging.ConsoleHandler.formatter", className);
-        p.put("java.util.logging.ConsoleHandler.encoding", "XXXX");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with invalid relevant log manager properties are
+	 * set.
+	 */
+	public void testConstructor_InvalidProperties() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.level", INVALID_LEVEL);
+		p.put("java.util.logging.ConsoleHandler.filter", className);
+		p.put("java.util.logging.ConsoleHandler.formatter", className);
+		p.put("java.util.logging.ConsoleHandler.encoding", "XXXX");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.level"), INVALID_LEVEL);
-        assertEquals(LogManager.getLogManager().getProperty(
-                "java.util.logging.ConsoleHandler.encoding"), "XXXX");
-        ConsoleHandler h = new ConsoleHandler();
-        assertSame(h.getLevel(), Level.INFO);
-        assertTrue(h.getFormatter() instanceof SimpleFormatter);
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-        h.publish(new LogRecord(Level.SEVERE, "test"));
-        assertNull(h.getEncoding());
-    }
+		assertEquals(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.level"), INVALID_LEVEL);
+		assertEquals(LogManager.getLogManager().getProperty(
+				"java.util.logging.ConsoleHandler.encoding"), "XXXX");
+		ConsoleHandler h = new ConsoleHandler();
+		assertSame(h.getLevel(), Level.INFO);
+		assertTrue(h.getFormatter() instanceof SimpleFormatter);
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+		h.publish(new LogRecord(Level.SEVERE, "test"));
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test close() when having sufficient privilege, and a record has been
-     * written to the output stream.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having sufficient privilege, and a record has been written to the output stream.",
-        method = "close",
-        args = {}
-    )
-    public void testClose_SufficientPrivilege_NormalClose() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        h.publish(new LogRecord(Level.SEVERE,
-                "testClose_SufficientPrivilege_NormalClose msg"));
-        h.close();
-        assertEquals("flush", CallVerificationStack.getInstance()
-                .getCurrentSourceMethod());
-        assertNull(CallVerificationStack.getInstance().pop());
-        h.close();
-    }
+	/*
+	 * Test close() when having sufficient privilege, and a record has been
+	 * written to the output stream.
+	 */
+	public void testClose_SufficientPrivilege_NormalClose() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		h.publish(new LogRecord(Level.SEVERE,
+				"testClose_SufficientPrivilege_NormalClose msg"));
+		h.close();
+		assertEquals("flush", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		assertNull(CallVerificationStack.getInstance().pop());
+		h.close();
+	}
 
-    /*
-     * Test close() when having sufficient privilege, and an output stream that
-     * always throws exceptions.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having sufficient privilege, and an output stream that always throws exceptions",
-        method = "close",
-        args = {}
-    )
-    public void testClose_SufficientPrivilege_Exception() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
+	/*
+	 * Test close() when having sufficient privilege, and an output stream that
+	 * always throws exceptions.
+	 */
+	public void testClose_SufficientPrivilege_Exception() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
 
-        h.publish(new LogRecord(Level.SEVERE,
-                "testClose_SufficientPrivilege_Exception msg"));
-        h.flush();
-        h.close();
-    }
+		h.publish(new LogRecord(Level.SEVERE,
+				"testClose_SufficientPrivilege_Exception msg"));
+		h.flush();
+		h.close();
+	}
 
-    /*
-     * Test close() when having sufficient privilege, and no record has been
-     * written to the output stream.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks close() when having sufficient privilege, and no record has been written to the output stream",
-        method = "close",
-        args = {}
-    )
-    public void testClose_SufficientPrivilege_DirectClose() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
+	/*
+	 * Test close() when having sufficient privilege, and no record has been
+	 * written to the output stream.
+	 */
+	public void testClose_SufficientPrivilege_DirectClose() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
 
-        h.close();
-        assertEquals("flush", CallVerificationStack.getInstance()
-                .getCurrentSourceMethod());
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-    }
+		h.close();
+		assertEquals("flush", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+	}
 
-    /*
-     * Test close() when having insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when insufficient privilege is set up.",
-        method = "close",
-        args = {}
-    )
-    public void testClose_InsufficientPrivilege() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        try {
-            h.close();
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+	/*
+	 * Test close() when having insufficient privilege.
+	 */
+	public void testClose_InsufficientPrivilege() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		try {
+			h.close();
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Test publish(), use no filter, having output stream, normal log record.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), use no filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_NoFilter() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
+	/*
+	 * Test publish(), use no filter, having output stream, normal log record.
+	 */
+	public void testPublish_NoFilter() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
 
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
-        h.setLevel(Level.INFO);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter",
-                this.errSubstituteStream.toString());
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
+		h.setLevel(Level.INFO);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter",
+				this.errSubstituteStream.toString());
 
-        h.setLevel(Level.WARNING);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter",
-                this.errSubstituteStream.toString());
+		h.setLevel(Level.WARNING);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter",
+				this.errSubstituteStream.toString());
 
-        h.setLevel(Level.CONFIG);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
-                + "testPublish_NoFilter", this.errSubstituteStream.toString());
+		h.setLevel(Level.CONFIG);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+				+ "testPublish_NoFilter", this.errSubstituteStream.toString());
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
-                + "testPublish_NoFilter", this.errSubstituteStream.toString());
-    }
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+				+ "testPublish_NoFilter", this.errSubstituteStream.toString());
+	}
 
-    /*
-     * Test publish(), after system err is reset.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), after system err is reset.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_AfterResetSystemErr() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        h.setFilter(new MockFilter());
+	/*
+	 * Test publish(), after system err is reset.
+	 */
+	public void testPublish_AfterResetSystemErr() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		h.setFilter(new MockFilter());
 
-        System.setErr(new PrintStream(new ByteArrayOutputStream()));
+		System.setErr(new PrintStream(new ByteArrayOutputStream()));
 
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
-        h.setLevel(Level.INFO);
-        h.publish(r);
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertEquals("", this.errSubstituteStream.toString());
-    }
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+		h.setLevel(Level.INFO);
+		h.publish(r);
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertEquals("", this.errSubstituteStream.toString());
+	}
 
-    /*
-     * Test publish(), use a filter, having output stream, normal log record.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies  publish(), use a filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_WithFilter() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        h.setFilter(new MockFilter());
+	/*
+	 * Test publish(), use a filter, having output stream, normal log record.
+	 */
+	public void testPublish_WithFilter() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		h.setFilter(new MockFilter());
 
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
-        h.setLevel(Level.INFO);
-        h.publish(r);
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertEquals("", this.errSubstituteStream.toString());
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+		h.setLevel(Level.INFO);
+		h.publish(r);
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertEquals("", this.errSubstituteStream.toString());
 
-        h.setLevel(Level.WARNING);
-        h.publish(r);
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-        assertEquals("", this.errSubstituteStream.toString());
+		h.setLevel(Level.WARNING);
+		h.publish(r);
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+		assertEquals("", this.errSubstituteStream.toString());
 
-        h.setLevel(Level.CONFIG);
-        h.publish(r);
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertEquals("", this.errSubstituteStream.toString());
+		h.setLevel(Level.CONFIG);
+		h.publish(r);
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertEquals("", this.errSubstituteStream.toString());
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        h.publish(r);
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertEquals("", this.errSubstituteStream.toString());
-        assertTrue(CallVerificationStack.getInstance().empty());
-    }
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		h.publish(r);
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertEquals("", this.errSubstituteStream.toString());
+		assertTrue(CallVerificationStack.getInstance().empty());
+	}
 
-    /*
-     * Test publish(), null log record, having output stream, spec said
-     * rather than throw exception, handler should call errormanager to handle
-     * exception case, so NullPointerException shouldn't be thrown.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), null log record, having output stream, spec said rather than throw exception, handler should call errormanager to handle exception case, so NullPointerException shouldn't be thrown.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_Null() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        h.publish(null);
-    }
+	/*
+	 * Test publish(), null log record, having output stream, spec said
+	 * rather than throw exception, handler should call errormanager to handle
+	 * exception case, so NullPointerException shouldn't be thrown.
+	 */
+	public void testPublish_Null() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		h.publish(null);
+	}
 
-    /*
-     * Test publish(), a log record with empty msg, having output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), a log record with empty msg, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_EmptyMsg() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        LogRecord r = new LogRecord(Level.INFO, "");
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head", this.errSubstituteStream.toString());
-    }
+	/*
+	 * Test publish(), a log record with empty msg, having output stream
+	 */
+	public void testPublish_EmptyMsg() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		LogRecord r = new LogRecord(Level.INFO, "");
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head", this.errSubstituteStream.toString());
+	}
 
-    /*
-     * Test publish(), a log record with null msg, having output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), a log record with null msg, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_NullMsg() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.ConsoleHandler.formatter", className
-                + "$MockFormatter");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
-        ConsoleHandler h = new ConsoleHandler();
-        LogRecord r = new LogRecord(Level.INFO, null);
-        h.publish(r);
-        h.flush();
-        // assertEquals("MockFormatter_Head",
-        // this.errSubstituteStream.toString());
-    }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish method after close.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_AfterClose() throws Exception {
-        PrintStream backup = System.err;
-        try {
-            ByteArrayOutputStream bos = new ByteArrayOutputStream();
-            System.setErr(new PrintStream(bos));
-            Properties p = new Properties();
-            p.put("java.util.logging.ConsoleHandler.level", "FINE");
-            p.put("java.util.logging.ConsoleHandler.formatter", className
-                    + "$MockFormatter");
-            LogManager.getLogManager().readConfiguration(
-                    EnvironmentHelper.PropertiesToInputStream(p));
-            ConsoleHandler h = new ConsoleHandler();
-            assertSame(h.getLevel(), Level.FINE);
-            LogRecord r1 = new LogRecord(Level.INFO, "testPublish_Record1");
-            LogRecord r2 = new LogRecord(Level.INFO, "testPublish_Record2");
-            assertTrue(h.isLoggable(r1));
-            h.publish(r1);
-            assertTrue(bos.toString().indexOf("testPublish_Record1") >= 0);
-            h.close();
-            // assertFalse(h.isLoggable(r));
-            assertTrue(h.isLoggable(r2));
-            h.publish(r2);
-            assertTrue(bos.toString().indexOf("testPublish_Record2") >= 0);
-            h.flush();
-            // assertEquals("MockFormatter_Head",
-            // this.errSubstituteStream.toString());
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            System.setErr(backup);
-        }
-    }
+	/*
+	 * Test publish(), a log record with null msg, having output stream
+	 */
+	public void testPublish_NullMsg() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.ConsoleHandler.formatter", className
+				+ "$MockFormatter");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
+		ConsoleHandler h = new ConsoleHandler();
+		LogRecord r = new LogRecord(Level.INFO, null);
+		h.publish(r);
+		h.flush();
+		// assertEquals("MockFormatter_Head",
+		// this.errSubstituteStream.toString());
+	}
 
-    /*
-     * Test setOutputStream() under normal condition.
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies setOutputStream() under normal condition.",
-        method = "setOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void testSetOutputStream_Normal() {
-        MockStreamHandler h = new MockStreamHandler();
-        h.setFormatter(new MockFormatter());
+	public void testPublish_AfterClose() throws Exception {
+		PrintStream backup = System.err;
+		try {
+			ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			System.setErr(new PrintStream(bos));
+			Properties p = new Properties();
+			p.put("java.util.logging.ConsoleHandler.level", "FINE");
+			p.put("java.util.logging.ConsoleHandler.formatter", className
+					+ "$MockFormatter");
+			LogManager.getLogManager().readConfiguration(
+					EnvironmentHelper.PropertiesToInputStream(p));
+			ConsoleHandler h = new ConsoleHandler();
+			assertSame(h.getLevel(), Level.FINE);
+			LogRecord r1 = new LogRecord(Level.INFO, "testPublish_Record1");
+			LogRecord r2 = new LogRecord(Level.INFO, "testPublish_Record2");
+			assertTrue(h.isLoggable(r1));
+			h.publish(r1);
+			assertTrue(bos.toString().indexOf("testPublish_Record1") >= 0);
+			h.close();
+			// assertFalse(h.isLoggable(r));
+			assertTrue(h.isLoggable(r2));
+			h.publish(r2);
+			assertTrue(bos.toString().indexOf("testPublish_Record2") >= 0);
+			h.flush();
+			// assertEquals("MockFormatter_Head",
+			// this.errSubstituteStream.toString());
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			System.setErr(backup);
+		}
+	}
 
-        LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
-        h.publish(r);
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal",
-                this.errSubstituteStream.toString());
+	/*
+	 * Test setOutputStream() under normal condition.
+	 */
+	public void testSetOutputStream_Normal() {
+		MockStreamHandler h = new MockStreamHandler();
+		h.setFormatter(new MockFormatter());
 
-        ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
-        h.setOutputStream(aos2);
+		LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
+		h.publish(r);
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal",
+				this.errSubstituteStream.toString());
 
-        // assertEquals("close", DelegationParameterStack.getInstance()
-        // .getCurrentSourceMethod());
-        // assertNull(DelegationParameterStack.getInstance().pop());
-        // assertEquals("flush", DelegationParameterStack.getInstance()
-        // .getCurrentSourceMethod());
-        // assertNull(DelegationParameterStack.getInstance().pop());
-        // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
-        // + "MockFormatter_Tail", this.errSubstituteStream.toString());
-        // r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
-        // h.publish(r);
-        // assertSame(r, DelegationParameterStack.getInstance().pop());
-        // assertTrue(DelegationParameterStack.getInstance().empty());
-        // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2",
-        // aos2
-        // .toString());
-        // assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
-        // + "MockFormatter_Tail", this.errSubstituteStream.toString());
-    }
+		ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
+		h.setOutputStream(aos2);
 
-    /*
-     * A mock filter, always return false.
-     */
-    public static class MockFilter implements Filter {
+		// assertEquals("close", DelegationParameterStack.getInstance()
+		// .getCurrentSourceMethod());
+		// assertNull(DelegationParameterStack.getInstance().pop());
+		// assertEquals("flush", DelegationParameterStack.getInstance()
+		// .getCurrentSourceMethod());
+		// assertNull(DelegationParameterStack.getInstance().pop());
+		// assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+		// + "MockFormatter_Tail", this.errSubstituteStream.toString());
+		// r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
+		// h.publish(r);
+		// assertSame(r, DelegationParameterStack.getInstance().pop());
+		// assertTrue(DelegationParameterStack.getInstance().empty());
+		// assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2",
+		// aos2
+		// .toString());
+		// assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+		// + "MockFormatter_Tail", this.errSubstituteStream.toString());
+	}
 
-        public boolean isLoggable(LogRecord record) {
-            CallVerificationStack.getInstance().push(record);
-            // System.out.println("filter called...");
-            return false;
-        }
-    }
+	/*
+	 * A mock filter, always return false.
+	 */
+	public static class MockFilter implements Filter {
 
-    /*
-     * A mock formatter.
-     */
-    public static class MockFormatter extends Formatter {
-        public String format(LogRecord r) {
-            // System.out.println("formatter called...");
-            return super.formatMessage(r);
-        }
+		public boolean isLoggable(LogRecord record) {
+			CallVerificationStack.getInstance().push(record);
+			// System.out.println("filter called...");
+			return false;
+		}
+	}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
-         */
-        public String getHead(Handler h) {
-            return "MockFormatter_Head";
-        }
+	/*
+	 * A mock formatter.
+	 */
+	public static class MockFormatter extends Formatter {
+		public String format(LogRecord r) {
+			// System.out.println("formatter called...");
+			return super.formatMessage(r);
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
-         */
-        public String getTail(Handler h) {
-            return "MockFormatter_Tail";
-        }
-    }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
+		 */
+		public String getHead(Handler h) {
+			return "MockFormatter_Head";
+		}
 
-    /*
-     * A mock output stream.
-     */
-    public static class MockOutputStream extends ByteArrayOutputStream {
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
+		 */
+		public String getTail(Handler h) {
+			return "MockFormatter_Tail";
+		}
+	}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#close()
-         */
-        public void close() throws IOException {
-            CallVerificationStack.getInstance().push(null);
-            super.close();
-        }
+	/*
+	 * A mock output stream.
+	 */
+	public static class MockOutputStream extends ByteArrayOutputStream {
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#flush()
-         */
-        public void flush() throws IOException {
-            CallVerificationStack.getInstance().push(null);
-            super.flush();
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#close()
+		 */
+		public void close() throws IOException {
+			CallVerificationStack.getInstance().push(null);
+			super.close();
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#write(int)
-         */
-        public void write(int oneByte) {
-            // TODO Auto-generated method stub
-            super.write(oneByte);
-        }
-    }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#flush()
+		 */
+		public void flush() throws IOException {
+			CallVerificationStack.getInstance().push(null);
+			super.flush();
+		}
 
-    /*
-     * Used to grant all permissions except logging control.
-     */
-    public static class MockSecurityManager extends SecurityManager {
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#write(int)
+		 */
+		public void write(int oneByte) {
+			// TODO Auto-generated method stub
+			super.write(oneByte);
+		}
+	}
 
-        public MockSecurityManager() {
-        }
+	/*
+	 * Used to grant all permissions except logging control.
+	 */
+	public static class MockSecurityManager extends SecurityManager {
 
-        public void checkPermission(Permission perm) {
-            // grant all permissions except logging control
-            if (perm instanceof LoggingPermission) {
-                throw new SecurityException();
-            }
-        }
+		public MockSecurityManager() {
+		}
 
-        public void checkPermission(Permission perm, Object context) {
-            // grant all permissions except logging control
-            if (perm instanceof LoggingPermission) {
-                throw new SecurityException();
-            }
-        }
-    }
+		public void checkPermission(Permission perm) {
+			// grant all permissions except logging control
+			if (perm instanceof LoggingPermission) {
+				throw new SecurityException();
+			}
+		}
 
-    /*
-     * A mock stream handler, expose setOutputStream.
-     */
-    public static class MockStreamHandler extends ConsoleHandler {
-        public MockStreamHandler() {
-            super();
-        }
+		public void checkPermission(Permission perm, Object context) {
+			// grant all permissions except logging control
+			if (perm instanceof LoggingPermission) {
+				throw new SecurityException();
+			}
+		}
+	}
 
-        public void setOutputStream(OutputStream out) {
-            super.setOutputStream(out);
-        }
+	/*
+	 * A mock stream handler, expose setOutputStream.
+	 */
+	public static class MockStreamHandler extends ConsoleHandler {
+		public MockStreamHandler() {
+			super();
+		}
 
-        public boolean isLoggable(LogRecord r) {
-            CallVerificationStack.getInstance().push(r);
-            return super.isLoggable(r);
-        }
-    }
+		public void setOutputStream(OutputStream out) {
+			super.setOutputStream(out);
+		}
+
+		public boolean isLoggable(LogRecord r) {
+			CallVerificationStack.getInstance().push(r);
+			return super.isLoggable(r);
+		}
+	}
 
 }
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java
index 3185351..d8c0053 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/ErrorManagerTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
@@ -31,7 +26,6 @@
 import java.io.PrintStream;
 import java.util.logging.ErrorManager;
 
-@TestTargetClass(ErrorManager.class)
 public class ErrorManagerTest extends TestCase {
     
     
@@ -53,12 +47,6 @@
     }
     
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies positive case only with ErrorManager.GENERIC_FAILURE, impove MockStream",
-        method = "error",
-        args = {java.lang.String.class, java.lang.Exception.class, int.class}
-    )
     public void test_errorCheck() {
         ErrorManager em = new ErrorManager();
         MockStream aos = new MockStream();
@@ -71,12 +59,6 @@
        assertTrue("message appears (supertest)", aos.getWrittenData().indexOf("supertest") != -1);
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies positive case only with ErrorManager.GENERIC_FAILURE",
-        method = "error",
-        args = {java.lang.String.class, java.lang.Exception.class, int.class}
-    )
     public void test_errorStringStringint() {
         ErrorManager em = new ErrorManager();
         em.error(null, new NullPointerException(),
@@ -85,12 +67,6 @@
         em.error(null, null, ErrorManager.GENERIC_FAILURE);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ErrorManager",
-        args = {}
-    )
     public void test_constants() {
         assertEquals(3, ErrorManager.CLOSE_FAILURE);
         assertEquals(2, ErrorManager.FLUSH_FAILURE);
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
index e4ef413..da0111b 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FileHandlerTest.java
@@ -17,12 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -54,7 +48,6 @@
 
 /**
  */
-@TestTargetClass(FileHandler.class) 
 public class FileHandlerTest extends TestCase {
 
     static LogManager manager = LogManager.getLogManager();
@@ -133,12 +126,6 @@
     /*
      * test for constructor void FileHandler()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify exceptions.",
-        method = "FileHandler",
-        args = {}
-    )
     public void testFileHandler() throws Exception {
         assertEquals("character encoding is non equal to actual value",
                 "iso-8859-1", handler.getEncoding());
@@ -164,12 +151,6 @@
     /*
      * test for constructor void FileHandler(String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify security exception.",
-        method = "FileHandler",
-        args = {java.lang.String.class}
-    )
     public void testFileHandler_1params() throws Exception {
 
         handler = new FileHandler("%t/log/string");
@@ -253,12 +234,6 @@
     /*
      * test for constructor void FileHandler(String pattern, boolean append)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify security exception.",
-        method = "FileHandler",
-        args = {java.lang.String.class, boolean.class}
-    )
     public void testFileHandler_2params() throws Exception {
         boolean append = false;
         do {
@@ -302,12 +277,6 @@
      * test for constructor void FileHandler(String pattern, int limit, int
      * count)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verifysecurity exception.",
-        method = "FileHandler",
-        args = {java.lang.String.class, int.class, int.class}
-    )
     public void testFileHandler_3params() throws Exception {
         int limit = 120;
         int count = 1;
@@ -357,12 +326,6 @@
      * test for constructor public FileHandler(String pattern, int limit, int
      * count, boolean append)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify security exception.",
-        method = "FileHandler",
-        args = {java.lang.String.class, int.class, int.class, boolean.class}
-    )
     public void testFileHandler_4params() throws Exception {
         int limit = 120;
         int count = 1;
@@ -417,38 +380,6 @@
             //expected
         }
     }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getEncoding",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getFormatter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getErrorManager",
-            args = {}
-        )
-    })
     public void testDefaultValue() throws Exception {
         handler.publish(r);
         handler.close();
@@ -553,12 +484,6 @@
             e.printStackTrace();
         }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "FileHandler",
-        args = {java.lang.String.class, int.class, int.class, boolean.class}
-    )
     public void testLimitAndCount() throws Exception {
         handler.close();
         // very small limit value, count=2
@@ -641,44 +566,6 @@
             reset("log", "");
         }
     }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "close",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "FileHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "FileHandler",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "FileHandler",
-            args = {java.lang.String.class, boolean.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "FileHandler",
-            args = {java.lang.String.class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "FileHandler",
-            args = {java.lang.String.class, int.class, int.class, boolean.class}
-        )
-    })
     public void testSecurity() throws IOException {
         SecurityManager currentManager = System.getSecurityManager();
 
@@ -722,44 +609,6 @@
         }
 
     }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "close",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "FileHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "FileHandler",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "FileHandler",
-            args = {java.lang.String.class, boolean.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "FileHandler",
-            args = {java.lang.String.class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "FileHandler",
-            args = {java.lang.String.class, int.class, int.class, boolean.class}
-        )
-    })
     public void testFileSecurity() throws IOException {
         SecurityManager currentManager = System.getSecurityManager();
 
@@ -802,12 +651,6 @@
             System.setSecurityManager(currentManager);
         }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies FileHandler when configuration file is invalid.",
-        method = "FileHandler",
-        args = {}
-    )
     public void testInvalidProperty() throws Exception {
         props.put("java.util.logging.FileHandler.level", "null");
         props.put("java.util.logging.FileHandler.filter", className
@@ -842,33 +685,7 @@
         } catch (NullPointerException e) {
         }
     }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
-            method = "FileHandler",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
-            method = "FileHandler",
-            args = {java.lang.String.class, boolean.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
-            method = "FileHandler",
-            args = {java.lang.String.class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies illegal parameters and exceptions: IOException, NullPointerException, IllegalArgumentException.",
-            method = "publish",
-            args = {java.util.logging.LogRecord.class}
-        )
-    })
-    @AndroidOnly("This test fails on RI. Doesn't parse special pattern \"%t/%h.")
+    // This test fails on RI. Doesn't parse special pattern \"%t/%h."
     public void testInvalidParams() throws IOException {
 
         // %t and %p parsing can add file separator automatically
@@ -987,12 +804,6 @@
     /*
      * test for method public void publish(LogRecord record)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish() throws Exception {
         LogRecord[] r = new LogRecord[] { new LogRecord(Level.CONFIG, "msg__"),
                 new LogRecord(Level.WARNING, "message"),
@@ -1010,12 +821,6 @@
     /*
      * test for method public void close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
     public void testClose() throws Exception {
         FileHandler h = new FileHandler("%t/log/stringPublish");
         h.publish(r);
@@ -1023,12 +828,6 @@
         assertFileContent(TEMPPATH + SEP + "log", "stringPublish", h
                 .getFormatter());
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't verify SecurityException.",
-        method = "setOutputStream",
-        args = {java.io.OutputStream.class}
-    )
     // set output stream still works, just like super StreamHandler
     public void testSetOutputStream() throws Exception {
         MockFileHandler handler = new MockFileHandler("%h/setoutput.log");
@@ -1045,12 +844,6 @@
         assertFileContent(HOMEPATH, "setoutput.log", handler.getFormatter());
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IllegalArgumentException.",
-        method = "FileHandler",
-        args = {java.lang.String.class, int.class, int.class}
-    )
     public void testEmptyPattern_3params() throws SecurityException,
             IOException {
         try {
@@ -1060,12 +853,6 @@
             // Expected
         }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IllegalArgumentException.",
-        method = "FileHandler",
-        args = {java.lang.String.class, boolean.class}
-    )
     public void testEmptyPattern_2params() throws SecurityException,
             IOException {
         try {
@@ -1075,12 +862,6 @@
             // Expected
         }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IllegalArgumentException.",
-        method = "FileHandler",
-        args = {java.lang.String.class, int.class, int.class, boolean.class}
-    )
     public void testEmptyPattern_4params() throws SecurityException,
             IOException {
         try {
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java
index d7ce843..1d105e0 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FilterTest.java
@@ -15,26 +15,8 @@
  * limitations under the License.
  */
 
-//TODO :
-/*
- * 1. Don't forget to write tests for org.apache.harmony.logging.internal.nls/Messages.java this file is in logging/src/main/java folder
- * 2. inrteface filter / LoggingMXBean tests machen
- * 3. XMLFormatter.java should be finish for Monday (not a lot to do) but as I beginn want to finish.  
- * 3. In my case
- *    I didn't use the PARTIAL_OK, so I believe that 98% of COMPLETE are PARTIAL_OK
- *    COMPLETE = Tests finish and should be working. If error check the test before to make a ticket.
- *    PARTIAL = Tests finish, but need special reviewing
- *    TODO = A test to do (or not). Mostly a test to complete
- * 4. For questions christian.wiederseiner
- */
-
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.util.logging.Filter;
 import java.util.logging.LogRecord;
 
@@ -44,26 +26,19 @@
  * This testcase verifies the signature of the interface Filter.
  * 
  */
-@TestTargetClass(Filter.class) 
 public class FilterTest extends TestCase {
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies interface.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testFilter() {
-        MockFilter f = new MockFilter();
-        assertFalse(f.isLoggable(null));
-    }
+	public void testFilter() {
+		MockFilter f = new MockFilter();
+		f.isLoggable(null);
+	}
 
-    /*
-     * This inner class implements the interface Filter to verify the signature.
-     */
-    private class MockFilter implements Filter {
+	/*
+	 * This inner class implements the interface Filter to verify the signature.
+	 */
+	private class MockFilter implements Filter {
 
-        public boolean isLoggable(LogRecord record) {
-            return false;
-        }
-    }
+		public boolean isLoggable(LogRecord record) {
+			return false;
+		}
+	}
 }
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
index ba2345d..47b9170 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/FormatterTest.java
@@ -17,12 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-
 import java.io.File;
 import java.text.MessageFormat;
 import java.util.Locale;
@@ -40,7 +34,6 @@
 
 import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
 
-@TestTargetClass(Formatter.class) 
 public class FormatterTest extends TestCase {
     Formatter f;
 
@@ -97,26 +90,6 @@
     /*
      * test for constructor protected Formatter()
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "Formatter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getHead",
-            args = {java.util.logging.Handler.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getTail",
-            args = {java.util.logging.Handler.class}
-        )
-    })
     public void testFormatter() {
         assertEquals("head string is not empty", "", f.getHead(null));
         assertEquals("tail string is not empty", "", f.getTail(null));
@@ -126,12 +99,6 @@
     /*
      * test for method public String getHead(Handler h)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getHead",
-        args = {Handler.class}
-    )
     public void testGetHead() {
         assertEquals("head string is not empty", "", f.getHead(null));
         assertEquals("head string is not empty", "", f.getHead(h));
@@ -142,12 +109,6 @@
     /*
      * test for method public String getTail(Handler h)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getTail",
-        args = {Handler.class}
-    )
     public void testGetTail() {
         assertEquals("tail string is not empty", "", f.getTail(null));
         assertEquals("tail string is not empty", "", f.getTail(h));
@@ -155,16 +116,10 @@
         assertEquals("tail string is not empty", "", f.getTail(h));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "formatMessage",
-        args = {LogRecord.class}
-    )
-    @AndroidOnly("The RI fails in this test because it uses a MessageFormat " +
-            "to format the message even though it doesn't contain \"{0\". " +
-            "The spec says that this would indicate that a MessageFormat " +
-            "should be used and else no formatting should be done.")
+    // The RI fails in this test because it uses a MessageFormat
+    // to format the message even though it doesn't contain "{0".
+    // The spec says that this would indicate that a MessageFormat
+    // should be used and else no formatting should be done.
     public void testFormatMessage() {
         assertEquals(MSG, f.formatMessage(r));
 
@@ -200,12 +155,6 @@
         assertEquals(pattern, f.formatMessage(r));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "formatMessage",
-        args = {LogRecord.class}
-    )
     public void testLocalizedFormatMessage() {
         // normal case
         r.setMessage("msg");
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
index 5868b1f..2f13f2d 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/HandlerTest.java
@@ -17,16 +17,10 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.security.Permission;
-import java.util.EmptyStackException;
 import java.util.Properties;
 import java.util.logging.ErrorManager;
 import java.util.logging.Filter;
@@ -46,730 +40,551 @@
  * Test suite for the class java.util.logging.Handler.
  * 
  */
-@TestTargetClass(Handler.class) 
 public class HandlerTest extends TestCase {
-    private static String className = HandlerTest.class.getName();
+	private static String className = HandlerTest.class.getName();
 
-    /*
-     * @see TestCase#tearDown()
-     */
-    protected void tearDown() throws Exception {
-        super.tearDown();
+	/*
+	 * @see TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+	}
+
+	/*
+	 * @see TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		super.tearDown();
         CallVerificationStack.getInstance().clear();
-    }
+	}
 
-    /*
-     * Test the constructor.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "Handler",
-        args = {}
-    )
-    public void testConstructor() {
-        MockHandler h = new MockHandler();
-        assertSame(h.getLevel(), Level.ALL);
-        assertNull(h.getFormatter());
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-        assertTrue(h.getErrorManager() instanceof ErrorManager);
-    }
+	/**
+	 * Constructor for HandlerTest.
+	 * 
+	 * @param arg0
+	 */
+	public HandlerTest(String arg0) {
+		super(arg0);
+	}
 
-    /*
-     * Test the constructor, with properties set
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "Handler",
-        args = {}
-    )
-    public void testConstructor_Properties() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.MockHandler.level", "FINE");
-        p.put("java.util.logging.MockHandler.filter", className
-                + "$MockFilter");
-        p.put("java.util.logging.Handler.formatter", className
-                + "$MockFormatter");
-        p.put("java.util.logging.MockHandler.encoding", "utf-8");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor.
+	 */
+	public void testConstructor() {
+		MockHandler h = new MockHandler();
+		assertSame(h.getLevel(), Level.ALL);
+		assertNull(h.getFormatter());
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+		assertTrue(h.getErrorManager() instanceof ErrorManager);
+	}
 
-        assertEquals(LogManager.getLogManager().getProperty(
-        "java.util.logging.MockHandler.level"), "FINE");
-        assertEquals(LogManager.getLogManager().getProperty(
-        "java.util.logging.MockHandler.encoding"), "utf-8");
-        MockHandler h = new MockHandler();
-        assertSame(h.getLevel(), Level.ALL);
-        assertNull(h.getFormatter());
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-        assertTrue(h.getErrorManager() instanceof ErrorManager);
-        LogManager.getLogManager().reset();
-    }
+	/*
+	 * Test the constructor, with properties set
+	 */
+	public void testConstructor_Properties() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.MockHandler.level", "FINE");
+		p
+				.put("java.util.logging.MockHandler.filter", className
+						+ "$MockFilter");
+		p.put("java.util.logging.Handler.formatter", className
+				+ "$MockFormatter");
+		p.put("java.util.logging.MockHandler.encoding", "utf-8");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-    /*
-     * Test getEncoding & setEncoding methods with supported encoding.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify exceptions.",
-            method = "getEncoding",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify exceptions.",
-            method = "setEncoding",
-            args = {java.lang.String.class}
-        )
-    })
-    public void testGetSetEncoding_Normal() throws Exception {
-        MockHandler h = new MockHandler();
-        h.setEncoding("iso-8859-1");
-        assertEquals("iso-8859-1", h.getEncoding());
-    }
+		assertEquals(LogManager.getLogManager().getProperty(
+				"java.util.logging.MockHandler.level"), "FINE");
+		assertEquals(LogManager.getLogManager().getProperty(
+				"java.util.logging.MockHandler.encoding"), "utf-8");
+		MockHandler h = new MockHandler();
+		assertSame(h.getLevel(), Level.ALL);
+		assertNull(h.getFormatter());
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+		assertTrue(h.getErrorManager() instanceof ErrorManager);
+		LogManager.getLogManager().reset();
+	}
 
-    /*
-     * Test getEncoding & setEncoding methods with null.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies null as a parameter.",
-        method = "getEncoding",
-        args = {}
-    )
-    public void testGetSetEncoding_Null() throws Exception {
-        MockHandler h = new MockHandler();
-        h.setEncoding(null);
-        assertNull(h.getEncoding());
-    }
+	/*
+	 * Abstract method, no test needed.
+	 */
+	public void testClose() {
+		MockHandler h = new MockHandler();
+		h.close();
+	}
 
-    /*
-     * Test getEncoding & setEncoding methods with unsupported encoding.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies UnsupportedEncodingException.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testGetSetEncoding_Unsupported() {
-        MockHandler h = new MockHandler();
-        try {
-            h.setEncoding("impossible");
-            fail("Should throw UnsupportedEncodingException!");
-        } catch (UnsupportedEncodingException e) {
-        }
-        assertNull(h.getEncoding());
-    }
+	/*
+	 * Abstract method, no test needed.
+	 */
+	public void testFlush() {
+		MockHandler h = new MockHandler();
+		h.flush();
+	}
 
-    /*
-     * Test setEncoding with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify UnsupportedEncodingException.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_InsufficientPrivilege() throws Exception {
-        MockHandler h = new MockHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        // set a normal value
-        try {
-            h.setEncoding("iso-8859-1");
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        assertNull(h.getEncoding());
-        System.setSecurityManager(new MockSecurityManager());
-        // set an invalid value
-        try {
+	/*
+	 * Abstract method, no test needed.
+	 */
+	public void testPublish() {
+		MockHandler h = new MockHandler();
+		h.publish(null);
+	}
 
-            h.setEncoding("impossible");
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        assertNull(h.getEncoding());
-    }
+	/*
+	 * Test getEncoding & setEncoding methods with supported encoding.
+	 */
+	public void testGetSetEncoding_Normal() throws Exception {
+		MockHandler h = new MockHandler();
+		h.setEncoding("iso-8859-1");
+		assertEquals("iso-8859-1", h.getEncoding());
+	}
 
-    /*
-     * Test getErrorManager & setErrorManager methods with non-null value.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "setErrorManager",
-            args = {java.util.logging.ErrorManager.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getErrorManager",
-            args = {}
-        )
-    })
-    public void testGetSetErrorManager_Normal() throws Exception {
-        MockHandler h = new MockHandler();
-        ErrorManager man = new ErrorManager();
-        h.setErrorManager(man);
-        assertSame(man, h.getErrorManager());
-    }
+	/*
+	 * Test getEncoding & setEncoding methods with null.
+	 */
+	public void testGetSetEncoding_Null() throws Exception {
+		MockHandler h = new MockHandler();
+		h.setEncoding(null);
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test getErrorManager & setErrorManager methods with null.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies null as a parameter.",
-            method = "getErrorManager",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies null as a parameter.",
-            method = "setErrorManager",
-            args = {java.util.logging.ErrorManager.class}
-        )
-    })
-    public void testGetSetErrorManager_Null() throws Exception {
-        MockHandler h = new MockHandler();
-        // test set null
-        try {
-            h.setErrorManager(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        }
+	/*
+	 * Test getEncoding & setEncoding methods with unsupported encoding.
+	 */
+	public void testGetSetEncoding_Unsupported() {
+		MockHandler h = new MockHandler();
+		try {
+			h.setEncoding("impossible");
+			fail("Should throw UnsupportedEncodingException!");
+		} catch (UnsupportedEncodingException e) {
+		}
+		assertNull(h.getEncoding());
+	}
 
-        // test reset null
-        try {
-            h.setErrorManager(new ErrorManager());
-            h.setErrorManager(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        }
-    }
+	/*
+	 * Test setEncoding with insufficient privilege.
+	 */
+	public void testSetEncoding_InsufficientPrivilege() throws Exception {
+		MockHandler h = new MockHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		// set a normal value
+		try {
+			h.setEncoding("iso-8859-1");
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		assertNull(h.getEncoding());
+		System.setSecurityManager(new MockSecurityManager());
+		// set an invalid value
+		try {
 
-    /*
-     * Test getErrorManager with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies SecurityException.",
-        method = "getErrorManager",
-        args = {}
-    )
-    public void testGetErrorManager_InsufficientPrivilege() throws Exception {
-        MockHandler h = new MockHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+			h.setEncoding("impossible");
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		assertNull(h.getEncoding());
+	}
 
-        try {
-            h.getErrorManager();
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+	/*
+	 * Test getErrorManager & setErrorManager methods with non-null value.
+	 */
+	public void testGetSetErrorManager_Normal() throws Exception {
+		MockHandler h = new MockHandler();
+		ErrorManager man = new ErrorManager();
+		h.setErrorManager(man);
+		assertSame(man, h.getErrorManager());
+	}
 
-    /*
-     * Test setErrorManager with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setErrorManager with insufficient privilege.",
-        method = "setErrorManager",
-        args = {java.util.logging.ErrorManager.class}
-    )
-    public void testSetErrorManager_InsufficientPrivilege() throws Exception {
-        MockHandler h = new MockHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+	/*
+	 * Test getErrorManager & setErrorManager methods with null.
+	 */
+	public void testGetSetErrorManager_Null() throws Exception {
+		MockHandler h = new MockHandler();
+		// test set null
+		try {
+			h.setErrorManager(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		}
 
-        // set null
-        try {
+		// test reset null
+		try {
+			h.setErrorManager(new ErrorManager());
+			h.setErrorManager(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		}
+	}
 
-            h.setErrorManager(null);
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        // set a normal value
-        System.setSecurityManager(new MockSecurityManager());
-        try {
+	/*
+	 * Test getErrorManager with insufficient privilege.
+	 */
+	public void testGetErrorManager_InsufficientPrivilege() throws Exception {
+		MockHandler h = new MockHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-            h.setErrorManager(new ErrorManager());
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		try {
+			h.getErrorManager();
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Test getFilter & setFilter methods with non-null value.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify SecurityException.",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify SecurityException.",
-            method = "getFilter",
-            args = {}
-        )
-    })
-    public void testGetSetFilter_Normal() throws Exception {
-        MockHandler h = new MockHandler();
-        Filter f = new MockFilter();
-        h.setFilter(f);
-        assertSame(f, h.getFilter());
-    }
+	/*
+	 * Test setErrorManager with insufficient privilege.
+	 */
+	public void testSetErrorManager_InsufficientPrivilege() throws Exception {
+		MockHandler h = new MockHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-    /*
-     * Test getFilter & setFilter methods with null.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies null as a parameter.",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies null as a parameter.",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
-    public void testGetSetFilter_Null() throws Exception {
-        MockHandler h = new MockHandler();
-        // test set null
-        h.setFilter(null);
+		// set null
+		try {
 
-        // test reset null
-        h.setFilter(new MockFilter());
-        h.setFilter(null);
-    }
+			h.setErrorManager(null);
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		// set a normal value
+		System.setSecurityManager(new MockSecurityManager());
+		try {
 
-    /*
-     * Test setFilter with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies SecurityException.",
-        method = "setFilter",
-        args = {java.util.logging.Filter.class}
-    )
-    public void testSetFilter_InsufficientPrivilege() throws Exception {
-        MockHandler h = new MockHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+			h.setErrorManager(new ErrorManager());
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-        // set null
-        try {
+	/*
+	 * Test getFilter & setFilter methods with non-null value.
+	 */
+	public void testGetSetFilter_Normal() throws Exception {
+		MockHandler h = new MockHandler();
+		Filter f = new MockFilter();
+		h.setFilter(f);
+		assertSame(f, h.getFilter());
+	}
 
-            h.setFilter(null);
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        // set a normal value
-        System.setSecurityManager(new MockSecurityManager());
-        try {
+	/*
+	 * Test getFilter & setFilter methods with null.
+	 */
+	public void testGetSetFilter_Null() throws Exception {
+		MockHandler h = new MockHandler();
+		// test set null
+		h.setFilter(null);
 
-            h.setFilter(new MockFilter());
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		// test reset null
+		h.setFilter(new MockFilter());
+		h.setFilter(null);
+	}
 
-    /*
-     * Test getFormatter & setFormatter methods with non-null value.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify SecurityException.",
-            method = "getFormatter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify SecurityException.",
-            method = "setFormatter",
-            args = {java.util.logging.Formatter.class}
-        )
-    })
-    public void testGetSetFormatter_Normal() throws Exception {
-        MockHandler h = new MockHandler();
-        Formatter f = new SimpleFormatter();
-        h.setFormatter(f);
-        assertSame(f, h.getFormatter());
-    }
+	/*
+	 * Test setFilter with insufficient privilege.
+	 */
+	public void testSetFilter_InsufficientPrivilege() throws Exception {
+		MockHandler h = new MockHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-    /*
-     * Test getFormatter & setFormatter methods with null.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies null as a parameter.",
-            method = "getFormatter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies null as a parameter.",
-            method = "setFormatter",
-            args = {java.util.logging.Formatter.class}
-        )
-    })
-    public void testGetSetFormatter_Null() throws Exception {
-        MockHandler h = new MockHandler();
-        // test set null
-        try {
-            h.setFormatter(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        }
+		// set null
+		try {
 
-        // test reset null
-        try {
-            h.setFormatter(new SimpleFormatter());
-            h.setFormatter(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        }
-    }
+			h.setFilter(null);
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		// set a normal value
+		System.setSecurityManager(new MockSecurityManager());
+		try {
 
-    /*
-     * Test setFormatter with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies SecurityException.",
-        method = "getFormatter",
-        args = {}
-    )
-    public void testSetFormatter_InsufficientPrivilege() throws Exception {
-        MockHandler h = new MockHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+			h.setFilter(new MockFilter());
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-        // set null
-        try {
+	/*
+	 * Test getFormatter & setFormatter methods with non-null value.
+	 */
+	public void testGetSetFormatter_Normal() throws Exception {
+		MockHandler h = new MockHandler();
+		Formatter f = new SimpleFormatter();
+		h.setFormatter(f);
+		assertSame(f, h.getFormatter());
+	}
 
-            h.setFormatter(null);
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        // set a normal value
-        System.setSecurityManager(new MockSecurityManager());
-        try {
+	/*
+	 * Test getFormatter & setFormatter methods with null.
+	 */
+	public void testGetSetFormatter_Null() throws Exception {
+		MockHandler h = new MockHandler();
+		// test set null
+		try {
+			h.setFormatter(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		}
 
-            h.setFormatter(new SimpleFormatter());
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		// test reset null
+		try {
+			h.setFormatter(new SimpleFormatter());
+			h.setFormatter(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		}
+	}
 
-    /*
-     * Test getLevel & setLevel methods with non-null value.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify SecurityException.",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify SecurityException.",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
-    public void testGetSetLevel_Normal() throws Exception {
-        MockHandler h = new MockHandler();
-        Level f = Level.CONFIG;
-        h.setLevel(f);
-        assertSame(f, h.getLevel());
-    }
+	/*
+	 * Test setFormatter with insufficient privilege.
+	 */
+	public void testSetFormatter_InsufficientPrivilege() throws Exception {
+		MockHandler h = new MockHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-    /*
-     * Test getLevel & setLevel methods with null.
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies getLevel & setLevel methods with null.",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies getLevel & setLevel methods with null.",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
-    public void testGetSetLevel_Null() throws Exception {
-        MockHandler h = new MockHandler();
-        // test set null
-        try {
-            h.setLevel(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        }
+		// set null
+		try {
 
-        // test reset null
-        try {
-            h.setLevel(Level.CONFIG);
-            h.setLevel(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        }
-    }
+			h.setFormatter(null);
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		// set a normal value
+		System.setSecurityManager(new MockSecurityManager());
+		try {
 
-    /*
-     * Test setLevel with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies  NullPointerException, SecurityException.",
-        method = "setLevel",
-        args = {java.util.logging.Level.class}
-    )
-    public void testSetLevel_InsufficientPrivilege() throws Exception {
-        MockHandler h = new MockHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+			h.setFormatter(new SimpleFormatter());
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-        // set null
-        try {
+	/*
+	 * Test getLevel & setLevel methods with non-null value.
+	 */
+	public void testGetSetLevel_Normal() throws Exception {
+		MockHandler h = new MockHandler();
+		Level f = Level.CONFIG;
+		h.setLevel(f);
+		assertSame(f, h.getLevel());
+	}
 
-            h.setLevel(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        // set a normal value
-        System.setSecurityManager(new MockSecurityManager());
-        try {
+	/*
+	 * Test getLevel & setLevel methods with null.
+	 */
+	public void testGetSetLevel_Null() throws Exception {
+		MockHandler h = new MockHandler();
+		// test set null
+		try {
+			h.setLevel(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		}
 
-            h.setLevel(Level.CONFIG);
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		// test reset null
+		try {
+			h.setLevel(Level.CONFIG);
+			h.setLevel(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		}
+	}
 
-    /*
-     * Use no filter
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_NoFilter() {
-        MockHandler h = new MockHandler();
-        LogRecord r = new LogRecord(Level.CONFIG, null);
-        assertTrue(h.isLoggable(r));
+	/*
+	 * Test setLevel with insufficient privilege.
+	 */
+	public void testSetLevel_InsufficientPrivilege() throws Exception {
+		MockHandler h = new MockHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-        h.setLevel(Level.CONFIG);
-        assertTrue(h.isLoggable(r));
+		// set null
+		try {
 
-        h.setLevel(Level.SEVERE);
-        assertFalse(h.isLoggable(r));
+			h.setLevel(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		// set a normal value
+		System.setSecurityManager(new MockSecurityManager());
+		try {
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        assertFalse(h.isLoggable(r));
-    }
+			h.setLevel(Level.CONFIG);
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Use a filter
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies isLoggable method with filter.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_WithFilter() {
-        MockHandler h = new MockHandler();
-        LogRecord r = new LogRecord(Level.CONFIG, null);
-        LogRecord r1 = new LogRecord(Level.CONFIG, null);
-        LogRecord r2 = new LogRecord(Level.CONFIG, null);
-        
-        h.setFilter(new MockFilter());
-        assertFalse(h.isLoggable(r));
-        assertSame(r,CallVerificationStack.getInstance().pop());
-        
-        h.setLevel(Level.CONFIG);
-        assertFalse(h.isLoggable(r1));
-        assertSame(r1, CallVerificationStack.getInstance().pop());
+	/*
+	 * Use no filter
+	 */
+	public void testIsLoggable_NoFilter() {
+		MockHandler h = new MockHandler();
+		LogRecord r = new LogRecord(Level.CONFIG, null);
+		assertTrue(h.isLoggable(r));
 
-        h.setLevel(Level.SEVERE);
-        assertFalse(h.isLoggable(r2));
-       
-        try{
-            CallVerificationStack.getInstance().pop();
-        }catch(EmptyStackException e){
-            //normal
-        }
-    }
+		h.setLevel(Level.CONFIG);
+		assertTrue(h.isLoggable(r));
 
-    /**
-     * @tests java.util.logging.Handler#isLoggable(LogRecord)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies null as a parameter.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_Null() {
-        MockHandler h = new MockHandler();
-        try {
-            h.isLoggable(null);
-            fail("should throw NullPointerException");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
+		h.setLevel(Level.SEVERE);
+		assertFalse(h.isLoggable(r));
 
-    /*
-     * Test whether the error manager is actually called with expected
-     * parameters.
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reportError",
-        args = {java.lang.String.class, java.lang.Exception.class, int.class}
-    )
-    public void testReportError() {
-        MockHandler h = new MockHandler();
-        h.setErrorManager(new MockErrorManager());
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		assertFalse(h.isLoggable(r));
+	}
 
-        try {
-            Exception ex = new Exception("test exception");
-            // with non-null parameters
-            h.reportError("test msg", ex, -1);
-            assertEquals(-1, CallVerificationStack.getInstance().popInt());
-            assertSame(ex, CallVerificationStack.getInstance().pop());
-            assertEquals("test msg", CallVerificationStack.getInstance().pop());
-            // with null parameters
-            h.reportError(null, null, 0);
-            assertEquals(0, CallVerificationStack.getInstance().popInt());
-            assertSame(null, CallVerificationStack.getInstance().pop());
-            assertNull(CallVerificationStack.getInstance().pop());
-        } catch (SecurityException e) {
-            fail("Should not throw SecurityException!");
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+	/*
+	 * Use a filter
+	 */
+	public void testIsLoggable_WithFilter() {
+		MockHandler h = new MockHandler();
+		LogRecord r = new LogRecord(Level.CONFIG, null);
+		h.setFilter(new MockFilter());
+		assertFalse(h.isLoggable(r));
 
-    /*
-     * Used to enable the testing of Handler because Handler is an abstract
-     * class.
-     */
-    public static class MockHandler extends Handler {
+		h.setLevel(Level.CONFIG);
+		assertFalse(h.isLoggable(r));
+		assertSame(r, CallVerificationStack.getInstance().pop());
 
-        public void close() {
-        }
+		h.setLevel(Level.SEVERE);
+		assertFalse(h.isLoggable(r));
+		assertSame(r, CallVerificationStack.getInstance().pop());
+	}
 
-        public void flush() {
-        }
+	/**
+	 * @tests java.util.logging.Handler#isLoggable(LogRecord)
+	 */
+	public void testIsLoggable_Null() {
+		MockHandler h = new MockHandler();
+		try {
+			h.isLoggable(null);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
 
-        public void publish(LogRecord record) {
-        }
+	/*
+	 * Test whether the error manager is actually called with expected
+	 * parameters.
+	 */
+	public void testReportError() {
+		MockHandler h = new MockHandler();
+		h.setErrorManager(new MockErrorManager());
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-        public void reportError(String msg, Exception ex, int code) {
-            super.reportError(msg, ex, code);
-        }
-    }
+		try {
+			Exception ex = new Exception("test exception");
+			// with non-null parameters
+			h.reportError("test msg", ex, -1);
+			assertEquals(-1, CallVerificationStack.getInstance().popInt());
+			assertSame(ex, CallVerificationStack.getInstance().pop());
+			assertEquals("test msg", CallVerificationStack.getInstance().pop());
+			// with null parameters
+			h.reportError(null, null, 0);
+			assertEquals(0, CallVerificationStack.getInstance().popInt());
+			assertSame(null, CallVerificationStack.getInstance().pop());
+			assertNull(CallVerificationStack.getInstance().pop());
+		} catch (SecurityException e) {
+			fail("Should not throw SecurityException!");
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Used to grant all permissions except logging control.
-     */
-    public static class MockSecurityManager extends SecurityManager {
+	/*
+	 * Used to enable the testing of Handler because Handler is an abstract
+	 * class.
+	 */
+	public static class MockHandler extends Handler {
 
-        public MockSecurityManager() {
-        }
+		public void close() {
+		}
 
-        public void checkPermission(Permission perm) {
-            // grant all permissions except logging control
-            if (perm instanceof LoggingPermission) {
-                throw new SecurityException();
-            }
-        }
+		public void flush() {
+		}
 
-        public void checkPermission(Permission perm, Object context) {
-            // grant all permissions except logging control
-            if (perm instanceof LoggingPermission) {
-                throw new SecurityException();
-            }
-        }
-    }
+		public void publish(LogRecord record) {
+		}
 
-    /*
-     * A mock filter, always return false.
-     */
-    public static class MockFilter implements Filter {
+		public void reportError(String msg, Exception ex, int code) {
+			super.reportError(msg, ex, code);
+		}
+	}
 
-        public boolean isLoggable(LogRecord record) {
-            CallVerificationStack.getInstance().push(record);
-            return false;
-        }
-    }
+	/*
+	 * Used to grant all permissions except logging control.
+	 */
+	public static class MockSecurityManager extends SecurityManager {
 
-    /*
-     * A mock error manager, used to validate the expected method is called with
-     * the expected parameters.
-     */
-    public static class MockErrorManager extends ErrorManager {
+		public MockSecurityManager() {
+		}
 
-        public void error(String msg, Exception ex, int errorCode) {
-            CallVerificationStack.getInstance().push(msg);
-            CallVerificationStack.getInstance().push(ex);
-            CallVerificationStack.getInstance().push(errorCode);
-        }
-    }
+		public void checkPermission(Permission perm) {
+			// grant all permissions except logging control
+			if (perm instanceof LoggingPermission) {
+				throw new SecurityException();
+			}
+		}
+
+		public void checkPermission(Permission perm, Object context) {
+			// grant all permissions except logging control
+			if (perm instanceof LoggingPermission) {
+				throw new SecurityException();
+			}
+		}
+	}
+
+	/*
+	 * A mock filter, always return false.
+	 */
+	public static class MockFilter implements Filter {
+
+		public boolean isLoggable(LogRecord record) {
+			CallVerificationStack.getInstance().push(record);
+			return false;
+		}
+	}
+
+	/*
+	 * A mock error manager, used to validate the expected method is called with
+	 * the expected parameters.
+	 */
+	public static class MockErrorManager extends ErrorManager {
+
+		public void error(String msg, Exception ex, int errorCode) {
+			CallVerificationStack.getInstance().push(msg);
+			CallVerificationStack.getInstance().push(ex);
+			CallVerificationStack.getInstance().push(errorCode);
+		}
+	}
     
     public static class NullOutputStream extends OutputStream{
         @Override
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java
index 1fee1ba..2dbe206 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-
 import java.io.Serializable;
 import java.util.ResourceBundle;
 import java.util.logging.Handler;
@@ -36,7 +31,6 @@
  * This class implements Serializable, so that the non-static inner class
  * MockLevel can be Serializable.
  */
-@TestTargetClass(Level.class) 
 public class LevelTest extends TestCase implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -45,20 +39,6 @@
      * Test the constructor without resource bundle parameter using normal
      * values. As byproducts, getName & intValue are also tested.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks  the constructor without resource bundle parameter using normal values.",
-            method = "Level",
-            args = {java.lang.String.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks  the constructor without resource bundle parameter using normal values.",
-            method = "getName",
-            args = {}
-        )
-    })
     public void testConstructorNoResBundle_Normal() {
         MockLevel l = new MockLevel("level1", 1);
         assertEquals("level1", l.getName());
@@ -70,20 +50,6 @@
      * Test the constructor without resource bundle parameter using null name.
      * As byproducts, getName & intValue are also tested.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks the constructor without resource bundle parameter using null name.",
-            method = "Level",
-            args = {java.lang.String.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks the constructor without resource bundle parameter using null name.",
-            method = "getName",
-            args = {}
-        )
-    })
     public void testConstructorNoResBundle_NullName() {
         try {
             new MockLevel(null, -2);
@@ -97,20 +63,6 @@
      * Test the constructor without resource bundle parameter using empty name.
      * As byproducts, getName & intValue are also tested.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks the constructor without resource bundle parameter using empty name.",
-            method = "Level",
-            args = {java.lang.String.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks the constructor without resource bundle parameter using empty name.",
-            method = "getName",
-            args = {}
-        )
-    })
      public void testConstructorNoResBundle_EmptyName() {
         MockLevel l = new MockLevel("", -3);
         assertEquals("", l.getName());
@@ -122,20 +74,6 @@
      * Test the constructor having resource bundle parameter using normal
      * values. As byproducts, getName & intValue are also tested.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "Level",
-            args = {java.lang.String.class, int.class, java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getName",
-            args = {}
-        )
-    })
     public void testConstructorHavingResBundle_Normal() {
         MockLevel l = new MockLevel("level1", 1, "resourceBundle");
         assertEquals("level1", l.getName());
@@ -147,12 +85,6 @@
      * Test the constructor having resource bundle parameter using null names.
      * As byproducts, getName & intValue are also tested.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks NullPointerException.",
-        method = "Level",
-        args = {java.lang.String.class, int.class, java.lang.String.class}
-    )
     public void testConstructorHavingResBundle_NullName() {
         try {
             new MockLevel(null, -123, "qwe");
@@ -167,12 +99,6 @@
      names.
      * As byproducts, getName & intValue are also tested.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor having resource bundle parameter using empty names.",
-        method = "Level",
-        args = {java.lang.String.class, int.class, java.lang.String.class}
-    )
      public void testConstructorHavingResBundle_EmptyName() {
      MockLevel l = new MockLevel("", -1000, "");
      assertEquals("", l.getName());
@@ -183,12 +109,6 @@
     /*
      * Test method parse, with the pre-defined string consts.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies parse, with the pre-defined string consts.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_PredefinedConstStrings() {
         assertSame(Level.SEVERE, Level.parse("SEVERE"));
         assertSame(Level.WARNING, Level.parse("WARNING"));
@@ -204,12 +124,6 @@
     /*
      * Test method parse, with an undefined string.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IllegalArgumentException is verified.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_IllegalConstString() {
         try {
             Level.parse("SEVERe");
@@ -222,12 +136,6 @@
     /*
      * Test method parse, with a null string.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies null as a parameter.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_NullString() {
         try {
             Level.parse(null);
@@ -240,12 +148,6 @@
     /*
      * Test method parse, with pre-defined valid number strings.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies parse, with pre-defined valid number strings.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_PredefinedNumber() {
         assertSame(Level.SEVERE, Level.parse("SEVERE"));
         assertSame(Level.WARNING, Level.parse("WARNING"));
@@ -270,12 +172,6 @@
     /*
      * Test method parse, with an undefined valid number strings.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies parse, with an undefined valid number strings.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_UndefinedNumber() {
         Level l = Level.parse("0");
         assertEquals(0, l.intValue());
@@ -286,12 +182,6 @@
     /*
      * Test method parse, with an undefined valid number strings with spaces.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies parse, with an undefined valid number strings with spaces.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_UndefinedNumberWithSpaces() {
         try {
             Level.parse(" 0");
@@ -299,12 +189,6 @@
             // expected
         }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies negative number.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_NegativeNumber() {
         Level l = Level.parse("-4");
         assertEquals(-4, l.intValue());
@@ -316,12 +200,6 @@
      * Test method parse, expecting the same objects will be returned given the
      * same name, even for non-predefined levels.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies parse, expecting the same objects will be returned given the same name, even for non-predefined levels.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testParse_SameObject() {
         Level l = Level.parse("-100");
         assertSame(l, Level.parse("-100"));
@@ -330,12 +208,6 @@
     /*
      * Test method hashCode, with normal fields.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void testHashCode_Normal() {
         assertEquals(100, Level.parse("100").hashCode());
         assertEquals(-1, Level.parse("-1").hashCode());
@@ -346,12 +218,6 @@
     /*
      * Test equals when two objects are equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check negative case.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEquals_Equal() {
         MockLevel l1 = new MockLevel("level1", 1);
         MockLevel l2 = new MockLevel("level2", 1);
@@ -362,12 +228,6 @@
     /*
      * Test equals when two objects are not equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks negative case.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEquals_NotEqual() {
         MockLevel l1 = new MockLevel("level1", 1);
         MockLevel l2 = new MockLevel("level1", 2);
@@ -378,12 +238,6 @@
     /*
      * Test equals when the other object is null.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks null as a parameter.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEquals_Null() {
         assertFalse(Level.ALL.equals(null));
     }
@@ -391,12 +245,6 @@
     /*
      * Test equals when the other object is not an instance of Level.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks negative case.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEquals_NotLevel() {
         assertFalse(Level.ALL.equals(new Object()));
     }
@@ -404,12 +252,6 @@
     /*
      * Test equals when the other object is itself.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks equals when the other object is itself.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEquals_Itself() {
         assertTrue(Level.ALL.equals(Level.ALL));
     }
@@ -417,12 +259,6 @@
     /*
      * Test toString of a normal Level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void testToString_Normal() {
         assertEquals("ALL", Level.ALL.toString());
 
@@ -457,12 +293,6 @@
      * Test serialization of pre-defined const levels. It is expected that the
      * deserialized cost level should be the same instance as the existing one.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Serialization of pre-defined const levels. ",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerialization_ConstLevel() throws Exception {
 
         SerializationTest.verifySelf(Level.ALL,
@@ -475,12 +305,6 @@
      * Test serialization of normal instance of Level. It is expected that the
      * deserialized level object should be equal to the original one.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Test serialization of normal instance of Level.",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerialization_InstanceLevel() throws Exception {
 
         // tests that objects are the same
@@ -500,23 +324,11 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Serialization/deserialization compatibility",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
                 new MockLevel("123", 123, "bundle"), LEVEL_COMPARATOR);
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getLocalizedName",
-        args = {}
-    )
     public void testGetLocalName() {
         ResourceBundle rb = ResourceBundle.getBundle("bundles/java/util/logging/res");
         Level l = new MockLevel("level1", 120,
@@ -543,12 +355,6 @@
     /*
      * test for method public String getResourceBundleName()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getResourceBundleName",
-        args = {}
-    )
      public void testGetResourceBundleName() {
         String bundleName = "bundles/java/util/logging/res";
         Level l = new MockLevel("level1", 120);
@@ -565,12 +371,6 @@
      /*
      * test for method public final int intValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValue() {
         int value1 = 120;
         Level l = new MockLevel("level1", value1);
@@ -582,12 +382,6 @@
     /*
      * Test defining new levels in subclasses of Level
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Test defining new levels in subclasses of Level",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
     public void testSubclassNewLevel() {
         MyLevel.DUPLICATENAME.getName();// just to load MyLevel class
         
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
index 9b41a9d..5e06b70 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LevelTestResource.java
@@ -17,12 +17,8 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargetClass;
-
 import java.util.ListResourceBundle;
-import java.util.logging.Level;
 
-//@TestTargetClass = No test needed, just test class helper
 public class LevelTestResource extends ListResourceBundle {
     public Object[][] getContents() {
         return contents;
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
index 7fa258b..eff8745 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogManagerTest.java
@@ -35,17 +35,11 @@
 import java.util.logging.Logger;
 import java.util.logging.LoggingPermission;
 
-import dalvik.annotation.KnownFailure;
 import junit.framework.TestCase;
 
 import org.apache.harmony.logging.tests.java.util.logging.HandlerTest.NullOutputStream;
 import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
 
-import dalvik.annotation.SideEffect;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
 import tests.util.TestEnvironment;
 
 /**
@@ -53,7 +47,6 @@
  * add/get logger(dot)
  * 
  */
-@TestTargetClass(LogManager.class) 
 public class LogManagerTest extends TestCase {
 
     private static final String FOO = "LogManagerTestFoo";
@@ -114,12 +107,6 @@
         handler = null;
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "LogManager",
-        args = {}
-    )
     public void testLogManager() {
        class TestLogManager extends LogManager {
            public TestLogManager() {
@@ -130,20 +117,6 @@
        assertNotNull(tlm.toString());
     }
     
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies NullPointerException.",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies NullPointerException.",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        )
-    })
     public void testAddGetLogger() {
         Logger log = new MockLogger(FOO, null);
         Logger foo = mockManager.getLogger(FOO);
@@ -177,20 +150,6 @@
         assertEquals(i, 1);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        )
-    })
     public void testAddGetLogger_duplicateName() {
         // add logger with duplicate name has no effect
         Logger foo = new MockLogger(FOO, null);
@@ -208,20 +167,6 @@
         assertEquals(1, i);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        )
-    })
     public void testAddGetLogger_Hierachy() {
         Logger foo = new MockLogger("testAddGetLogger_Hierachy.foo", null);
         Logger child = new MockLogger("testAddGetLogger_Hierachy.foo.child", null);
@@ -261,20 +206,6 @@
         assertSame(otherChild, grandson.getParent());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        )
-    })
     public void testAddLoggerReverseOrder() {
         Logger root = new MockLogger("testAddLoggerReverseOrder", null);
         Logger foo = new MockLogger("testAddLoggerReverseOrder.foo", null);
@@ -307,12 +238,6 @@
         assertSame(realRoot, root.getParent());
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addLogger",
-        args = {java.util.logging.Logger.class}
-    )
     public void testAddSimiliarLogger() {
         Logger root = new MockLogger("testAddSimiliarLogger", null);
         Logger foo = new MockLogger("testAddSimiliarLogger.foo", null);
@@ -344,20 +269,6 @@
         assertSame(fooo, foooChild.getParent());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        )
-    })
     public void testAddGetLogger_nameWithSpace() {
         Logger foo = new MockLogger(FOO, null);
         Logger fooBeforeSpace = new MockLogger(FOO + " ", null);
@@ -374,20 +285,6 @@
         assertSame(fooWithBothSpace, mockManager.getLogger(" " + FOO + " "));
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Doesn't verify NullPointerException",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        )
-    })
     public void testAddGetLogger_addRoot() {
         Logger foo = new MockLogger(FOO, null);
         Logger fooChild = new MockLogger(FOO + ".child", null);
@@ -418,20 +315,6 @@
     /**
      * @tests java.util.logging.LogManager#addLogger(Logger)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addLogger",
-            args = {java.util.logging.Logger.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogManager",
-            args = {}
-        )
-    })
     public void test_addLoggerLLogger_Security() throws Exception {
         // regression test for Harmony-1286
         SecurityManager originalSecurityManager = System.getSecurityManager();
@@ -450,12 +333,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testDefaultLoggerProperties() throws Exception {
         // mock LogManager has no default logger
         assertNull(mockManager.getLogger(""));
@@ -501,20 +378,6 @@
      * case 4: check correct tested value
      */
     
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getLoggerNames",
-            args = {}
-        )
-    })
     public void testGetLogger() throws Exception {
 
         // case 1: test default and valid value
@@ -551,20 +414,6 @@
     /*
      * test for method public Logger getLogger(String name)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getLogger",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "",
-            method = "getLoggerNames",
-            args = {}
-        )
-    })
     public void testGetLogger_duplicateName() throws Exception {
         // test duplicate name
         // add logger with duplicate name has no effect
@@ -588,12 +437,6 @@
     /*
      * test for method public Logger getLogger(String name)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_hierachy() throws Exception {
         // test hierachy
         Logger foo = new MockLogger("testGetLogger_hierachy.foo", null);
@@ -606,12 +449,6 @@
     /*
      * test for method public Logger getLogger(String name)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_nameSpace() throws Exception {
         // test name with space
         Logger foo = new MockLogger(FOO, null);
@@ -632,20 +469,6 @@
     /*
      * test for method public void checkAccess() throws SecurityException
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "checkAccess",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getLogManager",
-            args = {}
-        )
-    })
     public void testCheckAccess() {
         try {
             manager.checkAccess();
@@ -667,44 +490,6 @@
         System.setSecurityManager(securityManager);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "readConfiguration",
-            args = {java.io.InputStream.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "readConfiguration",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "checkAccess",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "reset",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "getLogManager",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "addPropertyChangeListener",
-            args = {java.beans.PropertyChangeListener.class}
-        )
-    })
     public void testLoggingPermission() throws IOException {
         System.setSecurityManager(new MockSecurityManagerLogPermission());
         mockManager.addLogger(new MockLogger("abc", null));
@@ -757,20 +542,6 @@
     }
 
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "readConfiguration",
-            args = {java.io.InputStream.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getProperty",
-            args = {java.lang.String.class}
-        )
-    })
     public void testMockGetProperty() throws Exception {
         // mock manager doesn't read configuration until you call
         // readConfiguration()
@@ -789,12 +560,6 @@
         assertEquals(0, mockManager.getLogger("").getHandlers().length);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getProperty",
-        args = {java.lang.String.class}
-    )
     public void testGetProperty() throws SecurityException, IOException {
 
         Logger root = manager.getLogger("");
@@ -811,12 +576,6 @@
         manager.reset();
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies NullPointerException.",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testReadConfiguration_null() throws SecurityException, IOException {
         try {
             manager.readConfiguration(null);
@@ -838,7 +597,6 @@
         assertNull(m.getProperty("java.util.logging.FileHandler.pattern"));
     }
 
-    @KnownFailure("We're ignoring a missing logging.properties. See bug 2487364")
     public void testReadConfiguration() throws SecurityException,
             IOException {
 
@@ -894,12 +652,6 @@
     /*
      * Class under test for void readConfiguration(InputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testReadConfigurationInputStream() throws IOException {
 
         Logger foo = new MockLogger(FOO, null);
@@ -930,12 +682,6 @@
         assertSame(l, h.getLevel());
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies NullPointerException.",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testReadConfigurationInputStream_null() throws SecurityException, IOException {
         try {
             mockManager.readConfiguration(null);
@@ -944,12 +690,6 @@
         }
 
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IOException.",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testReadConfigurationInputStream_IOException_1parm() throws SecurityException {
         try {
             mockManager.readConfiguration(new MockInputStream());
@@ -960,12 +700,6 @@
 
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testReadConfigurationInputStream_root() throws IOException {
         manager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
 
@@ -1030,20 +764,6 @@
         assertEquals(0, logger.getHandlers().length);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addPropertyChangeListener",
-            args = {java.beans.PropertyChangeListener.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "removePropertyChangeListener",
-            args = {java.beans.PropertyChangeListener.class}
-        )
-    })
     public void testAddRemovePropertyChangeListener() throws Exception {
         MockPropertyChangeListener listener1 = new MockPropertyChangeListener();
         MockPropertyChangeListener listener2 = new MockPropertyChangeListener();
@@ -1090,20 +810,6 @@
         assertNull(listener2.getEvent());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "addPropertyChangeListener",
-            args = {java.beans.PropertyChangeListener.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "removePropertyChangeListener",
-            args = {java.beans.PropertyChangeListener.class}
-        )
-    })
     public void testAddRemovePropertyChangeListener_null() {
         // seems nothing happened
         try{
@@ -1114,12 +820,6 @@
         mockManager.removePropertyChangeListener(null);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify SecurityException.",
-        method = "reset",
-        args = {}
-    )
     public void testReset() throws SecurityException, IOException {
         // mock LogManager
         mockManager.readConfiguration(EnvironmentHelper.PropertiesToInputStream(props));
@@ -1155,12 +855,6 @@
     }
 
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify SecurityException.",
-        method = "readConfiguration",
-        args = {java.io.InputStream.class}
-    )
     public void testGlobalPropertyConfig() throws Exception {
         PrintStream err = System.err;
         try {
@@ -1234,12 +928,6 @@
         }
 
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "readConfiguration",
-        args = {}
-    )
     public void testValidConfigClass() throws Exception {
         //            System.setProperty("java.util.logging.config.class", "org.apache.harmony.logging.tests.java.util.logging.LogManagerTest$ConfigClass");
         System.setProperty("java.util.logging.config.class", this.getClass().getName()
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
index 6d4f784..7d8757e 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LogRecordTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.Serializable;
 import java.util.Locale;
 import java.util.ResourceBundle;
@@ -36,7 +31,6 @@
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(LogRecord.class)
 public class LogRecordTest extends TestCase {
 
     static final String MSG = "test msg, pls. ignore itb";
@@ -50,12 +44,6 @@
         lr = new LogRecord(Level.CONFIG, MSG);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "LogRecord",
-        args = {java.util.logging.Level.class, java.lang.String.class}
-    )
     public void testLogRecordWithNullPointers() {
         try {
             new LogRecord(null, null);
@@ -72,20 +60,6 @@
         assertNull(r.getMessage());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "normally set/get don't need to be tested",
-            method = "getLoggerName",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "normally set/get don't need to be tested",
-            method = "setLoggerName",
-            args = {java.lang.String.class}
-        )
-    })
     public void testGetSetLoggerName() {
         assertNull(lr.getLoggerName());
         lr.setLoggerName(null);
@@ -94,21 +68,6 @@
         assertEquals("test logger name", lr.getLoggerName());
     }
 
-
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getResourceBundle",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setResourceBundle",
-            args = {java.util.ResourceBundle.class}
-        )
-    })
     public void testGetSetResourceBundle() {
         assertNull(lr.getResourceBundleName());
         assertNull(lr.getResourceBundle());
@@ -127,20 +86,6 @@
         assertNull(lr.getResourceBundleName());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getResourceBundleName",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setResourceBundleName",
-            args = {java.lang.String.class}
-        )
-    })
     public void testGetSetResourceBundleName() {
         assertNull(lr.getResourceBundleName());
         lr.setResourceBundleName(null);
@@ -149,20 +94,6 @@
         assertEquals("test", lr.getResourceBundleName());
     }
     
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "normal behavior of getter/setter don't need to be tested (normally)",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "normal behavior of getter/setter don't need to be tested (normally)",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
     public void testGetSetLevelNormal() {           
         assertSame(lr.getLevel(), Level.CONFIG);
         lr.setLevel(Level.ALL);
@@ -171,20 +102,6 @@
         assertSame(lr.getLevel(), Level.FINEST);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
     public void testGetSetLevelNullPointerException() {
         try {
             lr.setLevel(null);
@@ -194,20 +111,6 @@
         assertSame(lr.getLevel(), Level.CONFIG);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getSequenceNumber",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setSequenceNumber",
-            args = {long.class}
-        )
-    })
     public void testGetSetSequenceNumber() {
         long l = lr.getSequenceNumber();
         lr.setSequenceNumber(-111);
@@ -218,20 +121,6 @@
         assertEquals(lr.getSequenceNumber(), l + 1);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getSourceClassName",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setSourceClassName",
-            args = {java.lang.String.class}
-        )
-    })
     public void testGetSetSourceClassName() {
         lr.setSourceClassName(null);
         assertNull(lr.getSourceClassName());
@@ -241,20 +130,6 @@
         assertEquals(this.getClass().getName(), lr.getSourceClassName());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getSourceMethodName",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "setSourceMethodName",
-            args = {java.lang.String.class}
-        )
-    })
     public void testGetSetSourceMethodName() {
         lr.setSourceMethodName(null);
         assertNull(lr.getSourceMethodName());
@@ -264,32 +139,6 @@
         assertEquals(this.getClass().getName(), lr.getSourceMethodName());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getSourceMethodName",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "setSourceMethodName",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getSourceClassName",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "setSourceClassName",
-            args = {java.lang.String.class}
-        )
-    })
     public void testGetSourceDefaultValue() {
         assertNull(lr.getSourceMethodName());
         assertNull(lr.getSourceClassName());
@@ -363,20 +212,6 @@
         logger.removeHandler(handler);
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getMessage",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setMessage",
-            args = {java.lang.String.class}
-        )
-    })
     public void testGetSetMessage() {
         assertEquals(MSG, lr.getMessage());
         lr.setMessage(null);
@@ -385,20 +220,6 @@
         assertEquals("", lr.getMessage());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getParameters",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setParameters",
-            args = {java.lang.Object[].class}
-        )
-    })
     public void testGetSetParameters() {
         assertNull(lr.getParameters());
         lr.setParameters(null);
@@ -411,20 +232,6 @@
         assertSame(oa, lr.getParameters());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getMillis",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setMillis",
-            args = {long.class}
-        )
-    })
     public void testGetSetMillis() {
         long milli = lr.getMillis();
         assertTrue(milli > 0);
@@ -434,20 +241,6 @@
         assertEquals(0, lr.getMillis());
     }
     
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getMillis",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setMillis",
-            args = {long.class}
-        )
-    })
     public void testGetSetTimeCheck() {
         long before = lr.getMillis();
         try {
@@ -462,20 +255,6 @@
     
 
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getThreadID",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setThreadID",
-            args = {int.class}
-        )
-    })
     public void testGetSetThreadID() {
         int id = lr.getThreadID();
         lr = new LogRecord(Level.ALL, "a1");
@@ -489,20 +268,6 @@
     /*
      * Check threadID are different
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getThreadID",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setThreadID",
-            args = {int.class}
-        )
-    })
     public void testGetSetThreadID_DifferentThread() {
         int id = lr.getThreadID();
         // Create and start the thread
@@ -529,20 +294,6 @@
     }
 
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getThrown",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setThrown",
-            args = {java.lang.Throwable.class}
-        )
-    })
     public void testGetSetThrown() {
         assertNull(lr.getThrown());
         lr.setThrown(null);
@@ -600,12 +351,6 @@
     /**
      * @tests serialization/deserialization compatibility.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "serialisation/deserialization",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
         LogRecord r = new LogRecord(Level.ALL, "msg");
         r.setLoggerName("LoggerName");
@@ -624,12 +369,6 @@
     /**
      * @tests resolution of resource bundle for serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "tests resolution of resource bundle during deserialization",
-        method = "!Serialization",
-        args = {}
-    )
     public void testSerializationResourceBundle() throws Exception {
 
         // test case: valid resource bundle name
@@ -653,12 +392,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
         LogRecord r = new LogRecord(Level.ALL, "msg");
         r.setLoggerName("LoggerName");
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
index 7bf74e4..17233a1 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggerTest.java
@@ -17,6 +17,8 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
+import dalvik.annotation.SideEffect;
+
 import java.security.Permission;
 import java.util.Locale;
 import java.util.MissingResourceException;
@@ -32,22 +34,16 @@
 import java.io.File;
 import java.io.FileInputStream;
 
-import dalvik.annotation.KnownFailure;
 import junit.framework.TestCase;
 
 import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
 
+import tests.support.resource.Support_Resources;
 import tests.util.CallVerificationStack;
-import dalvik.annotation.SideEffect;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
 
 /**
  * Test suite for the class java.util.logging.Logger.
  */
-@TestTargetClass(Logger.class)
 public class LoggerTest extends TestCase {
 
     private final static String VALID_RESOURCE_BUNDLE = "bundles/java/util/logging/res";
@@ -58,7 +54,7 @@
 
     private final static String INVALID_RESOURCE_BUNDLE = "impossible_not_existing";
 
-    private final static String LOGGING_CONFIG_FILE = "src/test/resources/config/java/util/logging/logging.config";
+    private final static String LOGGING_CONFIG_FILE = "/config/java/util/logging/logging.config";
 
     private final static String VALID_KEY = "LOGGERTEST";
 
@@ -96,12 +92,6 @@
     /*
      * Test the global logger
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Logger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGlobalLogger() {
         assertNull(Logger.global.getFilter());
         assertEquals(0, Logger.global.getHandlers().length);
@@ -119,12 +109,6 @@
     /*
      * Test constructor under normal conditions.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies constructor under normal conditions.",
-        method = "Logger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testConstructor_Normal() {
         MockLogger mlog = new MockLogger("myname", VALID_RESOURCE_BUNDLE);
         assertNull(mlog.getFilter());
@@ -141,12 +125,6 @@
     /*
      * Test constructor with null parameters.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies constructor with null parameters.",
-        method = "Logger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testConstructor_Null() {
         MockLogger mlog = new MockLogger(null, null);
         assertNull(mlog.getFilter());
@@ -162,12 +140,6 @@
     /*
      * Test constructor with invalid name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies constructor with invalid name.",
-        method = "Logger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testConstructor_InvalidName() {
         MockLogger mlog = new MockLogger("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|",
                 null);
@@ -177,12 +149,6 @@
     /*
      * Test constructor with empty name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies constructor with empty name.",
-        method = "Logger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testConstructor_EmptyName() {
         MockLogger mlog = new MockLogger("", null);
         assertEquals("", mlog.getName());
@@ -191,12 +157,6 @@
     /*
      * Test constructor with invalid resource bundle name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies MissingResourceException.",
-        method = "Logger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testConstructor_InvalidResourceBundle() {
 
         // try anonymous with invalid resource
@@ -226,12 +186,6 @@
     /*
      * Test getAnonymousLogger()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAnonymousLogger",
-        args = {}
-    )
     public void testGetAnonymousLogger() {
         Logger alog = Logger.getAnonymousLogger();
         assertNotSame(alog, Logger.getAnonymousLogger());
@@ -250,12 +204,6 @@
      * Test getAnonymousLogger(String resourceBundleName) with valid resource
      * bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getAnonymousLogger(String resourceBundleName) with valid resource bundle.",
-        method = "getAnonymousLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetAnonymousLogger_ValidResourceBundle() {
         Logger alog = Logger.getAnonymousLogger(VALID_RESOURCE_BUNDLE);
         assertNotSame(alog, Logger.getAnonymousLogger(VALID_RESOURCE_BUNDLE));
@@ -274,12 +222,6 @@
      * Test getAnonymousLogger(String resourceBundleName) with null resource
      * bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getAnonymousLogger(String resourceBundleName) with null resource bundle.",
-        method = "getAnonymousLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetAnonymousLogger_NullResourceBundle() {
         Logger alog = Logger.getAnonymousLogger(null);
         assertNotSame(alog, Logger.getAnonymousLogger(null));
@@ -298,12 +240,6 @@
      * Test getAnonymousLogger(String resourceBundleName) with invalid resource
      * bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getAnonymousLogger(String resourceBundleName) with invalid resource bundle.",
-        method = "getAnonymousLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetAnonymousLogger_InvalidResourceBundle() {
         try {
             Logger.getAnonymousLogger(INVALID_RESOURCE_BUNDLE);
@@ -321,12 +257,6 @@
     /*
      * Test getLogger(String), getting a logger with no parent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String), getting a logger with no parent.",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_Normal() throws Exception {
         // config the level
         Properties p = new Properties();
@@ -360,12 +290,6 @@
     /*
      * Test getLogger(String), getting a logger with invalid level configured.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String), getting a logger with invalid level configured.",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_InvalidLevel() throws Exception {
         // config the level
         Properties p = new Properties();
@@ -391,12 +315,6 @@
     /*
      * Test getLogger(String) with null name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String) with null name.",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_Null() {
         try {
             Logger.getLogger(null);
@@ -415,12 +333,6 @@
     /*
      * Test getLogger(String) with invalid name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String) with invalid name.",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_Invalid() {
         Logger log = Logger.getLogger("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|");
         assertEquals("...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|", log.getName());
@@ -429,12 +341,6 @@
     /*
      * Test getLogger(String) with empty name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String) with empty name.",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void testGetLogger_Empty() {
         assertNotNull(LogManager.getLogManager().getLogger(""));
         Logger log = Logger.getLogger("");
@@ -453,12 +359,6 @@
     /*
      * Test getLogger(String), getting a logger with existing parent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String), getting a logger with existing parent.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLogger_WithParent() {
         assertNull(LogManager.getLogManager().getLogger(
                 "testGetLogger_WithParent_ParentLogger"));
@@ -545,12 +445,6 @@
     /*
      * Test getLogger(String, String), getting a logger with no parent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String), getting a logger with no parent.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_Normal() throws Exception {
         // config the level
         Properties p = new Properties();
@@ -584,12 +478,6 @@
     /*
      * Test getLogger(String, String) with null parameters.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with null parameters.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_Null() {
         Logger.getLogger("testGetLoggerWithRes_Null_ANewLogger", null);
         try {
@@ -603,12 +491,6 @@
     /*
      * Test getLogger(String, String) with invalid resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with invalid resource bundle.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_InvalidResourceBundle() {
 
         assertNull(LogManager.getLogManager().getLogger(
@@ -646,12 +528,6 @@
      * Test getLogger(String, String) with valid resource bundle, to get an
      * existing logger with no associated resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with valid resource bundle, to get an existing logger with no associated resource bundle.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_ExistingLoggerWithNoRes() {
         assertNull(LogManager.getLogManager().getLogger(
                 "testGetLoggerWithRes_ExistingLoggerWithNoRes_ANewLogger"));
@@ -672,12 +548,6 @@
      * Test getLogger(String, String) with valid resource bundle, to get an
      * existing logger with the same associated resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with valid resource bundle, to get an existing logger with the same associated resource bundle.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_ExistingLoggerWithSameRes() {
         assertNull(LogManager.getLogManager().getLogger(
                 "testGetLoggerWithRes_ExistingLoggerWithSameRes_ANewLogger"));
@@ -698,12 +568,6 @@
      * Test getLogger(String, String) with valid resource bundle, to get an
      * existing logger with different associated resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with valid resource bundle, to get an existing logger with different associated resource bundle.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_ExistingLoggerWithDiffRes() {
         assertNull(LogManager.getLogManager().getLogger(
                 "testGetLoggerWithRes_ExistingLoggerWithDiffRes_ANewLogger"));
@@ -735,12 +599,6 @@
     /*
      * Test getLogger(String, String) with invalid name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with invalid name.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_InvalidName() {
         Logger log = Logger.getLogger(
                 "...#$%%^&&()-_+=!@~./,[]{};:'\\\"?|WithRes",
@@ -752,12 +610,6 @@
     /*
      * Test getLogger(String, String) with empty name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String) with empty name.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     @SideEffect("Attaches ResourceBundle to anonymous logger; irreversible")
     public void testGetLoggerWithRes_Empty() {
         Logger log = Logger.getLogger("", VALID_RESOURCE_BUNDLE);
@@ -776,12 +628,6 @@
     /*
      * Test getLogger(String, String), getting a logger with existing parent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getLogger(String, String), getting a logger with existing parent.",
-        method = "getLogger",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testGetLoggerWithRes_WithParentNormal() {
         assertNull(LogManager.getLogManager().getLogger(
                 "testGetLoggerWithRes_WithParent_ParentLogger"));
@@ -813,12 +659,6 @@
     /*
      * Test addHandler(Handler) for a named logger with sufficient privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_NamedLoggerSufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testAddHandler_NamedLoggerSufficientPrivilege");
@@ -833,12 +673,6 @@
      * Test addHandler(Handler) for a named logger with sufficient privilege,
      * add duplicate handlers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_NamedLoggerSufficientPrivilegeDuplicate() {
         Logger log = Logger
                 .getLogger("testAddHandler_NamedLoggerSufficientPrivilegeDuplicate");
@@ -856,12 +690,6 @@
     /*
      * Test addHandler(Handler) with a null handler.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies NullPointerException.",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_Null() {
         Logger log = Logger.getLogger("testAddHandler_Null");
         try {
@@ -875,12 +703,6 @@
     /*
      * Test addHandler(Handler) for a named logger with insufficient privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_NamedLoggerInsufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testAddHandler_NamedLoggerInsufficientPrivilege");
@@ -901,12 +723,6 @@
      * Test addHandler(Handler) for a named logger with insufficient privilege,
      * using a null handler.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_NamedLoggerInsufficientPrivilegeNull() {
         Logger log = Logger
                 .getLogger("testAddHandler_NamedLoggerInsufficientPrivilege");
@@ -926,12 +742,6 @@
      * Test addHandler(Handler) for an anonymous logger with sufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_AnonyLoggerSufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         MockHandler h = new MockHandler();
@@ -945,12 +755,6 @@
      * Test addHandler(Handler) for an anonymous logger with insufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_AnonyLoggerInsufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         MockHandler h = new MockHandler();
@@ -970,12 +774,6 @@
      * Test addHandler(Handler) for a null-named mock logger with insufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies addHandler(Handler) for a null-named mock logger with insufficient privilege, SecurityException.",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testAddHandler_NullNamedMockLoggerInsufficientPrivilege() {
         MockLogger mlog = new MockLogger(null, null);
         MockHandler h = new MockHandler();
@@ -994,12 +792,6 @@
      * Test removeHandler(Handler) for a named logger with sufficient privilege,
      * remove an existing handler.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "addHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_NamedLoggerSufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testRemoveHandler_NamedLoggerSufficientPrivilege");
@@ -1014,12 +806,6 @@
      * Test removeHandler(Handler) for a named logger with sufficient privilege,
      * remove a non-existing handler.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_NamedLoggerSufficientPrivilegeNotExisting() {
         Logger log = Logger
                 .getLogger("testRemoveHandler_NamedLoggerSufficientPrivilegeNotExisting");
@@ -1032,12 +818,6 @@
     /*
      * Test removeHandler(Handler) with a null handler.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_Null() {
         Logger log = Logger.getLogger("testRemoveHandler_Null");
         log.removeHandler(null);
@@ -1048,12 +828,6 @@
      * Test removeHandler(Handler) for a named logger with insufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_NamedLoggerInsufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testRemoveHandler_NamedLoggerInsufficientPrivilege");
@@ -1074,12 +848,6 @@
      * Test removeHandler(Handler) for a named logger with insufficient
      * privilege, using a null handler.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_NamedLoggerInsufficientPrivilegeNull() {
         Logger log = Logger
                 .getLogger("testRemoveHandler_NamedLoggerInsufficientPrivilege");
@@ -1099,12 +867,6 @@
      * Test removeHandler(Handler) for an anonymous logger with sufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_AnonyLoggerSufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         MockHandler h = new MockHandler();
@@ -1118,12 +880,6 @@
      * Test removeHandler(Handler) for an anonymous logger with insufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_AnonyLoggerInsufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         MockHandler h = new MockHandler();
@@ -1143,12 +899,6 @@
      * Test removeHandler(Handler) for a null-named mock logger with
      * insufficient privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "removeHandler",
-        args = {java.util.logging.Handler.class}
-    )
     public void testRemoveHandler_NullNamedMockLoggerInsufficientPrivilege() {
         MockLogger mlog = new MockLogger(null, null);
         MockHandler h = new MockHandler();
@@ -1166,12 +916,6 @@
     /*
      * Test getHandlers() when there's no handler.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getHandlers() when there's no handler.",
-        method = "getHandlers",
-        args = {}
-    )
     public void testGetHandlers_None() {
         Logger log = Logger.getLogger("testGetHandlers_None");
         assertEquals(log.getHandlers().length, 0);
@@ -1180,12 +924,6 @@
     /*
      * Test getHandlers() when there are several handlers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getHandlers() when there are several handlers.",
-        method = "getHandlers",
-        args = {}
-    )
     public void testGetHandlers_Several() {
         Logger log = Logger.getLogger("testGetHandlers_None");
         assertEquals(log.getHandlers().length, 0);
@@ -1211,20 +949,6 @@
      * Test getFilter & setFilter with normal value for a named logger, having
      * sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getFilter & setFilter with normal value for a named logger, having sufficient privilege.",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getFilter & setFilter with normal value for a named logger, having sufficient privilege.",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
     public void testGetSetFilter_NamedLoggerSufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testGetSetFilter_NamedLoggerSufficientPrivilege");
@@ -1238,20 +962,6 @@
     /*
      * Test getFilter & setFilter with null value, having sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getFilter & setFilter with null value, having sufficient privilege.",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getFilter & setFilter with null value, having sufficient privilege.",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
     public void testGetSetFilter_Null() {
         Logger log = Logger.getLogger("testGetSetFilter_Null");
 
@@ -1267,20 +977,6 @@
      * Test setFilter with normal value for a named logger, having insufficient
      * privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies setFilter with normal value for a named logger, having insufficient privilege.",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies setFilter with normal value for a named logger, having insufficient privilege.",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
     public void testGetSetFilter_NamedLoggerInsufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testGetSetFilter_NamedLoggerInsufficientPrivilege");
@@ -1299,20 +995,6 @@
     /*
      * Test setFilter for an anonymous logger with sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
     public void testSetFilter_AnonyLoggerSufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         Filter f = new MockFilter();
@@ -1324,20 +1006,6 @@
     /*
      * Test setFilter for an anonymous logger with insufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
     public void testSetFilter_AnonyLoggerInsufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         Filter f = new MockFilter();
@@ -1355,20 +1023,6 @@
     /*
      * Test setFilter for a null-named mock logger with insufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getFilter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setFilter",
-            args = {java.util.logging.Filter.class}
-        )
-    })
     public void testSetFilter_NullNamedMockLoggerInsufficientPrivilege() {
         MockLogger mlog = new MockLogger(null, null);
         Filter f = new MockFilter();
@@ -1387,20 +1041,6 @@
      * Test getLevel & setLevel with normal value for a named logger, having
      * sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getLevel & setLevel with normal value for a named logger, having sufficient privilege.",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getLevel & setLevel with normal value for a named logger, having sufficient privilege.",
-            method = "getLevel",
-            args = {}
-        )
-    })
     public void testGetSetLevel_NamedLoggerSufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testGetSetLevel_NamedLoggerSufficientPrivilege");
@@ -1413,20 +1053,6 @@
     /*
      * Test getLevel & setLevel with null value, having sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getLevel & setLevel with null value, having sufficient privilege.",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies getLevel & setLevel with null value, having sufficient privilege.",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
     public void testGetSetLevel_Null() {
         Logger log = Logger.getLogger("testGetSetLevel_Null");
 
@@ -1442,20 +1068,6 @@
      * Test setLevel with normal value for a named logger, having insufficient
      * privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies setLevel with normal value for a named logger, having insufficient privilege.",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Verifies setLevel with normal value for a named logger, having insufficient privilege.",
-            method = "getLevel",
-            args = {}
-        )
-    })
     public void testGetSetLevel_NamedLoggerInsufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testGetSetLevel_NamedLoggerInsufficientPrivilege");
@@ -1473,20 +1085,6 @@
     /*
      * Test setLevel for an anonymous logger with sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
     public void testSetLevel_AnonyLoggerSufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         assertNull(log.getLevel());
@@ -1497,20 +1095,6 @@
     /*
      * Test setLevel for an anonymous logger with insufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
     public void testSetLevel_AnonyLoggerInsufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         SecurityManager oldMan = System.getSecurityManager();
@@ -1527,20 +1111,6 @@
     /*
      * Test setLevel for a null-named mock logger with insufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setLevel",
-            args = {java.util.logging.Level.class}
-        )
-    })
     public void testSetLevel_NullNamedMockLoggerInsufficientPrivilege() {
         MockLogger mlog = new MockLogger(null, null);
         SecurityManager oldMan = System.getSecurityManager();
@@ -1558,20 +1128,6 @@
      * Test getUseParentHandlers & setUseParentHandlers with normal value for a
      * named logger, having sufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getUseParentHandlers",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setUseParentHandlers",
-            args = {boolean.class}
-        )
-    })
     public void testGetSetUseParentHandlers_NamedLoggerSufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testGetSetUseParentHandlers_NamedLoggerSufficientPrivilege");
@@ -1585,20 +1141,6 @@
      * Test setUseParentHandlers with normal value for a named logger, having
      * insufficient privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getUseParentHandlers",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setUseParentHandlers",
-            args = {boolean.class}
-        )
-    })
     public void testGetSetUseParentHandlers_NamedLoggerInsufficientPrivilege() {
         Logger log = Logger
                 .getLogger("testGetSetUseParentHandlers_NamedLoggerInsufficientPrivilege");
@@ -1617,20 +1159,6 @@
      * Test setUseParentHandlers for an anonymous logger with sufficient
      * privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getUseParentHandlers",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setUseParentHandlers",
-            args = {boolean.class}
-        )
-    })
     public void testSetUseParentHandlers_AnonyLoggerSufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         assertTrue(log.getUseParentHandlers());
@@ -1642,20 +1170,6 @@
      * Test setUseParentHandlers for an anonymous logger with insufficient
      * privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getUseParentHandlers",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setUseParentHandlers",
-            args = {boolean.class}
-        )
-    })
     public void testSetUseParentHandlers_AnonyLoggerInsufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         SecurityManager oldMan = System.getSecurityManager();
@@ -1673,20 +1187,6 @@
      * Test setUseParentHandlers for a null-named mock logger with insufficient
      * privilege.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getUseParentHandlers",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setUseParentHandlers",
-            args = {boolean.class}
-        )
-    })
     public void testSetUseParentHandlers_NullNamedMockLoggerInsufficientPrivilege() {
         MockLogger mlog = new MockLogger(null, null);
         SecurityManager oldMan = System.getSecurityManager();
@@ -1703,12 +1203,6 @@
     /*
      * Test getParent() for root logger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getParent() for root logger.",
-        method = "getParent",
-        args = {}
-    )
     public void testGetParent_Root() {
         assertNull(Logger.getLogger("").getParent());
     }
@@ -1716,12 +1210,6 @@
     /*
      * Test getParent() for normal named loggers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getParent() for normal named loggers.",
-        method = "getParent",
-        args = {}
-    )
     public void testGetParent_NormalNamed() {
         Logger log = Logger.getLogger("testGetParent_NormalNamed");
         assertSame(log.getParent(), Logger.getLogger(""));
@@ -1734,12 +1222,6 @@
     /*
      * Test getParent() for anonymous loggers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getParent() for anonymous loggers.",
-        method = "getParent",
-        args = {}
-    )
     public void testGetParent_Anonymous() {
         assertSame(Logger.getAnonymousLogger().getParent(), Logger
                 .getLogger(""));
@@ -1749,12 +1231,6 @@
      * Test setParent(Logger) for the mock logger since it is advised not to
      * call this method on named loggers. Test normal conditions.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setParent",
-        args = {java.util.logging.Logger.class}
-    )
     public void testSetParent_Normal() {
         Logger log = new MockLogger(null, null);
         Logger parent = new MockLogger(null, null);
@@ -1766,12 +1242,6 @@
     /*
      * Test setParent(Logger) with null.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setParent",
-        args = {java.util.logging.Logger.class}
-    )
     public void testSetParent_Null() {
         try {
             (new MockLogger(null, null)).setParent(null);
@@ -1783,12 +1253,6 @@
     /*
      * Test setParent(Logger), having insufficient privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setParent",
-        args = {java.util.logging.Logger.class}
-    )
     public void testSetParent_InsufficientPrivilege() {
         MockLogger log = new MockLogger(null, null);
         SecurityManager oldMan = System.getSecurityManager();
@@ -1805,12 +1269,6 @@
     /*
      * Test setParent(Logger) with null, having insufficient privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setParent",
-        args = {java.util.logging.Logger.class}
-    )
     public void testSetParent_InsufficientPrivilegeNull() {
         MockLogger log = new MockLogger(null, null);
         SecurityManager oldMan = System.getSecurityManager();
@@ -1828,12 +1286,6 @@
      * Test setParent(Logger) for an anonymous logger with insufficient
      * privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setParent",
-        args = {java.util.logging.Logger.class}
-    )
     public void testSetParent_AnonyLoggerInsufficientPrivilege() {
         Logger log = Logger.getAnonymousLogger();
         SecurityManager oldMan = System.getSecurityManager();
@@ -1850,12 +1302,6 @@
     /*
      * Test getName() for normal names.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getName() for normal names.",
-        method = "getName",
-        args = {}
-    )
     public void testGetName_Normal() {
         Logger log = Logger.getLogger("testGetName_Normal");
         assertEquals("testGetName_Normal", log.getName());
@@ -1867,12 +1313,6 @@
     /*
      * Test getName() for empty name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getName() for empty name.",
-        method = "getName",
-        args = {}
-    )
     public void testGetName_Empty() {
         Logger log = Logger.getLogger("");
         assertEquals("", log.getName());
@@ -1884,12 +1324,6 @@
     /*
      * Test getName() for null name.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getName() for null name.",
-        method = "getName",
-        args = {}
-    )
     public void testGetName_Null() {
         Logger log = Logger.getAnonymousLogger();
         assertNull(log.getName());
@@ -1901,12 +1335,6 @@
     /*
      * Test getResourceBundle() when it it not null.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getResourceBundle() when it it not null.",
-        method = "getResourceBundle",
-        args = {}
-    )
     public void testGetResourceBundle_Normal() {
         Logger log = Logger.getLogger("testGetResourceBundle_Normal",
                 VALID_RESOURCE_BUNDLE);
@@ -1919,12 +1347,6 @@
     /*
      * Test getResourceBundle() when it it null.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getResourceBundle() when it it null.",
-        method = "getResourceBundle",
-        args = {}
-    )
     public void testGetResourceBundle_Null() {
         Logger log = Logger.getLogger("testGetResourceBundle_Null", null);
         assertNull(log.getResourceBundle());
@@ -1937,12 +1359,6 @@
     /*
      * Test getResourceBundleName() when it it not null.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getResourceBundleName() when it it not null.",
-        method = "getResourceBundleName",
-        args = {}
-    )
     public void testGetResourceBundleName_Normal() {
         Logger log = Logger.getLogger("testGetResourceBundleName_Normal",
                 VALID_RESOURCE_BUNDLE);
@@ -1955,12 +1371,6 @@
     /*
      * Test getResourceBundleName() when it it null.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies getResourceBundleName() when it it null.",
-        method = "getResourceBundleName",
-        args = {}
-    )
     public void testGetResourceBundleName_Null() {
         Logger log = Logger.getLogger("testGetResourceBundleName_Null", null);
         assertNull(log.getResourceBundleName());
@@ -1973,12 +1383,6 @@
     /*
      * Test isLoggable(Level).
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isLoggable",
-        args = {java.util.logging.Level.class}
-    )
     public void testIsLoggable() {
         MockLogger mlog = new MockLogger(null, null);
         assertNull(mlog.getLevel());
@@ -2012,12 +1416,6 @@
     /*
      * Test throwing(String, String, Throwable) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "throwing",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testThrowing_Normal() {
         Throwable t = new Throwable();
         this.sharedLogger.setLevel(Level.FINER);
@@ -2046,12 +1444,6 @@
     /*
      * Test throwing(String, String, Throwable) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "throwing",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testThrowing_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2076,12 +1468,6 @@
     /*
      * Test entering(String, String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String) with normal values.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testEntering_StringString_Normal() {
         this.sharedLogger.setLevel(Level.FINER);
         this.sharedLogger.entering("sourceClass", "sourceMethod");
@@ -2106,12 +1492,6 @@
     /*
      * Test entering(String, String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String) with null values.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testEntering_StringString_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2136,12 +1516,6 @@
     /*
      * Test entering(String, String, Object) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String, Object) with normal values.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testEntering_StringStringObject_Normal() {
         Object param = new Object();
         this.sharedLogger.setLevel(Level.FINER);
@@ -2168,12 +1542,6 @@
     /*
      * Test entering(String, String, Object) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String, Object) with null values.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testEntering_StringStringObject_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2199,12 +1567,6 @@
     /*
      * Test entering(String, String, Object[]) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String, Object[]) with normal values.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testEntering_StringStringObjects_Normal() {
         Object[] params = new Object[2];
         params[0] = new Object();
@@ -2235,12 +1597,6 @@
      * Test entering(String, String, Object[]) with null class name and method
      * name and empty parameter array.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String, Object[]) with null class name and method name and empty parameter array.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testEntering_StringStringObjects_NullEmpty() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2266,12 +1622,6 @@
      * Test entering(String, String, Object[]) with null values with appropriate
      * logging level set.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies  entering(String, String, Object[]) with null values with appropriate logging level set.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testEntering_StringStringObjects_Null() {
         sharedLogger.setLevel(Level.FINER);
         sharedLogger.entering(null, null, (Object[]) null);
@@ -2294,12 +1644,6 @@
      * Test entering(String, String, Object[]) with null values with
      * inappropriate logging level set.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies entering(String, String, Object[]) with null values with inappropriate logging level set.",
-        method = "entering",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testEntering_StringStringObjects_NullDisabled() {
         this.sharedLogger.setLevel(Level.FINE);
         this.sharedLogger.entering(null, null, (Object[]) null);
@@ -2309,12 +1653,6 @@
     /*
      * Test exiting(String, String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies exiting(String, String) with normal values.",
-        method = "exiting",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testExiting_StringString_Normal() {
         this.sharedLogger.setLevel(Level.FINER);
         this.sharedLogger.exiting("sourceClass", "sourceMethod");
@@ -2339,12 +1677,6 @@
     /*
      * Test exiting(String, String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies exiting(String, String) with null values.",
-        method = "exiting",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testExiting_StringString_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2369,12 +1701,6 @@
     /*
      * Test exiting(String, String, Object) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies exiting(String, String, Object) with normal values.",
-        method = "exiting",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testExiting_StringStringObject_Normal() {
         Object param = new Object();
         this.sharedLogger.setLevel(Level.FINER);
@@ -2401,12 +1727,6 @@
     /*
      * Test exiting(String, String, Object) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies exiting(String, String, Object) with null values.",
-        method = "exiting",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testExiting_StringStringObject_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2432,12 +1752,6 @@
     /*
      * Test config(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "config",
-        args = {java.lang.String.class}
-    )
     public void testConfig_Normal() {
         this.sharedLogger.setLevel(Level.CONFIG);
         this.sharedLogger.config("config msg");
@@ -2462,12 +1776,6 @@
     /*
      * Test config(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies null as a parameter.",
-        method = "config",
-        args = {java.lang.String.class}
-    )
     public void testConfig_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2496,12 +1804,6 @@
     /*
      * Test fine(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "fine",
-        args = {java.lang.String.class}
-    )
     public void testFine_Normal() {
         this.sharedLogger.setLevel(Level.FINE);
         this.sharedLogger.fine("fine msg");
@@ -2526,12 +1828,6 @@
     /*
      * Test fine(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies fine(String) with null values.",
-        method = "fine",
-        args = {java.lang.String.class}
-    )
     public void testFine_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2560,12 +1856,6 @@
     /*
      * Test finer(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies finer(String) with normal values.",
-        method = "finer",
-        args = {java.lang.String.class}
-    )
     public void testFiner_Normal() {
         this.sharedLogger.setLevel(Level.FINER);
         this.sharedLogger.finer("finer msg");
@@ -2590,12 +1880,6 @@
     /*
      * Test finer(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies finer(String) with null values.",
-        method = "finer",
-        args = {java.lang.String.class}
-    )
     public void testFiner_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2624,12 +1908,6 @@
     /*
      * Test finest(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies finest(String) with normal values.",
-        method = "finest",
-        args = {java.lang.String.class}
-    )
     public void testFinest_Normal() {
         this.sharedLogger.setLevel(Level.FINEST);
         this.sharedLogger.finest("finest msg");
@@ -2654,12 +1932,6 @@
     /*
      * Test finest(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies finest(String) with null values.",
-        method = "finest",
-        args = {java.lang.String.class}
-    )
     public void testFinest_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2688,12 +1960,6 @@
     /*
      * Test info(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "info",
-        args = {java.lang.String.class}
-    )
     public void testInfo_Normal() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.info("info msg");
@@ -2718,12 +1984,6 @@
     /*
      * Test info(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "info",
-        args = {java.lang.String.class}
-    )
     public void testInfo_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2752,12 +2012,6 @@
     /*
      * Test warning(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "warning",
-        args = {java.lang.String.class}
-    )
     public void testWarning_Normal() {
         this.sharedLogger.setLevel(Level.WARNING);
         this.sharedLogger.warning("warning msg");
@@ -2782,12 +2036,6 @@
     /*
      * Test warning(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "warning",
-        args = {java.lang.String.class}
-    )
     public void testWarning_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2816,12 +2064,6 @@
     /*
      * Test severe(String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "severe",
-        args = {java.lang.String.class}
-    )
     public void testSevere_Normal() {
         this.sharedLogger.setLevel(Level.SEVERE);
         this.sharedLogger.severe("severe msg");
@@ -2846,12 +2088,6 @@
     /*
      * Test severe(String) with null values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "severe",
-        args = {java.lang.String.class}
-    )
     public void testSevere_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2880,12 +2116,6 @@
     /*
      * Test log(Level, String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class}
-    )
     public void testLog_LevelString_Normal() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.log(Level.INFO, "log(Level, String) msg");
@@ -2912,12 +2142,6 @@
     /*
      * Test log(Level, String) with null message.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class}
-    )
     public void testLog_LevelString_NullMsg() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -2942,12 +2166,6 @@
     /*
      * Test log(Level, String) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class}
-    )
     public void testLog_LevelString_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -2960,12 +2178,6 @@
     /*
      * Test log(Level, String, Object) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLog_LevelStringObject_Normal() {
         Object param = new Object();
         this.sharedLogger.setLevel(Level.INFO);
@@ -2997,12 +2209,6 @@
     /*
      * Test log(Level, String, Object) with null message and object.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLog_LevelStringObject_NullMsgObj() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3028,12 +2234,6 @@
     /*
      * Test log(Level, String, Object) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLog_LevelStringObject_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3047,12 +2247,6 @@
     /*
      * Test log(Level, String, Object[]) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object[].class}
-    )
             
     public void testLog_LevelStringObjects_Normal() {
         Object[] params = new Object[2];
@@ -3088,12 +2282,6 @@
     /*
      * Test log(Level, String, Object[]) with null message and object.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLog_LevelStringObjects_NullMsgObj() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3118,12 +2306,6 @@
     /*
      * Test log(Level, String, Object[]) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLog_LevelStringObjects_NullLevel() {
         try {
             this.sharedLogger.log(null, "log(Level, String, Object[]) msg",
@@ -3136,12 +2318,6 @@
     /*
      * Test log(Level, String, Throwable) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLog_LevelStringThrowable_Normal() {
         Throwable t = new Throwable();
         this.sharedLogger.setLevel(Level.INFO);
@@ -3172,12 +2348,6 @@
     /*
      * Test log(Level, String, Throwable) with null message and throwable.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLog_LevelStringThrowable_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3202,12 +2372,6 @@
     /*
      * Test log(Level, String, Throwable) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLog_LevelStringThrowable_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3221,12 +2385,6 @@
     /*
      * Test logp(Level, String, String, String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogp_LevelStringStringString_Normal() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.logp(Level.INFO, "sourceClass", "sourceMethod",
@@ -3256,12 +2414,6 @@
     /*
      * Test logp(Level, String, String, String) with null message.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogp_LevelStringStringString_NullMsg() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3286,12 +2438,6 @@
     /*
      * Test logp(Level, String, String, String) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogp_LevelStringStringString_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3305,12 +2451,6 @@
     /*
      * Test logp(Level, String, String, String, Object) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLogp_LevelStringStringStringObject_Normal() {
         Object param = new Object();
         this.sharedLogger.setLevel(Level.INFO);
@@ -3344,12 +2484,6 @@
      * Test logp(Level, String, String, String, Object) with null message and
      * object.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLogp_LevelStringStringStringObject_NullMsgObj() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3375,13 +2509,6 @@
     /*
      * Test logp(Level, String, String, String, Object) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
-            
     public void testLogp_LevelStringStringStringObject_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3396,13 +2523,6 @@
     /*
      * Test logp(Level, String, String, String, Object[]) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
-                    
     public void testLogp_LevelStringStringStringObjects_Normal() {
         Object[] params = new Object[2];
         params[0] = new Object();
@@ -3439,12 +2559,6 @@
      * Test logp(Level, String, String, String, Object[]) with null message and
      * object.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLogp_LevelStringStringStringObjects_NullMsgObj() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3469,12 +2583,6 @@
     /*
      * Test logp(Level, String, String, String, Object[]) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLogp_LevelStringStringStringObjects_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3489,12 +2597,6 @@
     /*
      * Test logp(Level, String, String, String, Throwable) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogp_LevelStringStringStringThrowable_Normal() {
         Throwable t = new Throwable();
         this.sharedLogger.setLevel(Level.INFO);
@@ -3527,12 +2629,6 @@
      * Test logp(Level, String, String, String, Throwable) with null message and
      * throwable.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogp_LevelStringStringStringThrowable_Null() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -3557,12 +2653,6 @@
     /*
      * Test logp(Level, String, String, String, Throwable) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logp",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogp_LevelStringStringStringThrowable_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3577,12 +2667,6 @@
     /*
      * Test logrb(Level, String, String, String, String) with normal values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogrb_LevelStringStringString_Normal() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.logrb(Level.INFO, "sourceClass", "sourceMethod",
@@ -3615,12 +2699,6 @@
     /*
      * Test logrb(Level, String, String, String, String) with null message.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogrb_LevelStringStringString_NullMsg() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.logrb(Level.INFO, null, null, null, null);
@@ -3639,12 +2717,6 @@
     /*
      * Test logrb(Level, String, String, String) with null level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogrb_LevelStringStringString_NullLevel() {
         try {
             this.sharedLogger.logrb(null, "sourceClass", "sourceMethod",
@@ -3659,12 +2731,6 @@
      * Test logrb(Level, String, String, String, String) with invalid resource
      * bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void testLogrb_LevelStringStringString_InvalidRes() {
         this.sharedLogger.setLevel(Level.ALL);
         this.sharedLogger.logrb(Level.ALL, "sourceClass", "sourceMethod",
@@ -3688,12 +2754,6 @@
      * Test logrb(Level, String, String, String, String, Object) with normal
      * values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLogrb_LevelStringStringStringObject_Normal() {
         Object param = new Object();
         this.sharedLogger.setLevel(Level.INFO);
@@ -3731,12 +2791,6 @@
      * Test logrb(Level, String, String, String, String, Object) with null
      * message and object.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLogrb_LevelStringStringStringObject_NullMsgObj() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.logrb(Level.INFO, null, null, null, null,
@@ -3758,12 +2812,6 @@
      * java.util.logging.Logger#logrb(Level, String, String, String, String,
      * Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test.",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
     public void test_logrbLLevel_LString_LString_LObject_Security()
             throws Exception {
         // regression test for Harmony-1290
@@ -3780,12 +2828,6 @@
      * Test logrb(Level, String, String, String, String, Object) with null
      * level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLogrb_LevelStringStringStringObject_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -3802,12 +2844,6 @@
      * Test logrb(Level, String, String, String, String, Object) with invalid
      * resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object.class}
-    )
     public void testLogrb_LevelStringStringStringObject_InvalidRes() {
         Object param = new Object();
         this.sharedLogger.setLevel(Level.ALL);
@@ -3832,13 +2868,7 @@
     /*
      * Test logrb(Level, String, String, String, String, Object[]) with normal
      * values.
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )      
+     */      
     public void testLogrb_LevelStringStringStringObjects_Normal() {
         Object[] params = new Object[2];
         params[0] = new Object();
@@ -3879,12 +2909,6 @@
      * Test logrb(Level, String, String, String, String, Object[]) with null
      * message and object.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLogrb_LevelStringStringStringObjects_NullMsgObj() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.logrb(Level.INFO, null, null, null, null,
@@ -3905,12 +2929,6 @@
      * Test logrb(Level, String, String, String, String, Object[]) with null
      * level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLogrb_LevelStringStringStringObjects_NullLevel() {
         try {
             this.sharedLogger.logrb(
@@ -3929,12 +2947,6 @@
      * Test logrb(Level, String, String, String, String, Object[]) with invalid
      * resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void testLogrb_LevelStringStringStringObjects_InvalidRes() {
         Object[] params = new Object[2];
         params[0] = new Object();
@@ -3963,12 +2975,6 @@
      * Test logrb(Level, String, String, String, String, Throwable) with normal
      * values.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogrb_LevelStringStringStringThrowable_Normal() {
         Throwable t = new Throwable();
         this.sharedLogger.setLevel(Level.INFO);
@@ -4006,12 +3012,6 @@
      * Test logrb(Level, String, String, String, String, Throwable) with null
      * message and throwable.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogrb_LevelStringTStringStringhrowable_NullMsgObj() {
         this.sharedLogger.setLevel(Level.INFO);
         this.sharedLogger.logrb(Level.INFO, null, null, null, null,
@@ -4032,12 +3032,6 @@
      * Test logrb(Level, String, String, String, String, Throwable) with null
      * level.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogrb_LevelStringStringStringThrowable_NullLevel() {
         // this.sharedLogger.setLevel(Level.OFF);
         try {
@@ -4057,12 +3051,6 @@
      * Test logrb(Level, String, String, String, String, Throwable) with invalid
      * resource bundle.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "logrb",
-        args = {java.util.logging.Level.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.Throwable.class}
-    )
     public void testLogrb_LevelStringStringStringThrowable_InvalidRes() {
         Throwable t = new Throwable();
         this.sharedLogger.setLevel(Level.ALL);
@@ -4087,12 +3075,6 @@
      * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
      * appropriate level, no filter, no parent.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_LogRecord_AppropriateLevelNoFilterNoParent() {
         LogRecord r = new LogRecord(Level.INFO,
         "testLog_LogRecord_AppropriateLevelNoFilterNoParent");
@@ -4116,12 +3098,6 @@
     /*
      * Test log(LogRecord) with null log record.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_LogRecord_Null() {
         this.sharedLogger.setLevel(Level.INFO);
         try {
@@ -4135,12 +3111,6 @@
      * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
      * inappropriate level, no filter, no parent.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_LogRecord_InppropriateLevelNoFilterNoParent() {
         LogRecord r = new LogRecord(Level.INFO,
                 "testLog_LogRecord_InppropriateLevelNoFilterNoParent");
@@ -4159,12 +3129,6 @@
      * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
      * appropriate level, a filter that accepts the fed log record, no parent.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_LogRecord_AppropriateLevelTrueFilterNoParent() {
         LogRecord r = new LogRecord(Level.INFO,
                 "testLog_LogRecord_AppropriateLevelTrueFilterNoParent");
@@ -4193,12 +3157,6 @@
      * Test log(LogRecord) for a normal log record. Meanwhile the logger has an
      * appropriate level, a filter that rejects the fed log record, no parent.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_LogRecord_AppropriateLevelFalseFilterNoParent() {
         LogRecord r = new LogRecord(Level.INFO,
                 "testLog_LogRecord_AppropriateLevelFalseFilterNoParent");
@@ -4226,12 +3184,6 @@
      * Test that the parent's handler is notified for a new log record when
      * getUseParentHandlers() is true.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_ParentInformed() {
         Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
         Logger parent = new MockParentLogger("parentLogger",
@@ -4284,12 +3236,6 @@
      * Test that the ancestor's handler is notified for a new log record when
      * getUseParentHandlers() is true.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_AncestorInformed() {
         Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
         Logger parent = new MockParentLogger("parentLogger",
@@ -4336,12 +3282,6 @@
      * Test that the parent's handler is notified for a new log record when
      * getUseParentHandlers() is false.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_ParentNotInformed() {
         Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
         Logger parent = new MockParentLogger("parentLogger",
@@ -4362,12 +3302,6 @@
      * Test that a logger with null level and no parent. Defaulted to
      * Level.INFO.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_NullLevelNoParent() {
         LogRecord r = new LogRecord(Level.INFO, "testLog_NullLevelNoParent");
         assertNull(this.sharedLogger.getLevel());
@@ -4393,12 +3327,6 @@
     /*
      * Test that a logger inherits its parent level when its level is null.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_NullLevelHasParent() {
         Logger child = new MockLogger("childLogger", VALID_RESOURCE_BUNDLE);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -4451,12 +3379,6 @@
      * Test that a logger with null resource bundle and no parent. Defaulted to
      * null.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_NullResNoParent() {
         Logger log = new MockLogger("Logger", null);
         log.addHandler(new MockHandler());
@@ -4478,12 +3400,6 @@
      * Test that a logger inherits its parent resource bundle when its resource
      * bundle is null.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_NullResHasParent() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", VALID_RESOURCE_BUNDLE2);
@@ -4514,12 +3430,6 @@
      * Test that a logger inherits its ancestor's resource bundle when its
      * resource bundle and its parent's resource bundle are both null.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_NullResHasAncestor() {
         Logger child = new MockLogger("childLogger", null);
         Logger parent = new MockLogger("parentLogger", null);
@@ -4552,12 +3462,6 @@
     /*
      * Test when one handler throws an exception.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLog_ExceptionalHandler() {
         MockLogger l = new MockLogger("testLog_ExceptionalHandler", null);
         l.addHandler(new MockExceptionalHandler());
@@ -4573,12 +3477,6 @@
     /*
      * Test whether privileged code is used to load resource bundles.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAnonymousLogger",
-        args = {java.lang.String.class}
-    )
     public void testLoadResourceBundle() {
         // 
         SecurityManager oldMan = System.getSecurityManager();
@@ -4595,12 +3493,6 @@
      * java.util.logging.Logger#logrb(Level, String, String, String, String,
      * Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getLogger",
-        args = {java.lang.String.class}
-    )
     public void test_init_logger() throws Exception {
         Properties p = new Properties();
         p.put("testGetLogger_Normal_ANewLogger2.level", "ALL");
@@ -4634,15 +3526,9 @@
     /*
      * test initHandler
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "initHandler",
-        args = {}
-    )
-    @KnownFailure("This test doesn't load its resources properly")
     public void test_initHandler() throws Exception {
-        File logProps = new File(LOGGING_CONFIG_FILE);
+        File logProps = Support_Resources.getExternalLocalFile(
+                getClass().getResource(LOGGING_CONFIG_FILE).toString());
         LogManager lm = LogManager.getLogManager();
         lm.readConfiguration(new FileInputStream(logProps));
 
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java
index c9b7d50..36cfb33 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingMXBeanTest.java
@@ -16,11 +16,6 @@
  */
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-
 import junit.framework.TestCase;
 
 import tests.util.CallVerificationStack;
@@ -31,7 +26,6 @@
  * This testcase verifies the signature of the interface Filter.
  * 
  */
-@TestTargetClass(LoggingMXBean.class) 
 public class LoggingMXBeanTest extends TestCase {
     
     private MockLoggingMXBean m = null;
@@ -53,43 +47,19 @@
     
        
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getLoggerLevel",
-        args = {java.lang.String.class}
-    )
     public void testGetLoggerLevel() {
         assertNull(m.getLoggerLevel(null));
     }
 
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getLoggerNames",
-        args = {}
-    )
           public void testGetLoggerNames() {
                 assertNull(m.getLoggerNames());
           }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getParentLoggerName",
-        args = {java.lang.String.class}
-    )
           public void testGetParentLoggerName() {
               assertNull(m.getParentLoggerName(null));
           }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setLoggerLevel",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
           public void testSetLoggerLevel() {
             try{
                 m.setLoggerLevel(null,null);
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java
index 9507bbd..aa8f7fa 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/LoggingPermissionTest.java
@@ -17,29 +17,17 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.util.logging.LoggingPermission;
 
 import junit.framework.TestCase;
 
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(LoggingPermission.class) 
 public class LoggingPermissionTest extends TestCase {
 
     /**
      * @tests serialization/deserialization compatibility.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
         SerializationTest.verifySelf(new LoggingPermission("control", ""));
     }
@@ -47,55 +35,43 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new LoggingPermission("control",
                 ""));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "LoggingPermission",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
-    public void testLoggingPermission() {
-        try {
-            new LoggingPermission(null, null);
-            fail("should throw IllegalArgumentException");
-        } catch (NullPointerException e) {
-        }
-        try {
-            new LoggingPermission("", null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            new LoggingPermission("bad name", null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            new LoggingPermission("Control", null);
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-        }
-        try {
-            new LoggingPermission("control",
-                    "bad action");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-        }
-        
+	public void testLoggingPermission() {
+		try {
+			new LoggingPermission(null, null);
+			fail("should throw IllegalArgumentException");
+		} catch (NullPointerException e) {
+		}
+		try {
+			new LoggingPermission("", null);
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			new LoggingPermission("bad name", null);
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			new LoggingPermission("Control", null);
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+		}
+		try {
+			new LoggingPermission("control",
+					"bad action");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+		}
+		
         new LoggingPermission("control", "");
-        
+		
         new LoggingPermission("control", null);
-    }
+	}
 
 }
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java
index 9aa344a..89629c7 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MemoryHandlerTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
@@ -47,7 +42,6 @@
 /**
  * 
  */
-@TestTargetClass(MemoryHandler.class)
 public class MemoryHandlerTest extends TestCase {
 
     final static LogManager manager = LogManager.getLogManager();
@@ -107,50 +101,6 @@
         System.setErr(err);        
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "close",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "setPushLevel",
-            args = {java.util.logging.Level.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "flush",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "push",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "getPushLevel",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "isLoggable",
-            args = {java.util.logging.LogRecord.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "SecurityException",
-            method = "publish",
-            args = {java.util.logging.LogRecord.class}
-        )
-    })
     public void testGlobalSecurity() {
         SecurityManager currentManager = System.getSecurityManager();
         System.setSecurityManager(securityManager);
@@ -176,12 +126,6 @@
 
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
     public void testClose() {
         Filter filter = handler.getFilter();
         Formatter formatter = handler.getFormatter();
@@ -197,12 +141,6 @@
         assertFalse(handler.isLoggable(new LogRecord(Level.SEVERE, "test")));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "flush",
-        args = {}
-    )
     public void testFlush() {
         Filter filter = handler.getFilter();
         Formatter formatter = handler.getFormatter();
@@ -218,12 +156,6 @@
         assertTrue(handler.isLoggable(new LogRecord(Level.SEVERE, "test")));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testIsLoggable() {
         try {
             handler.isLoggable(null);
@@ -255,12 +187,6 @@
     /*
      * Class under test for void MemoryHandler()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "check errors",
-        method = "MemoryHandler",
-        args = {}
-    )
     public void testMemoryHandler() throws IOException {
         assertNotNull("Filter should not be null", handler.getFilter());
         assertNotNull("Formatter should not be null", handler.getFormatter());
@@ -287,12 +213,6 @@
  
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "MemoryHandler",
-        args = {}
-    )
     public void testMemoryHandlerInvalidProps() throws IOException {
         // null target
         try {
@@ -360,12 +280,6 @@
 
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "MemoryHandler",
-        args = {}
-    )
     public void testMemoryHandlerDefaultValue() throws SecurityException,
             IOException {
         props.clear();
@@ -386,12 +300,6 @@
     /*
      * Class under test for void MemoryHandler(Handler, int, Level)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "MemoryHandler",
-        args = {java.util.logging.Handler.class, int.class, java.util.logging.Level.class}
-    )
     public void testMemoryHandlerHandlerintLevel() {
         handler = new MemoryHandler(target, 2, Level.FINEST);
         assertNotNull("Filter should not be null", handler.getFilter());
@@ -426,12 +334,6 @@
 
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPushLevel",
-        args = {}
-    )
     public void testGetPushLevel() {
         try {
             handler.setPushLevel(null);
@@ -442,12 +344,6 @@
         assertEquals(handler.getPushLevel(), Level.parse("123"));
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setPushLevel",
-        args = {java.util.logging.Level.class}
-    )
     public void testSetPushLevel() {
         // change push level don't trigger push action
         writer.getBuffer().setLength(0);
@@ -462,12 +358,6 @@
         assertEquals(writer.toString(), lr.getMessage() + lr.getMessage());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "push",
-        args = {}
-    )
     public void testPushPublic() {
         writer.getBuffer().setLength(0);
         // loggable but don't trig push
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java
deleted file mode 100644
index 74edbcb..0000000
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/MessagesTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package org.apache.harmony.logging.tests.java.util.logging;
-
-import junit.framework.TestCase;
-
-import org.apache.harmony.logging.internal.nls.Messages;
-
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.logging.ErrorManager;
-
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-
-
-@TestTargetClass(Messages.class) 
-public class MessagesTest extends TestCase{
-
-
-        private Messages m = null;
-        
-        public void setUp() throws Exception{
-            super.setUp();
-            m = new Messages();
-        
-        }
-        
-        public void tearDown() throws Exception{
-            super.tearDown();
-        }
-        
-        
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Just check signature, cannot make use of mock, method depend on luni",
-        method = "getString",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("harmony specific")
-    public void testGetString_String() {
-            m.getString(new String());
-    }
-        
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Juste check signature, cannot make use of mock, depend on luni",
-        method = "getString",
-        args = {java.lang.String.class, java.lang.Object.class}
-    )
-    @AndroidOnly("harmony specific")    
-    public void testGetString_StringObject() {
-        m.getString(new String(), new Object());
-    }
-        
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Juste check signature, cannot make use of mock, depend on luni",
-        method = "getString",
-        args = {java.lang.String.class, int.class}
-    )
-    @AndroidOnly("harmony specific")
-    public void testGetString_StringInt() {
-        m.getString(new String(), 0);
-    }
-        
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Juste check signature, cannot make use of mock, depend on luni",
-        method = "getString",
-        args = {java.lang.String.class, char.class}
-    )
-    @AndroidOnly("harmony specific")
-    public void testGetString_StringChar() {
-        m.getString(new String(), 'a');
-    }
-        
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Juste check signature, cannot make use of mock, depend on luni",
-        method = "getString",
-        args = {java.lang.String.class, java.lang.Object.class, java.lang.Object.class}
-    )
-    @AndroidOnly("harmony specific")
-    public void testGetString_StringObjectObject() {
-            m.getString(new String(), new Object(), new Object() );
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Juste check signature, cannot make use of mock, depend on luni",
-        method = "getString",
-        args = {java.lang.String.class, java.lang.Object[].class}
-    )
-    @AndroidOnly("harmony specific")
-    public void testGetString_StringObjectArray() {
-            m.getString(new String(), new Object[1]);
-    }
-      
-
-}
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java
index 79e37e8..16d051d 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SimpleFormatterTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.util.Calendar;
 import java.util.ResourceBundle;
 import java.util.logging.Handler;
@@ -35,7 +30,6 @@
 /**
  * 
  */
-@TestTargetClass(SimpleFormatter.class)
 public class SimpleFormatterTest extends TestCase {
 
     SimpleFormatter sf;
@@ -56,38 +50,12 @@
     /*
      * test for constructor protected SimpleFormatter
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "SimpleFormatter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getHead",
-            args = {java.util.logging.Handler.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getTail",
-            args = {java.util.logging.Handler.class}
-        )
-    })
     public void testSimpleFormatter() {
         assertEquals("Head for this SimpleFormatter should be empty", "", sf
                 .getHead(null));
         assertEquals("Tail for this SimpleFormatter should be empty", "", sf
                 .getTail(null));
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testFormatNull() {
         try {
             sf.format(null);
@@ -97,12 +65,6 @@
         sf.format(new LogRecord(Level.SEVERE, null));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLocalizedFormat() {
         // if bundle set, should use localized message
         ResourceBundle rb = ResourceBundle
@@ -122,12 +84,6 @@
         assertTrue(str.indexOf(localeMsg) < 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testFormat() {
         String str = sf.format(lr);
         Throwable t;
@@ -159,22 +115,10 @@
         assertTrue(str.indexOf(Level.FINE.getLocalizedName()) > 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getHead",
-        args = {java.util.logging.Handler.class}
-    )
     public void testGetHead() {
         assertEquals("", sf.getHead(null));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getTail",
-        args = {java.util.logging.Handler.class}
-    )
     public void testGetTail() {
         assertEquals("", sf.getTail(null));
     }
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java
index cc3b165..bbf30b0 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/SocketHandlerTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -52,7 +47,6 @@
 /**
  * Test class java.util.logging.ConsoleHandler
  */
-@TestTargetClass(SocketHandler.class)
 public class SocketHandlerTest extends TestCase {
 
     private static final LogManager LOG_MANAGER = LogManager.getLogManager();
@@ -116,20 +110,6 @@
     /*
      * Test the constructor with no relevant log manager properties are set.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with no relevant log manager properties are set.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with no relevant log manager properties are set.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_NoProperties() throws Exception {
         assertNull(LOG_MANAGER.getProperty(
                 "java.util.logging.SocketHandler.level"));
@@ -205,20 +185,6 @@
      * Test the constructor with no relevant log manager properties are set
      * except host and port.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with no relevant log manager properties are set except host and port.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with no relevant log manager properties are set except host and port.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_NoBasicProperties() throws Exception {
         assertNull(LOG_MANAGER.getProperty(
                 "java.util.logging.SocketHandler.level"));
@@ -258,20 +224,6 @@
     /*
      * Test the constructor with insufficient privilege for connection.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies SecurityException.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_InsufficientPrivilege() throws Exception {
         SecurityManager oldMan = null;
         Properties p = new Properties();
@@ -308,20 +260,6 @@
     /*
      * Test the constructor with valid relevant log manager properties are set.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with valid relevant log manager properties are set.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with valid relevant log manager properties are set.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_ValidProperties() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.level", "FINE");
@@ -368,20 +306,6 @@
      * Test the constructor with invalid relevant log manager properties are set
      * except host and port.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with invalid relevant log manager properties are set except host and port.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies the constructor with invalid relevant log manager properties are set except host and port.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_InvalidBasicProperties() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.level", INVALID_LEVEL);
@@ -430,12 +354,6 @@
      * Test the constructor with valid relevant log manager properties are set
      * except port.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IllegalArgumentException.",
-        method = "SocketHandler",
-        args = {}
-    )
     public void testConstructor_InvalidPort() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.level", "FINE");
@@ -461,20 +379,6 @@
      * Test the constructor with valid relevant log manager properties are set,
      * but the port is not open.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies that the constructor with valid relevant log manager properties are set, but the port is not open.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies that the constructor with valid relevant log manager properties are set, but the port is not open.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_NotOpenPort() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.level", "FINE");
@@ -507,20 +411,6 @@
      * Test the constructor with valid relevant log manager properties are set
      * except port.
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies IOException.",
-            method = "SocketHandler",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies IOException.",
-            method = "SocketHandler",
-            args = {java.lang.String.class, int.class}
-        )
-    })
     public void testConstructor_InvalidHost() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.level", "FINE");
@@ -553,12 +443,6 @@
      * Test close() when having sufficient privilege, and a record has been
      * written to the output stream.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having sufficient privilege, and a record has been written to the output stream.",
-        method = "close",
-        args = {}
-    )
     public void testClose_SufficientPrivilege_NormalClose() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -587,12 +471,6 @@
      * Test close() when having sufficient privilege, and no record has been
      * written to the output stream.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having sufficient privilege, and no record has been written to the output stream.",
-        method = "close",
-        args = {}
-    )
     public void testClose_SufficientPrivilege_DirectClose() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -618,12 +496,6 @@
     /*
      * Test close() when having insufficient privilege.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having insufficient privilege.",
-        method = "close",
-        args = {}
-    )
     public void testClose_InsufficientPrivilege() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -658,12 +530,6 @@
     /*
      * Test publish(), use no filter, having output stream, normal log record.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), use no filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish_NoFilter() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -703,12 +569,6 @@
     /*
      * Test publish(), use a filter, having output stream, normal log record.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), use a filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish_WithFilter() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -739,12 +599,6 @@
     /*
      * Test publish(), null log record, having output stream
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), null log record, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish_Null() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -772,12 +626,6 @@
     /*
      * Test publish(), a log record with empty msg, having output stream
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies  publish() method, a log record with empty msg, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish_EmptyMsg() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -803,12 +651,6 @@
     /*
      * Test publish(), a log record with null msg, having output stream
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), a log record with null msg, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish_NullMsg() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
@@ -834,12 +676,6 @@
     /*
      * Test publish(), after close.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish() method after close.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testPublish_AfterClose() throws Exception {
         Properties p = new Properties();
         p.put("java.util.logging.SocketHandler.formatter", className
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java
index 72270e5..76380e6 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/StreamHandlerTest.java
@@ -17,8 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.*;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -39,7 +37,6 @@
 import java.util.logging.LogRecord;
 import java.util.logging.LoggingPermission;
 import java.util.logging.SimpleFormatter;
-import java.util.logging.SocketHandler;
 import java.util.logging.StreamHandler;
 
 import junit.framework.TestCase;
@@ -51,1274 +48,1035 @@
 /**
  * Test the class StreamHandler.
  */
-@TestTargetClass(StreamHandler.class)
 public class StreamHandlerTest extends TestCase {
 
-    private final static String INVALID_LEVEL = "impossible_level";
+	private final static String INVALID_LEVEL = "impossible_level";
     
     private final PrintStream err = System.err;
 
     private OutputStream errSubstituteStream = null;     
 
-    private static String className = StreamHandlerTest.class.getName();
+	private static String className = StreamHandlerTest.class.getName();
 
-    private static CharsetEncoder encoder;
+	private static CharsetEncoder encoder;
 
-    static {
-        encoder = Charset.forName("iso-8859-1").newEncoder();
-        encoder.onMalformedInput(CodingErrorAction.REPLACE);
-        encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
-    }
+	static {
+		encoder = Charset.forName("iso-8859-1").newEncoder();
+		encoder.onMalformedInput(CodingErrorAction.REPLACE);
+		encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+	}
 
-    /*
-     * @see TestCase#setUp()
-     */
-    protected void setUp() throws Exception {
-        super.setUp();
+	/*
+	 * @see TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
         errSubstituteStream = new NullOutputStream();
         System.setErr(new PrintStream(errSubstituteStream));          
-    }
+	}
 
-    /*
-     * @see TestCase#tearDown()
-     */
-    protected void tearDown() throws Exception {
-        LogManager.getLogManager().reset();
-        CallVerificationStack.getInstance().clear();
+	/*
+	 * @see TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		LogManager.getLogManager().reset();
+		CallVerificationStack.getInstance().clear();
         System.setErr(err);        
         super.tearDown();
-    }
+	}
 
-    /*
-     * Test the constructor with no parameter, and no relevant log manager
-     * properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with no parameter, and no relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {}
-    )
-    public void testConstructor_NoParameter_NoProperties() {
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.filter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.formatter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
+	/*
+	 * Test the constructor with no parameter, and no relevant log manager
+	 * properties are set.
+	 */
+	public void testConstructor_NoParameter_NoProperties() {
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.filter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.formatter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
 
-        StreamHandler h = new StreamHandler();
-        assertSame(Level.INFO, h.getLevel());
-        assertTrue(h.getFormatter() instanceof SimpleFormatter);
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-    }
+		StreamHandler h = new StreamHandler();
+		assertSame(Level.INFO, h.getLevel());
+		assertTrue(h.getFormatter() instanceof SimpleFormatter);
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test the constructor with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with insufficient privilege.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_NoParameter_InsufficientPrivilege() {
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.filter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.formatter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
+	/*
+	 * Test the constructor with insufficient privilege.
+	 */
+	public void testConstructor_NoParameter_InsufficientPrivilege() {
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.filter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.formatter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
 
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        // set a normal value
-        try {
-            StreamHandler h = new StreamHandler();
-            assertSame(Level.INFO, h.getLevel());
-            assertTrue(h.getFormatter() instanceof SimpleFormatter);
-            assertNull(h.getFilter());
-            assertNull(h.getEncoding());
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		// set a normal value
+		try {
+			StreamHandler h = new StreamHandler();
+			assertSame(Level.INFO, h.getLevel());
+			assertTrue(h.getFormatter() instanceof SimpleFormatter);
+			assertNull(h.getFilter());
+			assertNull(h.getEncoding());
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Test the constructor with no parameter, and valid relevant log manager
-     * properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with no parameter, and valid relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {}
-    )
-    public void testConstructor_NoParameter_ValidProperties() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", "FINE");
-        p.put("java.util.logging.StreamHandler.filter", className
-                + "$MockFilter");
-        p.put("java.util.logging.StreamHandler.formatter", className
-                + "$MockFormatter");
-        p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with no parameter, and valid relevant log manager
+	 * properties are set.
+	 */
+	public void testConstructor_NoParameter_ValidProperties() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", "FINE");
+		p.put("java.util.logging.StreamHandler.filter", className
+				+ "$MockFilter");
+		p.put("java.util.logging.StreamHandler.formatter", className
+				+ "$MockFormatter");
+		p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals("FINE", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
-        StreamHandler h = new StreamHandler();
-        assertSame(h.getLevel(), Level.parse("FINE"));
-        assertTrue(h.getFormatter() instanceof MockFormatter);
-        assertTrue(h.getFilter() instanceof MockFilter);
-        assertEquals("iso-8859-1", h.getEncoding());
-    }
+		assertEquals("FINE", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
+		StreamHandler h = new StreamHandler();
+		assertSame(h.getLevel(), Level.parse("FINE"));
+		assertTrue(h.getFormatter() instanceof MockFormatter);
+		assertTrue(h.getFilter() instanceof MockFilter);
+		assertEquals("iso-8859-1", h.getEncoding());
+	}
 
-    /*
-     * Test the constructor with no parameter, and invalid relevant log manager
-     * properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with no parameter, and invalid relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {}
-    )
-    public void testConstructor_NoParameter_InvalidProperties()
-            throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", INVALID_LEVEL);
-        p.put("java.util.logging.StreamHandler.filter", className + "");
-        p.put("java.util.logging.StreamHandler.formatter", className + "");
-        p.put("java.util.logging.StreamHandler.encoding", "XXXX");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with no parameter, and invalid relevant log manager
+	 * properties are set.
+	 */
+	public void testConstructor_NoParameter_InvalidProperties()
+			throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", INVALID_LEVEL);
+		p.put("java.util.logging.StreamHandler.filter", className + "");
+		p.put("java.util.logging.StreamHandler.formatter", className + "");
+		p.put("java.util.logging.StreamHandler.encoding", "XXXX");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals(INVALID_LEVEL, LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertEquals("XXXX", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
-        StreamHandler h = new StreamHandler();
-        assertSame(Level.INFO, h.getLevel());
-        assertTrue(h.getFormatter() instanceof SimpleFormatter);
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-        h.publish(new LogRecord(Level.SEVERE, "test"));
-        assertTrue(CallVerificationStack.getInstance().empty());
-        assertNull(h.getEncoding());
-    }
+		assertEquals(INVALID_LEVEL, LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertEquals("XXXX", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
+		StreamHandler h = new StreamHandler();
+		assertSame(Level.INFO, h.getLevel());
+		assertTrue(h.getFormatter() instanceof SimpleFormatter);
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+		h.publish(new LogRecord(Level.SEVERE, "test"));
+		assertTrue(CallVerificationStack.getInstance().empty());
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test the constructor with normal parameter values, and no relevant log
-     * manager properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with normal parameter values, and no relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_HasParameters_NoProperties() {
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.filter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.formatter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
+	/*
+	 * Test the constructor with normal parameter values, and no relevant log
+	 * manager properties are set.
+	 */
+	public void testConstructor_HasParameters_NoProperties() {
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.filter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.formatter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
 
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new MockFormatter2());
-        assertSame(Level.INFO, h.getLevel());
-        assertTrue(h.getFormatter() instanceof MockFormatter2);
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-    }
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new MockFormatter2());
+		assertSame(Level.INFO, h.getLevel());
+		assertTrue(h.getFormatter() instanceof MockFormatter2);
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test the constructor with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with insufficient privilege.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_HasParameter_InsufficientPrivilege() {
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.filter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.formatter"));
-        assertNull(LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
+	/*
+	 * Test the constructor with insufficient privilege.
+	 */
+	public void testConstructor_HasParameter_InsufficientPrivilege() {
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.filter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.formatter"));
+		assertNull(LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
 
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        // set a normal value
-        try {
-            StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                    new MockFormatter2());
-            assertSame(Level.INFO, h.getLevel());
-            assertTrue(h.getFormatter() instanceof MockFormatter2);
-            assertNull(h.getFilter());
-            assertNull(h.getEncoding());
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		// set a normal value
+		try {
+			StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+					new MockFormatter2());
+			assertSame(Level.INFO, h.getLevel());
+			assertTrue(h.getFormatter() instanceof MockFormatter2);
+			assertNull(h.getFilter());
+			assertNull(h.getEncoding());
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * Test the constructor with normal parameter values, and valid relevant log
-     * manager properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with normal parameter values, and valid relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_HasParameters_ValidProperties()
-            throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", "FINE");
-        p.put("java.util.logging.StreamHandler.filter", className
-                + "$MockFilter");
-        p.put("java.util.logging.StreamHandler.formatter", className
-                + "$MockFormatter");
-        p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with normal parameter values, and valid relevant log
+	 * manager properties are set.
+	 */
+	public void testConstructor_HasParameters_ValidProperties()
+			throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", "FINE");
+		p.put("java.util.logging.StreamHandler.filter", className
+				+ "$MockFilter");
+		p.put("java.util.logging.StreamHandler.formatter", className
+				+ "$MockFormatter");
+		p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals("FINE", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new MockFormatter2());
-        assertSame(h.getLevel(), Level.parse("FINE"));
-        assertTrue(h.getFormatter() instanceof MockFormatter2);
-        assertTrue(h.getFilter() instanceof MockFilter);
-        assertEquals("iso-8859-1", h.getEncoding());
-    }
+		assertEquals("FINE", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new MockFormatter2());
+		assertSame(h.getLevel(), Level.parse("FINE"));
+		assertTrue(h.getFormatter() instanceof MockFormatter2);
+		assertTrue(h.getFilter() instanceof MockFilter);
+		assertEquals("iso-8859-1", h.getEncoding());
+	}
 
-    /*
-     * Test the constructor with normal parameter, and invalid relevant log
-     * manager properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with normal parameter, and invalid relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_HasParameters_InvalidProperties()
-            throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", INVALID_LEVEL);
-        p.put("java.util.logging.StreamHandler.filter", className + "");
-        p.put("java.util.logging.StreamHandler.formatter", className + "");
-        p.put("java.util.logging.StreamHandler.encoding", "XXXX");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with normal parameter, and invalid relevant log
+	 * manager properties are set.
+	 */
+	public void testConstructor_HasParameters_InvalidProperties()
+			throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", INVALID_LEVEL);
+		p.put("java.util.logging.StreamHandler.filter", className + "");
+		p.put("java.util.logging.StreamHandler.formatter", className + "");
+		p.put("java.util.logging.StreamHandler.encoding", "XXXX");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals(INVALID_LEVEL, LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertEquals("XXXX", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new MockFormatter2());
-        assertSame(Level.INFO, h.getLevel());
-        assertTrue(h.getFormatter() instanceof MockFormatter2);
-        assertNull(h.getFilter());
-        assertNull(h.getEncoding());
-    }
+		assertEquals(INVALID_LEVEL, LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertEquals("XXXX", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new MockFormatter2());
+		assertSame(Level.INFO, h.getLevel());
+		assertTrue(h.getFormatter() instanceof MockFormatter2);
+		assertNull(h.getFilter());
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test the constructor with null formatter, and invalid relevant log manager
-     * properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with null formatter, and invalid relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_HasParameters_ValidPropertiesNullStream()
-            throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", "FINE");
-        p.put("java.util.logging.StreamHandler.filter", className
-                + "$MockFilter");
-        p.put("java.util.logging.StreamHandler.formatter", className
-                + "$MockFormatter");
-        p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with null formatter, and invalid relevant log manager
+	 * properties are set.
+	 */
+	public void testConstructor_HasParameters_ValidPropertiesNullStream()
+			throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", "FINE");
+		p.put("java.util.logging.StreamHandler.filter", className
+				+ "$MockFilter");
+		p.put("java.util.logging.StreamHandler.formatter", className
+				+ "$MockFormatter");
+		p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals("FINE", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
-        try {
-            new StreamHandler(new ByteArrayOutputStream(), null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
+		assertEquals("FINE", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
+		try {
+			new StreamHandler(new ByteArrayOutputStream(), null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
 
-    /*
-     * Test the constructor with null output stream, and invalid relevant log
-     * manager properties are set.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies the constructor with null output stream, and invalid relevant log manager properties are set.",
-        method = "StreamHandler",
-        args = {java.io.OutputStream.class, java.util.logging.Formatter.class}
-    )
-    public void testConstructor_HasParameters_ValidPropertiesNullFormatter()
-            throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", "FINE");
-        p.put("java.util.logging.StreamHandler.filter", className
-                + "$MockFilter");
-        p.put("java.util.logging.StreamHandler.formatter", className
-                + "$MockFormatter");
-        p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test the constructor with null output stream, and invalid relevant log
+	 * manager properties are set.
+	 */
+	public void testConstructor_HasParameters_ValidPropertiesNullFormatter()
+			throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", "FINE");
+		p.put("java.util.logging.StreamHandler.filter", className
+				+ "$MockFilter");
+		p.put("java.util.logging.StreamHandler.formatter", className
+				+ "$MockFormatter");
+		p.put("java.util.logging.StreamHandler.encoding", "iso-8859-1");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        assertEquals("FINE", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.level"));
-        assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
-                "java.util.logging.StreamHandler.encoding"));
-        try {
-            new StreamHandler(null, new MockFormatter2());
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
+		assertEquals("FINE", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.level"));
+		assertEquals("iso-8859-1", LogManager.getLogManager().getProperty(
+				"java.util.logging.StreamHandler.encoding"));
+		try {
+			new StreamHandler(null, new MockFormatter2());
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
 
-    /*
-     * Test close() when having sufficient privilege, and a record has been
-     * written to the output stream.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having sufficient privilege, and a record has been written to the output stream.",
-        method = "close",
-        args = {}
-    )
-    public void testClose_SufficientPrivilege_NormalClose() {
-        ByteArrayOutputStream aos = new MockOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.publish(new LogRecord(Level.SEVERE,
-                "testClose_SufficientPrivilege_NormalClose msg"));
-        h.close();
-        assertEquals("close", CallVerificationStack.getInstance()
-                .getCurrentSourceMethod());
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertEquals("flush", CallVerificationStack.getInstance()
-                .getCurrentSourceMethod());
-        CallVerificationStack.getInstance().clear();
-        assertTrue(aos.toString().endsWith("MockFormatter_Tail"));
-        h.close();
-    }
+	/*
+	 * Test close() when having sufficient privilege, and a record has been
+	 * written to the output stream.
+	 */
+	public void testClose_SufficientPrivilege_NormalClose() {
+		ByteArrayOutputStream aos = new MockOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.publish(new LogRecord(Level.SEVERE,
+				"testClose_SufficientPrivilege_NormalClose msg"));
+		h.close();
+		assertEquals("close", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertEquals("flush", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		CallVerificationStack.getInstance().clear();
+		assertTrue(aos.toString().endsWith("MockFormatter_Tail"));
+		h.close();
+	}
 
-    /*
-     * Test close() when having sufficient privilege, and an output stream that
-     * always throws exceptions.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() when having sufficient privilege, and an output stream that always throws exceptions.",
-        method = "close",
-        args = {}
-    )
-    public void testClose_SufficientPrivilege_Exception() {
-        ByteArrayOutputStream aos = new MockExceptionOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.publish(new LogRecord(Level.SEVERE,
-                "testClose_SufficientPrivilege_Exception msg"));
-        h.flush();
-        h.close();
-    }
+	/*
+	 * Test close() when having sufficient privilege, and an output stream that
+	 * always throws exceptions.
+	 */
+	public void testClose_SufficientPrivilege_Exception() {
+		ByteArrayOutputStream aos = new MockExceptionOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.publish(new LogRecord(Level.SEVERE,
+				"testClose_SufficientPrivilege_Exception msg"));
+		h.flush();
+		h.close();
+	}
 
-    /*
-     * Test close() when having sufficient privilege, and no record has been
-     * written to the output stream.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() method when having sufficient privilege, and no record has been written to the output stream.",
-        method = "close",
-        args = {}
-    )
-    public void testClose_SufficientPrivilege_DirectClose() {
-        ByteArrayOutputStream aos = new MockOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.close();
-        assertEquals("close", CallVerificationStack.getInstance()
-                .getCurrentSourceMethod());
-        assertNull(CallVerificationStack.getInstance().pop());
-        assertEquals("flush", CallVerificationStack.getInstance()
-                .getCurrentSourceMethod());
-        CallVerificationStack.getInstance().clear();
-        assertEquals("MockFormatter_HeadMockFormatter_Tail", aos.toString());
-    }
+	/*
+	 * Test close() when having sufficient privilege, and no record has been
+	 * written to the output stream.
+	 */
+	public void testClose_SufficientPrivilege_DirectClose() {
+		ByteArrayOutputStream aos = new MockOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.close();
+		assertEquals("close", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		assertNull(CallVerificationStack.getInstance().pop());
+		assertEquals("flush", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		CallVerificationStack.getInstance().clear();
+		assertEquals("MockFormatter_HeadMockFormatter_Tail", aos.toString()
+				);
+	}
 
-    /*
-     * Test close() when having insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies SecurityException.",
-        method = "close",
-        args = {}
-    )
-     public void testClose_InsufficientPrivilege() {          
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new MockFormatter());
+	/*
+	 * Test close() when having insufficient privilege.
+	 */
+	public void testClose_InsufficientPrivilege() {
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		try {
+			StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+					new MockFormatter());
+			h.close();
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+			// expected
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        try {
-            h.close();
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+	/*
+	 * Test close() when having no output stream.
+	 */
+	public void testClose_NoOutputStream() {
+		StreamHandler h = new StreamHandler();
+		h.close();
+	}
 
-    /*
-     * Test close() when having no output stream.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies close() method when having no output stream.",
-        method = "close",
-        args = {}
-    )
-    public void testClose_NoOutputStream() {
-        StreamHandler h = new StreamHandler();
-        h.close();
-    }
+	/*
+	 * Test flush().
+	 */
+	public void testFlush_Normal() {
+		ByteArrayOutputStream aos = new MockOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.flush();
+		assertEquals("flush", CallVerificationStack.getInstance()
+				.getCurrentSourceMethod());
+		assertNull(CallVerificationStack.getInstance().pop());
+		CallVerificationStack.getInstance().clear();
+	}
 
-    /*
-     * Test flush().
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies flush() method.",
-        method = "flush",
-        args = {}
-    )
-    public void testFlush_Normal() {
-        ByteArrayOutputStream aos = new MockOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.flush();
-        assertEquals("flush", CallVerificationStack.getInstance().getCurrentSourceMethod());
-        assertNull(CallVerificationStack.getInstance().pop());
-        CallVerificationStack.getInstance().clear();
-    }
+	/*
+	 * Test flush() when having no output stream.
+	 */
+	public void testFlush_NoOutputStream() {
+		StreamHandler h = new StreamHandler();
+		h.flush();
+	}
 
-    /*
-     * Test flush() when having no output stream.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies flush() when having no output stream.",
-        method = "flush",
-        args = {}
-    )
-    public void testFlush_NoOutputStream() {
-        StreamHandler h = new StreamHandler();
-        h.flush();
-    }
+	/*
+	 * Test isLoggable(), use no filter, having output stream
+	 */
+	public void testIsLoggable_NoOutputStream() {
+		StreamHandler h = new StreamHandler();
+		LogRecord r = new LogRecord(Level.INFO, null);
+		assertFalse(h.isLoggable(r));
 
-    /*
-     * Test isLoggable(), use no filter, having no output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies isLoggable(), use no filter, having no output stream.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_NoOutputStream() {
-        StreamHandler h = new StreamHandler();
-        LogRecord r = new LogRecord(Level.INFO, null);
-        assertFalse(h.isLoggable(r));
+		h.setLevel(Level.WARNING);
+		assertFalse(h.isLoggable(r));
 
-        h.setLevel(Level.WARNING);
-        assertFalse(h.isLoggable(r));
+		h.setLevel(Level.CONFIG);
+		assertFalse(h.isLoggable(r));
 
-        h.setLevel(Level.CONFIG);
-        assertFalse(h.isLoggable(r));
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		assertFalse(h.isLoggable(r));
+	}
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        assertFalse(h.isLoggable(r));
-    }
+	/*
+	 * Test isLoggable(), use no filter, having output stream
+	 */
+	public void testIsLoggable_NoFilter() {
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new SimpleFormatter());
+		LogRecord r = new LogRecord(Level.INFO, null);
+		assertTrue(h.isLoggable(r));
 
-    /*
-     * Test isLoggable(), use no filter, having output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies isLoggable(), use no filter, having output stream.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_NoFilter() {
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new SimpleFormatter());
-        LogRecord r = new LogRecord(Level.INFO, null);
-        assertTrue(h.isLoggable(r));
+		h.setLevel(Level.WARNING);
+		assertFalse(h.isLoggable(r));
 
-        h.setLevel(Level.WARNING);
-        assertFalse(h.isLoggable(r));
+		h.setLevel(Level.CONFIG);
+		assertTrue(h.isLoggable(r));
 
-        h.setLevel(Level.CONFIG);
-        assertTrue(h.isLoggable(r));
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		assertFalse(h.isLoggable(r));
+	}
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        assertFalse(h.isLoggable(r));
-    }
+	/*
+	 * Test isLoggable(), use a filter, having output stream
+	 */
+	public void testIsLoggable_WithFilter() {
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new SimpleFormatter());
+		LogRecord r = new LogRecord(Level.INFO, null);
+		h.setFilter(new MockFilter());
+		assertFalse(h.isLoggable(r));
+		assertSame(r, CallVerificationStack.getInstance().pop());
 
-    /*
-     * Test isLoggable(), use a filter, having output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies isLoggable(), use a filter, having output stream.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_WithFilter() {
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new SimpleFormatter());
-        LogRecord r = new LogRecord(Level.INFO, null);
-        h.setFilter(new MockFilter());
-        assertFalse(h.isLoggable(r));
-        assertSame(r, CallVerificationStack.getInstance().pop());
+		h.setLevel(Level.CONFIG);
+		assertFalse(h.isLoggable(r));
+		assertSame(r, CallVerificationStack.getInstance().pop());
 
-        h.setLevel(Level.CONFIG);
-        assertFalse(h.isLoggable(r));
-        assertSame(r, CallVerificationStack.getInstance().pop());
+		h.setLevel(Level.WARNING);
+		assertFalse(h.isLoggable(r));
+		assertTrue(CallVerificationStack.getInstance().empty());
+	}
 
-        h.setLevel(Level.WARNING);
-        assertFalse(h.isLoggable(r)); //level to high, data will not reach the filter
-        assertTrue(CallVerificationStack.getInstance().empty());
-    }
+	/*
+	 * Test isLoggable(), null log record, having output stream. Handler should
+	 * call ErrorManager to handle exceptional case
+	 */
+	public void testIsLoggable_Null() {
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new SimpleFormatter());
+		assertFalse(h.isLoggable(null));
+	}
 
-    /*
-     * Test isLoggable(), null log record, having output stream. Handler should
-     * call ErrorManager to handle exceptional case
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies isLoggable(), null log record, having output stream. Handler should call ErrorManager to handle exceptional case.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_Null() {
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new SimpleFormatter());
-        assertFalse(h.isLoggable(null));
-    }
+	/*
+	 * Test isLoggable(), null log record, without output stream
+	 */
+	public void testIsLoggable_Null_NoOutputStream() {
+		StreamHandler h = new StreamHandler();
+		assertFalse(h.isLoggable(null));
+	}
 
-    /*
-     * Test isLoggable(), null log record, without output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies isLoggable(), null log record, without output stream.",
-        method = "isLoggable",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testIsLoggable_Null_NoOutputStream() {
-        StreamHandler h = new StreamHandler();
-        assertFalse(h.isLoggable(null));
-    }
+	/*
+	 * Test publish(), use no filter, having output stream, normal log record.
+	 */
+	public void testPublish_NoOutputStream() {
+		StreamHandler h = new StreamHandler();
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_NoOutputStream");
+		h.publish(r);
 
-    /*
-     * Test publish(), use no filter, having output stream, normal log record.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), use no filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_NoOutputStream() {
-        StreamHandler h = new StreamHandler(); 
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_NoOutputStream");
-        h.publish(r);
+		h.setLevel(Level.WARNING);
+		h.publish(r);
 
-        h.setLevel(Level.WARNING);
-        h.publish(r);
+		h.setLevel(Level.CONFIG);
+		h.publish(r);
 
-        h.setLevel(Level.CONFIG);
-        h.publish(r);
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		h.publish(r);
+	}
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        h.publish(r);
-    }
+	/*
+	 * Test publish(), use no filter, having output stream, normal log record.
+	 */
+	public void testPublish_NoFilter() {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
 
-    /*
-     * Test publish(), use no filter, having output stream, normal log record.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), use no filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_NoFilter() {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
+		h.setLevel(Level.INFO);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter", aos
+				.toString());
 
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFilter");
-        h.setLevel(Level.INFO);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter", aos
-                .toString());
+		h.setLevel(Level.WARNING);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter", aos
+				.toString());
 
-        h.setLevel(Level.WARNING);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter", aos
-                .toString());
+		h.setLevel(Level.CONFIG);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+				+ "testPublish_NoFilter", aos.toString());
 
-        h.setLevel(Level.CONFIG);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
-                + "testPublish_NoFilter", aos.toString());
-
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
-                + "testPublish_NoFilter", aos.toString());
-    }
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testPublish_NoFilter"
+				+ "testPublish_NoFilter", aos.toString());
+	}
 
-    /*
-     * Test publish(), use a filter, having output stream, normal log record.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), use a filter, having output stream, normal log record.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_WithFilter() {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.setFilter(new MockFilter());
+	/*
+	 * Test publish(), use a filter, having output stream, normal log record.
+	 */
+	public void testPublish_WithFilter() {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.setFilter(new MockFilter());
 
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
-        h.setLevel(Level.INFO);
-        h.publish(r);
-        h.flush();
-        assertEquals("", aos.toString());
-        assertSame(r, CallVerificationStack.getInstance().pop());
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_WithFilter");
+		h.setLevel(Level.INFO);
+		h.publish(r);
+		h.flush();
+		assertEquals("", aos.toString());
+		assertSame(r, CallVerificationStack.getInstance().pop());
 
-        h.setLevel(Level.WARNING);
-        h.publish(r);
-        h.flush();
-        assertEquals("", aos.toString());
-        assertTrue(CallVerificationStack.getInstance().empty());
+		h.setLevel(Level.WARNING);
+		h.publish(r);
+		h.flush();
+		assertEquals("", aos.toString());
+		assertTrue(CallVerificationStack.getInstance().empty());
 
-        h.setLevel(Level.CONFIG);
-        h.publish(r);
-        h.flush();
-        assertEquals("", aos.toString());
-        assertSame(r, CallVerificationStack.getInstance().pop());
+		h.setLevel(Level.CONFIG);
+		h.publish(r);
+		h.flush();
+		assertEquals("", aos.toString());
+		assertSame(r, CallVerificationStack.getInstance().pop());
 
-        r.setLevel(Level.OFF);
-        h.setLevel(Level.OFF);
-        h.publish(r);
-        h.flush();
-        assertEquals("", aos.toString());
-        assertTrue(CallVerificationStack.getInstance().empty());
-    }
+		r.setLevel(Level.OFF);
+		h.setLevel(Level.OFF);
+		h.publish(r);
+		h.flush();
+		assertEquals("", aos.toString());
+		assertTrue(CallVerificationStack.getInstance().empty());
+	}
 
-    /*
-     * Test publish(), null log record, handler should call ErrorManager to
-     * handle exceptional case
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), null log record, handler should call ErrorManager to handle exceptional case.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_Null() {
-        StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
-                new SimpleFormatter());
-        h.publish(null);
-    }
+	/*
+	 * Test publish(), null log record, handler should call ErrorManager to
+	 * handle exceptional case
+	 */
+	public void testPublish_Null() {
+		StreamHandler h = new StreamHandler(new ByteArrayOutputStream(),
+				new SimpleFormatter());
+		h.publish(null);
+	}
 
-    /*
-     * Test publish(), null log record, without output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), null log record, without output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_Null_NoOutputStream() {
-        StreamHandler h = new StreamHandler();
-        h.publish(null);
-        // regression test for Harmony-1279
-        MockFilter filter = new MockFilter();
-        h.setLevel(Level.FINER);
-        h.setFilter(filter);
-        LogRecord record = new LogRecord(Level.FINE, "abc");
-        h.publish(record);
-        // verify that filter.isLoggable is not called, because there's no
-        // associated output stream.
-        assertTrue(CallVerificationStack.getInstance().empty());
-    }
+	/*
+	 * Test publish(), null log record, without output stream
+	 */
+	public void testPublish_Null_NoOutputStream() {
+		StreamHandler h = new StreamHandler();
+		h.publish(null);
+		// regression test for Harmony-1279
+		MockFilter filter = new MockFilter();
+		h.setLevel(Level.FINER);
+		h.setFilter(filter);
+		LogRecord record = new LogRecord(Level.FINE, "abc");
+		h.publish(record);
+		// verify that filter.isLoggable is not called, because there's no
+		// associated output stream.
+		assertTrue(CallVerificationStack.getInstance().empty());
+	}
 
-    /*
-     * Test publish(), a log record with empty msg, having output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), a log record with empty msg, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_EmptyMsg() {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        LogRecord r = new LogRecord(Level.INFO, "");
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head", aos.toString());
-    }
+	/*
+	 * Test publish(), a log record with empty msg, having output stream
+	 */
+	public void testPublish_EmptyMsg() {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		LogRecord r = new LogRecord(Level.INFO, "");
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head", aos.toString());
+	}
 
-    /*
-     * Test publish(), a log record with null msg, having output stream
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), a log record with null msg, having output stream.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_NullMsg() {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        LogRecord r = new LogRecord(Level.INFO, null);
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_Head", aos.toString());
-    }
+	/*
+	 * Test publish(), a log record with null msg, having output stream
+	 */
+	public void testPublish_NullMsg() {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		LogRecord r = new LogRecord(Level.INFO, null);
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_Head", aos.toString());
+	}
 
-    /*
-     * Test publish(), after close.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies publish(), after close.",
-        method = "publish",
-        args = {java.util.logging.LogRecord.class}
-    )
-    public void testPublish_AfterClose() throws Exception {
-        Properties p = new Properties();
-        p.put("java.util.logging.StreamHandler.level", "FINE");
-        LogManager.getLogManager().readConfiguration(
-                EnvironmentHelper.PropertiesToInputStream(p));
+	/*
+	 * Test publish(), after close.
+	 */
+	public void testPublish_AfterClose() throws Exception {
+		Properties p = new Properties();
+		p.put("java.util.logging.StreamHandler.level", "FINE");
+		LogManager.getLogManager().readConfiguration(
+				EnvironmentHelper.PropertiesToInputStream(p));
 
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        assertSame(h.getLevel(), Level.FINE);
-        LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFormatter");
-        assertTrue(h.isLoggable(r));
-        h.close();
-        assertFalse(h.isLoggable(r));
-        h.publish(r);
-        h.flush();
-        assertEquals("MockFormatter_HeadMockFormatter_Tail", aos.toString());
-    }
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		assertSame(h.getLevel(), Level.FINE);
+		LogRecord r = new LogRecord(Level.INFO, "testPublish_NoFormatter");
+		assertTrue(h.isLoggable(r));
+		h.close();
+		assertFalse(h.isLoggable(r));
+		h.publish(r);
+		h.flush();
+		assertEquals("MockFormatter_HeadMockFormatter_Tail", aos.toString());
+	}
 
-    /*
-     * Test setEncoding() method with supported encoding.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setEncoding() method with supported encoding.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_Normal() throws Exception {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.setEncoding("iso-8859-1");
-        assertEquals("iso-8859-1", h.getEncoding());
-        LogRecord r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
-        h.publish(r);
-        h.flush();
+	/*
+	 * Test setEncoding() method with supported encoding.
+	 */
+	public void testSetEncoding_Normal() throws Exception {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.setEncoding("iso-8859-1");
+		assertEquals("iso-8859-1", h.getEncoding());
+		LogRecord r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
+		h.publish(r);
+		h.flush();
 
-        byte[] bytes = encoder.encode(
-                CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
-                .array();
-        assertTrue(Arrays.equals(bytes, aos.toByteArray()));
-    }
+		byte[] bytes = encoder.encode(
+				CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
+				.array();
+		assertTrue(Arrays.equals(bytes, aos.toByteArray()));
+	}
 
-    /*
-     * Test setEncoding() method with supported encoding, after a log record
-     * has been written.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setEncoding() method with supported encoding, after a log record has been written.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_AfterPublish() throws Exception {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        h.setEncoding("iso-8859-1");
-        assertEquals("iso-8859-1", h.getEncoding());
-        LogRecord r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
-        h.publish(r);
-        h.flush();
-        assertTrue(Arrays.equals(aos.toByteArray(), encoder.encode(
-                CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
-                .array()));
+	/*
+	 * Test setEncoding() method with supported encoding, after a log record
+	 * has been written.
+	 */
+	public void testSetEncoding_AfterPublish() throws Exception {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		h.setEncoding("iso-8859-1");
+		assertEquals("iso-8859-1", h.getEncoding());
+		LogRecord r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
+		h.publish(r);
+		h.flush();
+		assertTrue(Arrays.equals(aos.toByteArray(), encoder.encode(
+				CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
+				.array()));
 
-        h.setEncoding("iso8859-1");
-        assertEquals("iso8859-1", h.getEncoding());
-        r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
-        h.publish(r);
-        h.flush();
-        assertFalse(Arrays.equals(aos.toByteArray(), encoder.encode(
-                CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"
-                        + "testSetEncoding_Normal2")).array()));
-        byte[] b0 = aos.toByteArray();
-        byte[] b1 = encoder.encode(
-                CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
-                .array();
-        byte[] b2 = encoder.encode(CharBuffer.wrap("\u6881\u884D\u8F69"))
-                .array();
-        byte[] b3 = new byte[b1.length + b2.length];
-        System.arraycopy(b1, 0, b3, 0, b1.length);
-        System.arraycopy(b2, 0, b3, b1.length, b2.length);
-        assertTrue(Arrays.equals(b0, b3));
-    }
+		h.setEncoding("iso8859-1");
+		assertEquals("iso8859-1", h.getEncoding());
+		r = new LogRecord(Level.INFO, "\u6881\u884D\u8F69");
+		h.publish(r);
+		h.flush();
+		assertFalse(Arrays.equals(aos.toByteArray(), encoder.encode(
+				CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"
+						+ "testSetEncoding_Normal2")).array()));
+		byte[] b0 = aos.toByteArray();
+		byte[] b1 = encoder.encode(
+				CharBuffer.wrap("MockFormatter_Head" + "\u6881\u884D\u8F69"))
+				.array();
+		byte[] b2 = encoder.encode(CharBuffer.wrap("\u6881\u884D\u8F69"))
+				.array();
+		byte[] b3 = new byte[b1.length + b2.length];
+		System.arraycopy(b1, 0, b3, 0, b1.length);
+		System.arraycopy(b2, 0, b3, b1.length, b2.length);
+		assertTrue(Arrays.equals(b0, b3));
+	}
 
-    /*
-     * Test setEncoding() methods with null.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setEncoding() methods with null.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_Null() throws Exception {
-        StreamHandler h = new StreamHandler();
-        h.setEncoding(null);
-        assertNull(h.getEncoding());
-    }
+	/*
+	 * Test setEncoding() methods with null.
+	 */
+	public void testSetEncoding_Null() throws Exception {
+		StreamHandler h = new StreamHandler();
+		h.setEncoding(null);
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test setEncoding() methods with unsupported encoding.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setEncoding() methods with unsupported encoding.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_Unsupported() {
-        StreamHandler h = new StreamHandler();
-        try {
-            h.setEncoding("impossible");
-            fail("Should throw UnsupportedEncodingException!");
-        } catch (UnsupportedEncodingException e) {
-            // expected
-        }
-        assertNull(h.getEncoding());
-    }
+	/*
+	 * Test setEncoding() methods with unsupported encoding.
+	 */
+	public void testSetEncoding_Unsupported() {
+		StreamHandler h = new StreamHandler();
+		try {
+			h.setEncoding("impossible");
+			fail("Should throw UnsupportedEncodingException!");
+		} catch (UnsupportedEncodingException e) {
+			// expected
+		}
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test setEncoding() with insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setEncoding() method with insufficient privilege.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_InsufficientPrivilege() throws Exception {
-        StreamHandler h = new StreamHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
-        // set a normal value
-        try {
-            h.setEncoding("iso-8859-1");
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        assertNull(h.getEncoding());
-        System.setSecurityManager(new MockSecurityManager());
-        // set an invalid value
-        try {
+	/*
+	 * Test setEncoding() with insufficient privilege.
+	 */
+	public void testSetEncoding_InsufficientPrivilege() throws Exception {
+		StreamHandler h = new StreamHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
+		// set a normal value
+		try {
+			h.setEncoding("iso-8859-1");
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+			// expected
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		assertNull(h.getEncoding());
+		System.setSecurityManager(new MockSecurityManager());
+		// set an invalid value
+		try {
 
-            h.setEncoding("impossible");
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-        assertNull(h.getEncoding());
-    }
+			h.setEncoding("impossible");
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+			// expected
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+		assertNull(h.getEncoding());
+	}
 
-    /*
-     * Test setEncoding() methods will flush a stream before setting.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies that setEncoding() method will flush a stream before setting.",
-        method = "setEncoding",
-        args = {java.lang.String.class}
-    )
-    public void testSetEncoding_FlushBeforeSetting() throws Exception {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        StreamHandler h = new StreamHandler(aos, new MockFormatter());
-        LogRecord r = new LogRecord(Level.INFO, "abcd");
-        h.publish(r);
-        assertFalse(aos.toString().indexOf("abcd") > 0);
-        h.setEncoding("iso-8859-1");
-        assertTrue(aos.toString().indexOf("abcd") > 0);
-    }
+	/*
+	 * Test setEncoding() methods will flush a stream before setting.
+	 */
+	public void testSetEncoding_FlushBeforeSetting() throws Exception {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		StreamHandler h = new StreamHandler(aos, new MockFormatter());
+		LogRecord r = new LogRecord(Level.INFO, "abcd");
+		h.publish(r);
+		assertFalse(aos.toString().indexOf("abcd") > 0);
+		h.setEncoding("iso-8859-1");
+		assertTrue(aos.toString().indexOf("abcd") > 0);
+	}
 
-    /*
-     * Test setOutputStream() with null.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setOutputStream() method with null.",
-        method = "setOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void testSetOutputStream_null() {
-        MockStreamHandler h = new MockStreamHandler(
-                new ByteArrayOutputStream(), new SimpleFormatter());
-        try {
-            h.setOutputStream(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
+	/*
+	 * Test setOutputStream() with null.
+	 */
+	public void testSetOutputStream_null() {
+		MockStreamHandler h = new MockStreamHandler(
+				new ByteArrayOutputStream(), new SimpleFormatter());
+		try {
+			h.setOutputStream(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
 
-    /*
-     * Test setOutputStream() under normal condition.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setOutputStream() method under normal condition.",
-        method = "setOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void testSetOutputStream_Normal() {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        MockStreamHandler h = new MockStreamHandler(aos, new MockFormatter());
+	/*
+	 * Test setOutputStream() under normal condition.
+	 */
+	public void testSetOutputStream_Normal() {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		MockStreamHandler h = new MockStreamHandler(aos, new MockFormatter());
 
-        LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
-        h.publish(r);
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", aos
-                .toString());
+		LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
+		h.publish(r);
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", aos
+				.toString());
 
-        ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
-        h.setOutputStream(aos2);
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
-                + "MockFormatter_Tail", aos.toString());
-        r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
-        h.publish(r);
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", aos2
-                .toString());
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
-                + "MockFormatter_Tail", aos.toString());
-    }
+		ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
+		h.setOutputStream(aos2);
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+				+ "MockFormatter_Tail", aos.toString());
+		r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
+		h.publish(r);
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", aos2
+				.toString());
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+				+ "MockFormatter_Tail", aos.toString());
+	}
 
-    /*
-     * Test setOutputStream() after close.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setOutputStream() method after close.",
-        method = "setOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void testSetOutputStream_AfterClose() {
-        ByteArrayOutputStream aos = new ByteArrayOutputStream();
-        MockStreamHandler h = new MockStreamHandler(aos, new MockFormatter());
+	/*
+	 * Test setOutputStream() after close.
+	 */
+	public void testSetOutputStream_AfterClose() {
+		ByteArrayOutputStream aos = new ByteArrayOutputStream();
+		MockStreamHandler h = new MockStreamHandler(aos, new MockFormatter());
 
-        LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
-        h.publish(r);
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", aos
-                .toString());
-        h.close();
+		LogRecord r = new LogRecord(Level.INFO, "testSetOutputStream_Normal");
+		h.publish(r);
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal", aos
+				.toString());
+		h.close();
 
-        ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
-        h.setOutputStream(aos2);
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
-                + "MockFormatter_Tail", aos.toString());
-        r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
-        h.publish(r);
-        assertSame(r, CallVerificationStack.getInstance().pop());
-        assertTrue(CallVerificationStack.getInstance().empty());
-        h.flush();
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", aos2
-                .toString());
-        assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
-                + "MockFormatter_Tail", aos.toString());
-    }
+		ByteArrayOutputStream aos2 = new ByteArrayOutputStream();
+		h.setOutputStream(aos2);
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+				+ "MockFormatter_Tail", aos.toString());
+		r = new LogRecord(Level.INFO, "testSetOutputStream_Normal2");
+		h.publish(r);
+		assertSame(r, CallVerificationStack.getInstance().pop());
+		assertTrue(CallVerificationStack.getInstance().empty());
+		h.flush();
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal2", aos2
+				.toString());
+		assertEquals("MockFormatter_Head" + "testSetOutputStream_Normal"
+				+ "MockFormatter_Tail", aos.toString());
+	}
 
-    /*
-     * Test setOutputStream() when having insufficient privilege.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies setOutputStream() method when having insufficient privilege.",
-        method = "setOutputStream",
-        args = {java.io.OutputStream.class}
-    )
-    public void testSetOutputStream_InsufficientPrivilege() {
-        MockStreamHandler h = new MockStreamHandler();
-        SecurityManager oldMan = System.getSecurityManager();
-        System.setSecurityManager(new MockSecurityManager());
+	/*
+	 * Test setOutputStream() when having insufficient privilege.
+	 */
+	public void testSetOutputStream_InsufficientPrivilege() {
+		MockStreamHandler h = new MockStreamHandler();
+		SecurityManager oldMan = System.getSecurityManager();
+		System.setSecurityManager(new MockSecurityManager());
 
-        try {
-            h.setOutputStream(new ByteArrayOutputStream());
-            fail("Should throw SecurityException!");
-        } catch (SecurityException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
+		try {
+			h.setOutputStream(new ByteArrayOutputStream());
+			fail("Should throw SecurityException!");
+		} catch (SecurityException e) {
+			// expected
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
 
-        h = new MockStreamHandler();
-        System.setSecurityManager(new MockSecurityManager());
-        try {
-            h.setOutputStream(null);
-            fail("Should throw NullPointerException!");
-        } catch (NullPointerException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldMan);
-        }
-    }
+		h = new MockStreamHandler();
+		System.setSecurityManager(new MockSecurityManager());
+		try {
+			h.setOutputStream(null);
+			fail("Should throw NullPointerException!");
+		} catch (NullPointerException e) {
+			// expected
+		} finally {
+			System.setSecurityManager(oldMan);
+		}
+	}
 
-    /*
-     * A mock stream handler, expose setOutputStream.
-     */
-    public static class MockStreamHandler extends StreamHandler {
-        public MockStreamHandler() {
-            super();
-        }
+	/*
+	 * A mock stream handler, expose setOutputStream.
+	 */
+	public static class MockStreamHandler extends StreamHandler {
+		public MockStreamHandler() {
+			super();
+		}
 
-        public MockStreamHandler(OutputStream out, Formatter formatter) {
-            super(out, formatter);
-        }
+		public MockStreamHandler(OutputStream out, Formatter formatter) {
+			super(out, formatter);
+		}
 
-        public void setOutputStream(OutputStream out) {
-            super.setOutputStream(out);
-        }
+		public void setOutputStream(OutputStream out) {
+			super.setOutputStream(out);
+		}
 
-        public boolean isLoggable(LogRecord r) {
-            CallVerificationStack.getInstance().push(r);
-            return super.isLoggable(r);
-        }
-    }
+		public boolean isLoggable(LogRecord r) {
+			CallVerificationStack.getInstance().push(r);
+			return super.isLoggable(r);
+		}
+	}
 
-    /*
-     * A mock filter, always return false.
-     */
-    public static class MockFilter implements Filter {
+	/*
+	 * A mock filter, always return false.
+	 */
+	public static class MockFilter implements Filter {
 
-        public boolean isLoggable(LogRecord record) {
-            CallVerificationStack.getInstance().push(record);
-            return false;
-        }
-    }
+		public boolean isLoggable(LogRecord record) {
+			CallVerificationStack.getInstance().push(record);
+			return false;
+		}
+	}
 
-    /*
-     * A mock formatter.
-     */
-    public static class MockFormatter extends java.util.logging.Formatter {
-        public String format(LogRecord r) {
-            // System.out.println("formatter called...");
-            return super.formatMessage(r);
-        }
+	/*
+	 * A mock formatter.
+	 */
+	public static class MockFormatter extends java.util.logging.Formatter {
+		public String format(LogRecord r) {
+			// System.out.println("formatter called...");
+			return super.formatMessage(r);
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
-         */
-        public String getHead(Handler h) {
-            return "MockFormatter_Head";
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.util.logging.Formatter#getHead(java.util.logging.Handler)
+		 */
+		public String getHead(Handler h) {
+			return "MockFormatter_Head";
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
-         */
-        public String getTail(Handler h) {
-            return "MockFormatter_Tail";
-        }
-    }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.util.logging.Formatter#getTail(java.util.logging.Handler)
+		 */
+		public String getTail(Handler h) {
+			return "MockFormatter_Tail";
+		}
+	}
 
-    /*
-     * Another mock formatter.
-     */
-    public static class MockFormatter2 extends java.util.logging.Formatter {
-        public String format(LogRecord r) {
-            // System.out.println("formatter2 called...");
-            return r.getMessage();
-        }
-    }
+	/*
+	 * Another mock formatter.
+	 */
+	public static class MockFormatter2 extends java.util.logging.Formatter {
+		public String format(LogRecord r) {
+			// System.out.println("formatter2 called...");
+			return r.getMessage();
+		}
+	}
 
-    /*
-     * A mock output stream.
-     */
-    public static class MockOutputStream extends ByteArrayOutputStream {
+	/*
+	 * A mock output stream.
+	 */
+	public static class MockOutputStream extends ByteArrayOutputStream {
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#close()
-         */
-        public void close() throws IOException {
-            CallVerificationStack.getInstance().push(null);
-            super.close();
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#close()
+		 */
+		public void close() throws IOException {
+			CallVerificationStack.getInstance().push(null);
+			super.close();
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#flush()
-         */
-        public void flush() throws IOException {
-            CallVerificationStack.getInstance().push(null);
-            super.flush();
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#flush()
+		 */
+		public void flush() throws IOException {
+			CallVerificationStack.getInstance().push(null);
+			super.flush();
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#write(int)
-         */
-        public void write(int oneByte) {
-            super.write(oneByte);
-        }
-    }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#write(int)
+		 */
+		public void write(int oneByte) {
+			// TODO Auto-generated method stub
+			super.write(oneByte);
+		}
+	}
 
-    /*
-     * A mock output stream that always throw exception.
-     */
-    public static class MockExceptionOutputStream extends ByteArrayOutputStream {
+	/*
+	 * A mock output stream that always throw exception.
+	 */
+	public static class MockExceptionOutputStream extends ByteArrayOutputStream {
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#close()
-         */
-        public void close() throws IOException {
-            throw new IOException();
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#close()
+		 */
+		public void close() throws IOException {
+			throw new IOException();
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#flush()
-         */
-        public void flush() throws IOException {
-            throw new IOException();
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#flush()
+		 */
+		public void flush() throws IOException {
+			throw new IOException();
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#write(byte[], int, int)
-         */
-        public synchronized void write(byte[] buffer, int offset, int count) {
-            throw new NullPointerException();
-        }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#write(byte[], int, int)
+		 */
+		public synchronized void write(byte[] buffer, int offset, int count) {
+			throw new NullPointerException();
+		}
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see java.io.OutputStream#write(int)
-         */
-        public synchronized void write(int oneByte) {
-            throw new NullPointerException();
-        }
-    }
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.io.OutputStream#write(int)
+		 */
+		public synchronized void write(int oneByte) {
+			throw new NullPointerException();
+		}
+	}
 
-    /*
-     * Used to grant all permissions except logging control.
-     */
-    public static class MockSecurityManager extends SecurityManager {
+	/*
+	 * Used to grant all permissions except logging control.
+	 */
+	public static class MockSecurityManager extends SecurityManager {
 
-        public MockSecurityManager() {
-        }
+		public MockSecurityManager() {
+		}
 
-        public void checkPermission(Permission perm) {
-            // grant all permissions except logging control
-            if (perm instanceof LoggingPermission) {
-                throw new SecurityException();
-            }
-        }
+		public void checkPermission(Permission perm) {
+			// grant all permissions except logging control
+			if (perm instanceof LoggingPermission) {
+				throw new SecurityException();
+			}
+		}
 
-        public void checkPermission(Permission perm, Object context) {
-            // grant all permissions except logging control
-            if (perm instanceof LoggingPermission) {
-                throw new SecurityException();
-            }
-        }
-    }
+		public void checkPermission(Permission perm, Object context) {
+			// grant all permissions except logging control
+			if (perm instanceof LoggingPermission) {
+				throw new SecurityException();
+			}
+		}
+	}
 
 }
diff --git a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
index 90c93c9..175ffb5 100644
--- a/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
+++ b/logging/src/test/java/org/apache/harmony/logging/tests/java/util/logging/XMLFormatterTest.java
@@ -17,12 +17,6 @@
 
 package org.apache.harmony.logging.tests.java.util.logging;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 import java.io.UnsupportedEncodingException;
@@ -32,7 +26,6 @@
 import java.util.logging.LogRecord;
 import java.util.logging.XMLFormatter;
 
-@TestTargetClass(XMLFormatter.class)
 public class XMLFormatterTest extends TestCase {
 
     XMLFormatter formatter = null;
@@ -52,26 +45,6 @@
      * test for constructor public XMLFormatter()
      * 
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "XMLFormatter",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getHead",
-            args = {java.util.logging.Handler.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "getTail",
-            args = {java.util.logging.Handler.class}
-        )
-    })
     public void testXMLFormatter() throws SecurityException,
             UnsupportedEncodingException {
 
@@ -93,12 +66,6 @@
                 .getTail(handler).indexOf("/log>") > 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testLocalFormat() {
         // if set resource bundle, output will use localized message,
         // but put the original message into the key element
@@ -130,12 +97,6 @@
         assertTrue(result.indexOf("<key>") < 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testFullFormat() {
         lr.setSourceClassName("source class");
         lr.setSourceMethodName("source method");
@@ -168,12 +129,6 @@
         assertTrue(output.indexOf("<key>pattern</key>") > 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.logging.LogRecord.class}
-    )
     public void testFormat() {
         String output = formatter.format(lr);
         // System.out.println(output);
@@ -193,12 +148,6 @@
         assertTrue(output.indexOf("<key>") < 0);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getHead",
-        args = {java.util.logging.Handler.class}
-    )
     public void testGetHead() throws SecurityException,
             UnsupportedEncodingException {
         String result = formatter.getHead(handler);
@@ -230,12 +179,6 @@
     /*
      * test for method public String getTail(Handler h)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getTail",
-        args = {java.util.logging.Handler.class}
-    )
     public void testGetTail() {
         assertEquals(
                 "Tail string with null handler should be equal expected value",
@@ -248,28 +191,7 @@
                 "</log>", formatter.getTail(handler).trim());
     }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "format",
-            args = {java.util.logging.LogRecord.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getTail",
-            args = {java.util.logging.Handler.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "XMLFormatter",
-            args = {}
-        )
-    })
-    @AndroidOnly("This test fails on RI. Output doesn't contain " +
-            "<message/>.")
+    // This test fails on RI. Output doesn't contain <message/>.
     public void testInvalidParameter() {
         formatter.getTail(null);
         try {
diff --git a/logging/src/test/java/tests/logging/AllTests.java b/logging/src/test/java/tests/logging/AllTests.java
index c6032df..aa0cb15 100644
--- a/logging/src/test/java/tests/logging/AllTests.java
+++ b/logging/src/test/java/tests/logging/AllTests.java
@@ -24,16 +24,11 @@
  * Test suite that includes all tests for the Logging project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Logging test suites");
+        TestSuite suite = new TestSuite("All Logging test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.logging.tests.java.util.logging.AllTests.suite());
         // $JUnit-END$
         return suite;
     }
-}
\ No newline at end of file
+}
diff --git a/luni-kernel/src/main/java/java/lang/Class.java b/luni-kernel/src/main/java/java/lang/Class.java
index 101d593..35e47bc 100644
--- a/luni-kernel/src/main/java/java/lang/Class.java
+++ b/luni-kernel/src/main/java/java/lang/Class.java
@@ -117,21 +117,21 @@
  * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li>
  * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li>
  * </ul>
- * 
- * @since Android 1.0
  */
 public final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type {
 
     private static final long serialVersionUID = 3206093459760846163L;
 
-    // TODO How is this field being initialized? What's it being used for?
-    private ProtectionDomain pd;
+    /**
+     * This field is initialized by dalvikvm when the class is loaded.
+     */
+    private transient ProtectionDomain pd;
 
     /**
      * null-ok; cache of reflective information, wrapped in a soft
      * reference
      */
-    private volatile SoftReference<ClassCache<T>> cacheRef;
+    private transient volatile SoftReference<ClassCache<T>> cacheRef;
     
     private Class() {
         // Prevent this class to be instantiated, instance
@@ -1423,8 +1423,7 @@
      *             if a security manager exists and it does not allow creating
      *             new instances.
      */
-    public T newInstance() throws IllegalAccessException,
-            InstantiationException {
+    public T newInstance() throws InstantiationException, IllegalAccessException {
         checkPublicMemberAccess();        
         return newInstanceImpl();
     }
diff --git a/luni-kernel/src/main/java/java/lang/ClassLoader.java b/luni-kernel/src/main/java/java/lang/ClassLoader.java
index 3c2e911..aae807e 100644
--- a/luni-kernel/src/main/java/java/lang/ClassLoader.java
+++ b/luni-kernel/src/main/java/java/lang/ClassLoader.java
@@ -60,8 +60,6 @@
  * applications may implement subclasses of {@code ClassLoader} to provide
  * special ways for loading classes.
  * </p>
- * 
- * @since Android 1.0
  * @see Class
  */
 public abstract class ClassLoader {
@@ -135,7 +133,6 @@
      * @throws SecurityException
      *             if a security manager exists and it does not allow access to
      *             the system class loader.
-     * @since Android 1.0
      */
     public static ClassLoader getSystemClassLoader() {
         SecurityManager smgr = System.getSecurityManager();
@@ -158,7 +155,6 @@
      * @param resName
      *            the name of the resource to find.
      * @see Class#getResource
-     * @since Android 1.0
      */
     public static URL getSystemResource(String resName) {
         return SystemClassLoader.loader.getResource(resName);
@@ -175,7 +171,6 @@
      *            the name of the resource to find.
      * @throws IOException
      *             if an I/O error occurs.
-     * @since Android 1.0
      */
     public static Enumeration<URL> getSystemResources(String resName) throws IOException {
         return SystemClassLoader.loader.getResources(resName);
@@ -191,7 +186,6 @@
      * @param resName
      *            the name of the resource to find.
      * @see Class#getResourceAsStream
-     * @since Android 1.0
      */
     public static InputStream getSystemResourceAsStream(String resName) {
         return SystemClassLoader.loader.getResourceAsStream(resName);
@@ -204,7 +198,6 @@
      * @throws SecurityException
      *             if a security manager exists and it does not allow the
      *             creation of a new {@code ClassLoader}.
-     * @since Android 1.0
      */
     protected ClassLoader() {
         this(getSystemClassLoader(), false);
@@ -220,7 +213,6 @@
      * @throws SecurityException
      *             if a security manager exists and it does not allow the
      *             creation of new a new {@code ClassLoader}.
-     * @since Android 1.0
      */
     protected ClassLoader(ClassLoader parentLoader) {
         this(parentLoader, false);
@@ -262,7 +254,6 @@
      *             {@code offset + length} is greater than the length of
      *             {@code classRep}.
      * @deprecated Use {@link #defineClass(String, byte[], int, int)}
-     * @since Android 1.0
      */
     @Deprecated
     protected final Class<?> defineClass(byte[] classRep, int offset, int length)
@@ -292,7 +283,6 @@
      *             if {@code offset < 0}, {@code length < 0} or if
      *             {@code offset + length} is greater than the length of
      *             {@code classRep}.
-     * @since Android 1.0
      */
     protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length)
             throws ClassFormatError {
@@ -330,7 +320,6 @@
      * @throws NoClassDefFoundError
      *             if {@code className} is not equal to the name of the class
      *             contained in {@code classRep}.
-     * @since Android 1.0
      */
     protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length,
             ProtectionDomain protectionDomain) throws java.lang.ClassFormatError {
@@ -359,7 +348,6 @@
      * @throws NoClassDefFoundError
      *             if {@code className} is not equal to the name of the class
      *             contained in {@code b}.
-     * @since Android 1.0
      */
     protected final Class<?> defineClass(String name, ByteBuffer b,
             ProtectionDomain protectionDomain) throws ClassFormatError {
@@ -379,7 +367,6 @@
      * @return the {@code Class} object that is found.
      * @throws ClassNotFoundException
      *             if the class cannot be found.
-     * @since Android 1.0
      */
     protected Class<?> findClass(String className) throws ClassNotFoundException {
         throw new ClassNotFoundException(className);
@@ -393,7 +380,6 @@
      *            the name of the class to look for.
      * @return the {@code Class} object or {@code null} if the requested class
      *         has not been loaded.
-     * @since Android 1.0
      */
     protected final Class<?> findLoadedClass(String className) {
         ClassLoader loader;
@@ -413,7 +399,6 @@
      * @return the {@code Class} object with the requested {@code className}.
      * @throws ClassNotFoundException
      *             if the class can not be found.
-     * @since Android 1.0
      */
     protected final Class<?> findSystemClass(String className) throws ClassNotFoundException {
         return Class.forName(className, false, getSystemClassLoader());
@@ -426,7 +411,6 @@
      * @throws SecurityException
      *             if a security manager exists and it does not allow to
      *             retrieve the parent class loader.
-     * @since Android 1.0
      */
     public final ClassLoader getParent() {
         SecurityManager smgr = System.getSecurityManager();
@@ -449,7 +433,6 @@
      *         if either the resource can not be found or a security manager
      *         does not allow to access the resource.
      * @see Class#getResource
-     * @since Android 1.0
      */
     public URL getResource(String resName) {
         URL resource = null;
@@ -475,7 +458,6 @@
      *            the name of the resource to find.
      * @throws IOException
      *             if an I/O error occurs.
-     * @since Android 1.0
      */
     @SuppressWarnings("unchecked")
     public Enumeration<URL> getResources(String resName) throws IOException {
@@ -497,7 +479,6 @@
      * @param resName
      *            the name of the resource to find.
      * @see Class#getResourceAsStream
-     * @since Android 1.0
      */
     public InputStream getResourceAsStream(String resName) {
         try {
@@ -526,7 +507,6 @@
      *            the name of the class to look for.
      * @throws ClassNotFoundException
      *             if the class can not be found.
-     * @since Android 1.0
      */
     public Class<?> loadClass(String className) throws ClassNotFoundException {
         return loadClass(className, false);
@@ -557,7 +537,6 @@
      *            classes are not resolved.
      * @throws ClassNotFoundException
      *             if the class can not be found.
-     * @since Android 1.0
      */
     protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
         Class<?> clazz = findLoadedClass(className);
@@ -587,7 +566,6 @@
      * 
      * @param clazz
      *            the class to link.
-     * @since Android 1.0
      */
     protected final void resolveClass(Class<?> clazz) {
         // no-op, doesn't make sense on android.
@@ -650,7 +628,6 @@
      * @param resName
      *            the name of the resource to find.
      * @return the {@code URL} object for the requested resource.
-     * @since Android 1.0
      */
     protected URL findResource(String resName) {
         return null;
@@ -666,7 +643,6 @@
      * @return an enumeration of {@code URL} objects for the requested resource.
      * @throws IOException
      *             if an I/O error occurs.
-     * @since Android 1.0
      */
     @SuppressWarnings( {
             "unchecked", "unused"
@@ -687,7 +663,6 @@
      * @param libName
      *            the name of the library to find.
      * @return the absolute path of the library.
-     * @since Android 1.0
      */
     protected String findLibrary(String libName) {
         return null;
@@ -701,7 +676,6 @@
      *            the name of the package to find.
      * @return the package with the requested name; {@code null} if the package
      *         can not be found.
-     * @since Android 1.0
      */
     protected Package getPackage(String name) {
         synchronized (packages) {
@@ -720,7 +694,6 @@
      *            the name of the package to find.
      * @return the package with the requested name; {@code null} if the package
      *         can not be found.
-     * @since Android 1.0
      */
     static Package getPackage(ClassLoader loader, String name) {
         return loader.getPackage(name);
@@ -730,7 +703,6 @@
      * Returns all the packages known to this class loader.
      * 
      * @return an array with all packages known to this class loader.
-     * @since Android 1.0
      */
     protected Package[] getPackages() {
         synchronized (packages) {
@@ -766,7 +738,6 @@
      * @return the {@code Package} object that has been created.
      * @throws IllegalArgumentException
      *             if a package with the specified name already exists.
-     * @since Android 1.0
      */
     protected Package definePackage(String name, String specTitle, String specVersion,
             String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)
@@ -793,7 +764,6 @@
      * @param c
      *            the {@code Class} object for which to get the signers.
      * @return signers the signers of {@code c}.
-     * @since Android 1.0
      */
     final Object[] getSigners(Class<?> c) {
         return null;
@@ -807,7 +777,6 @@
      *            the {@code Class} object for which to set the signers.
      * @param signers
      *            the signers for {@code c}.
-     * @since Android 1.0
      */
     protected final void setSigners(Class<?> c, Object[] signers) {
         return;
@@ -910,7 +879,6 @@
      *            the name of the class for which to set the assertion status.
      * @param enable
      *            the new assertion status.
-     * @since Android 1.0
      */
     public void setClassAssertionStatus(String cname, boolean enable) {
         return;
@@ -927,7 +895,6 @@
      *            the name of the package for which to set the assertion status.
      * @param enable
      *            the new assertion status.
-     * @since Android 1.0
      */    
     public void setPackageAssertionStatus(String pname, boolean enable) {
         return;
@@ -942,7 +909,6 @@
      * 
      * @param enable
      *            the new assertion status.
-     * @since Android 1.0
      */
     public void setDefaultAssertionStatus(boolean enable) {
         return;
@@ -955,8 +921,6 @@
      * <strong>Note:</strong> This method does nothing in the Android reference
      * implementation.
      * </p>
-     * 
-     * @since Android 1.0
      */
     public void clearAssertionStatus() {
         return;
@@ -1040,7 +1004,7 @@
 
     static BootClassLoader instance;
 
-    public static BootClassLoader getInstance() {
+    public static synchronized BootClassLoader getInstance() {
         if (instance == null) {
             instance = new BootClassLoader();
         }
diff --git a/luni-kernel/src/main/java/java/lang/Compiler.java b/luni-kernel/src/main/java/java/lang/Compiler.java
index cf41f06..88251e7 100644
--- a/luni-kernel/src/main/java/java/lang/Compiler.java
+++ b/luni-kernel/src/main/java/java/lang/Compiler.java
@@ -20,11 +20,7 @@
 /**
  * Placeholder class for environments which explicitly manage the action of a
  * <em>Just In Time (JIT)</em> compiler. This class is usually implemented by
- * the virtual machine vendor. The Android reference implementation does not
- * (yet) contain such a JIT compiler, though other implementations may choose to
- * provide one.
- * 
- * @since Android 1.0
+ * the virtual machine vendor.
  */
 public final class Compiler {
 
@@ -38,12 +34,12 @@
     /**
      * Executes an operation according to the specified command object. This
      * method is the low-level interface to the JIT compiler. It may return any
-     * object or {@code null} if no JIT compiler is available.
+     * object or {@code null} if no JIT compiler is available. Returns null
+     * on Android, whether or not the system has a JIT.
      * 
      * @param cmd
      *            the command object for the JIT compiler.
      * @return the result of executing command or {@code null}.
-     * @since Android 1.0
      */
     public static Object command(Object cmd) {
         return null;
@@ -51,14 +47,14 @@
 
     /**
      * Compiles the specified class using the JIT compiler and indicates if
-     * compilation has been successful.
+     * compilation has been successful. Does nothing and returns false on
+     * Android.
      * 
      * @param classToCompile
      *            java.lang.Class the class to JIT compile
      * @return {@code true} if the compilation has been successful;
      *         {@code false} if it has failed or if there is no JIT compiler
      *         available.
-     * @since Android 1.0
      */
     public static boolean compileClass(Class<?> classToCompile) {
         return false;
@@ -66,32 +62,28 @@
 
     /**
      * Compiles all classes whose name matches the specified name using the JIT
-     * compiler and indicates if compilation has been successful.
+     * compiler and indicates if compilation has been successful. Does nothing
+     * and returns false on Android.
      * 
      * @param nameRoot
      *            the string to match class names with.
      * @return {@code true} if the compilation has been successful;
      *         {@code false} if it has failed or if there is no JIT compiler
      *         available.
-     * @since Android 1.0
      */
     public static boolean compileClasses(String nameRoot) {
         return false;
     }
 
     /**
-     * Disables the JIT compiler.
-     * 
-     * @since Android 1.0
+     * Disables the JIT compiler. Does nothing on Android.
      */
     public static void disable() {
         return;
     }
 
     /**
-     * Enables the JIT compiler.
-     * 
-     * @since Android 1.0
+     * Enables the JIT compiler. Does nothing on Android.
      */
     public static void enable() {
         return;
diff --git a/luni-kernel/src/main/java/java/lang/Object.java b/luni-kernel/src/main/java/java/lang/Object.java
index 4fef609..bdb66b9 100644
--- a/luni-kernel/src/main/java/java/lang/Object.java
+++ b/luni-kernel/src/main/java/java/lang/Object.java
@@ -45,15 +45,11 @@
  * The {@link #wait()} and {@link #notify()} methods provide a foundation for
  * synchronization, acquiring and releasing an internal monitor associated with
  * each {@code Object}.
- * 
- * @since Android 1.0
  */
 public class Object {
 
     /**
      * Constructs a new instance of {@code Object}.
-     * 
-     * @since Android 1.0
      */
     public Object() {
     }
@@ -72,7 +68,6 @@
      * @throws CloneNotSupportedException
      *             if this object's class does not implement the {@code
      *             Cloneable} interface.
-     * @since Android 1.0
      */
     protected Object clone() throws CloneNotSupportedException {
         if (!(this instanceof Cloneable)) {
@@ -111,7 +106,6 @@
      * @return {@code true} if the specified object is equal to this {@code
      *         Object}; {@code false} otherwise.
      * @see #hashCode
-     * @since Android 1.0
      */
     public boolean equals(Object o) {
         return this == o;
@@ -142,16 +136,15 @@
      * @throws Throwable
      *             any exception which is raised during finalization; these are
      *             ignored by the virtual machine.
-     * @since Android 1.0
      */
     protected void finalize() throws Throwable {
     }
 
     /**
-     * Returns the unique instance of {@link Class} which represents this
+     * Returns the unique instance of {@link Class} that represents this
      * object's class. Note that {@code getClass()} is a special case in that it
      * actually returns {@code Class<? extends Foo>} where {@code Foo} is the
-     * erasure of the type of expression {@code getClass()} was called upon.
+     * erasure of the type of the expression {@code getClass()} was called upon.
      * <p>
      * As an example, the following code actually compiles, although one might
      * think it shouldn't:
@@ -162,7 +155,6 @@
      * </pre>
      * 
      * @return this object's {@code Class} instance.
-     * @since Android 1.0
      */
     public final native Class<? extends Object> getClass();
 
@@ -174,7 +166,6 @@
      * 
      * @return this object's hash code.
      * @see #equals
-     * @since Android 1.0
      */
     public native int hashCode();
 
@@ -203,7 +194,6 @@
      * @see #wait(long)
      * @see #wait(long,int)
      * @see java.lang.Thread
-     * @since Android 1.0
      */
     public final native void notify();
 
@@ -249,7 +239,6 @@
      * </pre>
      * 
      * @return a printable representation of this object.
-     * @since Android 1.0
      */
     public String toString() {
         return getClass().getName() + '@' + Integer.toHexString(hashCode());
@@ -282,7 +271,6 @@
      * @see #wait(long)
      * @see #wait(long,int)
      * @see java.lang.Thread
-     * @since Android 1.0
      */
     public final void wait() throws InterruptedException {
         wait(0 ,0);
@@ -320,7 +308,6 @@
      * @see #wait()
      * @see #wait(long,int)
      * @see java.lang.Thread
-     * @since Android 1.0
      */
     public final void wait(long millis) throws InterruptedException {
         wait(millis, 0);
@@ -362,7 +349,6 @@
      * @see #wait()
      * @see #wait(long,int)
      * @see java.lang.Thread
-     * @since Android 1.0
      */
     public final native void wait(long millis, int nanos) throws InterruptedException;
 }
diff --git a/luni-kernel/src/main/java/java/lang/Package.java b/luni-kernel/src/main/java/java/lang/Package.java
index 4d98959..9ad40b8 100644
--- a/luni-kernel/src/main/java/java/lang/Package.java
+++ b/luni-kernel/src/main/java/java/lang/Package.java
@@ -46,7 +46,6 @@
  * Packages are managed by class loaders. All classes loaded by the same loader
  * from the same package share a {@code Package} instance.
  * </p>
- * @since Android 1.0
  * 
  * @see java.lang.ClassLoader
  */
@@ -76,14 +75,13 @@
      *            the annotation type to look for.
      * @return an instance of {@link Annotation} or {@code null}.
      * @see java.lang.reflect.AnnotatedElement#getAnnotation(java.lang.Class)
-     * @since Android 1.0
      */
     @SuppressWarnings("unchecked")
-    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
         Annotation[] list = getAnnotations();
         for (int i = 0; i < list.length; i++) {
             if (annotationType.isInstance(list[i])) {
-                return (T)list[i];
+                return (A) list[i];
             }
         }
         
@@ -95,7 +93,6 @@
      * 
      * @return an array of {@link Annotation} instances, which may be empty.
      * @see java.lang.reflect.AnnotatedElement#getAnnotations()
-     * @since Android 1.0
      */
     public Annotation[] getAnnotations() {
         return getDeclaredAnnotations(this, true);
@@ -106,7 +103,6 @@
      * 
      * @return an array of {@link Annotation} instances, which may be empty.
      * @see java.lang.reflect.AnnotatedElement#getDeclaredAnnotations()
-     * @since Android 1.0
      */
     public Annotation[] getDeclaredAnnotations() {
         return getDeclaredAnnotations(this, false);
@@ -133,7 +129,6 @@
      * @return {@code true} if the annotation is present; {@code false}
      *         otherwise.
      * @see java.lang.reflect.AnnotatedElement#isAnnotationPresent(java.lang.Class)
-     * @since Android 1.0
      */
     public boolean isAnnotationPresent(
             Class<? extends Annotation> annotationType) {
@@ -145,7 +140,6 @@
      * if this is unknown. The format of this string is unspecified.
      * 
      * @return the implementation title, may be {@code null}.
-     * @since Android 1.0
      */
     public String getImplementationTitle() {
         return implTitle;
@@ -157,7 +151,6 @@
      * format of this string is unspecified.
      * 
      * @return the implementation vendor name, may be {@code null}.
-     * @since Android 1.0
      */
     public String getImplementationVendor() {
         return implVendor;
@@ -168,7 +161,6 @@
      * null} if this is unknown. The format of this string is unspecified.
      * 
      * @return the implementation version, may be {@code null}.
-     * @since Android 1.0
      */
     public String getImplementationVersion() {
         return implVersion;
@@ -179,7 +171,6 @@
      * example: "java.lang".
      * 
      * @return the name of this package.
-     * @since Android 1.0
      */
     public String getName() {
         return name;
@@ -193,7 +184,6 @@
      *            the name of the package to find.
      * @return the requested package, or {@code null}.
      * @see ClassLoader#getPackage(java.lang.String)
-     * @since Android 1.0
      */
     public static Package getPackage(String packageName) {
         ClassLoader classloader = VMStack.getCallingClassLoader();
@@ -205,7 +195,6 @@
      * 
      * @return all the packages known to the caller's class loader.
      * @see ClassLoader#getPackages
-     * @since Android 1.0
      */
     public static Package[] getPackages() {
         ClassLoader classloader = VMStack.getCallingClassLoader();
@@ -217,7 +206,6 @@
      * {@code null} if this is unknown.
      * 
      * @return the specification title, may be {@code null}.
-     * @since Android 1.0
      */
     public String getSpecificationTitle() {
         return specTitle;
@@ -229,7 +217,6 @@
      * unknown.
      * 
      * @return the specification vendor name, may be {@code null}.
-     * @since Android 1.0
      */
     public String getSpecificationVendor() {
         return specVendor;
@@ -241,7 +228,6 @@
      * non-negative integers separated by dots; for example: "1.2.3".
      * 
      * @return the specification version string, may be {@code null}.
-     * @since Android 1.0
      */
     public String getSpecificationVersion() {
         return specVersion;
@@ -264,7 +250,6 @@
      * @throws NumberFormatException
      *             if this package's version string or the one provided are not
      *             in the correct format.
-     * @since Android 1.0
      */
     public boolean isCompatibleWith(String version)
             throws NumberFormatException {
@@ -293,7 +278,6 @@
      * Indicates whether this package is sealed.
      * 
      * @return {@code true} if this package is sealed; {@code false} otherwise.
-     * @since Android 1.0
      */
     public boolean isSealed() {
         return sealBase != null;
@@ -307,7 +291,6 @@
      *            the URL to check.
      * @return {@code true} if this package is sealed with {@code url}; {@code
      *         false} otherwise
-     * @since Android 1.0
      */
     public boolean isSealed(URL url) {
         return sealBase != null && sealBase.sameFile(url);
diff --git a/luni-kernel/src/main/java/java/lang/Runtime.java b/luni-kernel/src/main/java/java/lang/Runtime.java
index 8560399..6d928f7 100644
--- a/luni-kernel/src/main/java/java/lang/Runtime.java
+++ b/luni-kernel/src/main/java/java/lang/Runtime.java
@@ -58,8 +58,6 @@
  * get a singleton instance by invoking {@link #getRuntime()}.
  * 
  * @see System
- * 
- * @since Android 1.0
  */
 public class Runtime {
     
@@ -135,7 +133,6 @@
      *             if the current {@code SecurityManager} disallows program
      *             execution.
      * @see SecurityManager#checkExec
-     * @since Android 1.0
      */
     public Process exec(String[] progArray) throws java.io.IOException {
         return exec(progArray, null, null);
@@ -161,7 +158,6 @@
      *             if the current {@code SecurityManager} disallows program
      *             execution.
      * @see SecurityManager#checkExec
-     * @since Android 1.0
      */    
     public Process exec(String[] progArray, String[] envp) throws java.io.IOException {
         return exec(progArray, envp, null);
@@ -189,7 +185,6 @@
      *             if the current {@code SecurityManager} disallows program
      *             execution.
      * @see SecurityManager#checkExec
-     * @since Android 1.0
      */
     public Process exec(String[] progArray, String[] envp, File directory) throws IOException {
         // BEGIN android-changed: push responsibility for argument checking into ProcessManager
@@ -212,7 +207,6 @@
      *             if the current {@code SecurityManager} disallows program
      *             execution.
      * @see SecurityManager#checkExec
-     * @since Android 1.0
      */
     public Process exec(String prog) throws java.io.IOException {
         return exec(prog, null, null);
@@ -236,7 +230,6 @@
      *             if the current {@code SecurityManager} disallows program
      *             execution.
      * @see SecurityManager#checkExec
-     * @since Android 1.0
      */
     public Process exec(String prog, String[] envp) throws java.io.IOException {
         return exec(prog, envp, null);
@@ -263,7 +256,6 @@
      *             if the current {@code SecurityManager} disallows program
      *             execution.
      * @see SecurityManager#checkExec
-     * @since Android 1.0
      */
     public Process exec(String prog, String[] envp, File directory) throws java.io.IOException {
         // Sanity checks
@@ -288,7 +280,7 @@
     /**
      * Causes the virtual machine to stop running and the program to exit. If
      * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a
-     * {@code true} argument, then all all objects will be properly
+     * {@code true} argument, then all objects will be properly
      * garbage-collected and finalized first.
      * 
      * @param code
@@ -298,7 +290,6 @@
      *             if the current {@code SecurityManager} does not allow the
      *             running thread to terminate the virtual machine.
      * @see SecurityManager#checkExit
-     * @since Android 1.0
      */
     public void exit(int code) {
         // Security checks
@@ -349,7 +340,6 @@
      * running program.
      * 
      * @return the approximate amount of free memory, measured in bytes.
-     * @since Android 1.0
      */
     public native long freeMemory();
 
@@ -357,8 +347,6 @@
      * Indicates to the virtual machine that it would be a good time to run the
      * garbage collector. Note that this is a hint only. There is no guarantee
      * that the garbage collector will actually be run.
-     * 
-     * @since Android 1.0
      */
     public native void gc();
 
@@ -366,7 +354,6 @@
      * Returns the single {@code Runtime} instance.
      * 
      * @return the {@code Runtime} object for the current application.
-     * @since Android 1.0
      */
     public static Runtime getRuntime() {
         return mRuntime;
@@ -386,7 +373,6 @@
      *             if the current {@code SecurityManager} does not allow to load
      *             the library.
      * @see SecurityManager#checkLink
-     * @since Android 1.0
      */
     public void load(String pathName) {
         // Security checks
@@ -424,7 +410,6 @@
      *             if the current {@code SecurityManager} does not allow to load
      *             the library.
      * @see SecurityManager#checkLink
-     * @since Android 1.0
      */
     public void loadLibrary(String libName) {
         // Security checks
@@ -479,7 +464,6 @@
      * Provides a hint to the virtual machine that it would be useful to attempt
      * to perform any outstanding object finalizations.
      * 
-     * @since Android 1.0
      */
     public void runFinalization() {
         runFinalization(false);
@@ -495,7 +479,6 @@
      *            {@code true} to enable finalization on exit, {@code false} to
      *            disable it.
      * @deprecated This method is unsafe.
-     * @since Android 1.0
      */
     @Deprecated
     public static void runFinalizersOnExit(boolean run) {
@@ -511,7 +494,6 @@
      * program.
      * 
      * @return the total amount of memory, measured in bytes.
-     * @since Android 1.0
      */
     public native long totalMemory();
 
@@ -522,7 +504,6 @@
      * @param enable
      *            {@code true} to switch tracing on, {@code false} to switch it
      *            off.
-     * @since Android 1.0
      */
     public void traceInstructions(boolean enable) {
         // TODO(Google) Provide some implementation for this.
@@ -535,7 +516,6 @@
      * @param enable
      *            {@code true} to switch tracing on, {@code false} to switch it
      *            off.
-     * @since Android 1.0
      */
     public void traceMethodCalls(boolean enable) {
         if (enable != tracingMethods) {
@@ -558,7 +538,6 @@
      *            the input stream to localize.
      * @return the localized input stream.
      * @deprecated Use {@link InputStreamReader}.
-     * @since Android 1.0
      */
     @Deprecated
     public InputStream getLocalizedInputStream(InputStream stream) {
@@ -578,7 +557,6 @@
      *            the output stream to localize.
      * @return the localized output stream.
      * @deprecated Use {@link OutputStreamWriter}.
-     * @since Android 1.0
      */    
     @Deprecated
     public OutputStream getLocalizedOutputStream(OutputStream stream) {
@@ -700,7 +678,6 @@
      * @see #addShutdownHook(Thread)
      * @see #removeShutdownHook(Thread)
      * @see #runFinalizersOnExit(boolean)
-     * @since Android 1.0
      */
     public void halt(int code) {
         // Security checks
@@ -718,7 +695,6 @@
      * Android reference implementation (currently) always returns 1.
      * 
      * @return the number of available processors, at least 1.
-     * @since Android 1.0
      */
     public int availableProcessors() {
         return 1;
@@ -730,7 +706,6 @@
      * 
      * @return the maximum amount of memory that the virtual machine will try to
      *         allocate, measured in bytes.
-     * @since Android 1.0
      */
     public native long maxMemory();
 
diff --git a/luni-kernel/src/main/java/java/lang/StackTraceElement.java b/luni-kernel/src/main/java/java/lang/StackTraceElement.java
index 5394ae9..88fe1ab 100644
--- a/luni-kernel/src/main/java/java/lang/StackTraceElement.java
+++ b/luni-kernel/src/main/java/java/lang/StackTraceElement.java
@@ -25,7 +25,6 @@
  * call stack at the time a {@code Throwable} gets thrown.
  * 
  * @see Throwable#getStackTrace()
- * @since Android 1.0
  */
 public final class StackTraceElement implements Serializable {
 
@@ -59,7 +58,6 @@
      *            method.
      * @throws NullPointerException
      *             if {@code cls} or {@code method} is {@code null}.
-     * @since Android 1.0
      */
     public StackTraceElement(String cls, String method, String file, int line) {
         super();
@@ -98,7 +96,6 @@
      * @return {@code true} if the specified object is equal to this
      *         {@code StackTraceElement}; {@code false} otherwise.
      * @see #hashCode
-     * @since Android 1.0
      */
     @Override
     public boolean equals(Object obj) {
@@ -143,7 +140,6 @@
      * {@code StackTraceElement}.
      * 
      * @return the fully qualified type name of the class
-     * @since Android 1.0
      */
     public String getClassName() {
         return (declaringClass == null) ? "<unknown class>" : declaringClass;
@@ -155,7 +151,6 @@
      * 
      * @return the name of the file, or {@code null} if this information is not
      *         available.
-     * @since Android 1.0
      */
     public String getFileName() {
         return fileName;
@@ -167,7 +162,6 @@
      * 
      * @return the line number, or a negative number if this information is not
      *         available.
-     * @since Android 1.0
      */
     public int getLineNumber() {
         return lineNumber;
@@ -179,7 +173,6 @@
      * 
      * @return the name of the method, or "<unknown method>" if this information
      *         is not available.
-     * @since Android 1.0
      */
     public String getMethodName() {
         return (methodName == null) ? "<unknown method>" : methodName;
@@ -205,7 +198,6 @@
      * 
      * @return {@code true} if the method in which this stack trace element is
      *         executing is a native method; {@code false} otherwise.
-     * @since Android 1.0
      */
     public boolean isNativeMethod() {
         // BEGIN android-changed
diff --git a/luni-kernel/src/main/java/java/lang/System.java b/luni-kernel/src/main/java/java/lang/System.java
index a238de7..095307a 100644
--- a/luni-kernel/src/main/java/java/lang/System.java
+++ b/luni-kernel/src/main/java/java/lang/System.java
@@ -32,6 +32,7 @@
 
 package java.lang;
 
+import java.io.Console;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -57,29 +58,21 @@
  * class itself can not be instantiated.
  * 
  * @see Runtime
- * 
- * @since Android 1.0
  */
 public final class System {
 
     /**
      * Default input stream.
-     * 
-     * @since Android 1.0
      */
     public static final InputStream in;
 
     /**
      * Default output stream.
-     * 
-     * @since Android 1.0
      */
     public static final PrintStream out;
 
     /**
      * Default error output stream.
-     * 
-     * @since Android 1.0
      */
     public static final PrintStream err;
 
@@ -112,7 +105,6 @@
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPermission()} method does not allow the change of the
      *             stream.
-     * @since Android 1.0
      */
     public static void setIn(InputStream newIn) {
         SecurityManager secMgr = System.getSecurityManager();
@@ -132,7 +124,6 @@
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPermission()} method does not allow the change of the
      *             stream.
-     * @since Android 1.0
      */
     public static void setOut(java.io.PrintStream newOut) {
         SecurityManager secMgr = System.getSecurityManager();
@@ -153,7 +144,6 @@
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPermission()} method does not allow the change of the
      *             stream.
-     * @since Android 1.0
      */
     public static void setErr(java.io.PrintStream newErr) {
         SecurityManager secMgr = System.getSecurityManager();
@@ -185,7 +175,6 @@
      * @param length
      *            the number of elements of the {@code array1} content they have
      *            to be copied.
-     * @since Android 1.0
      */
     public static native void arraycopy(Object src, int srcPos, Object dest,
             int destPos, int length);
@@ -197,7 +186,6 @@
      * the results.
      * 
      * @return the local system time in milliseconds.
-     * @since Android 1.0
      */
     public static native long currentTimeMillis();
 
@@ -208,14 +196,13 @@
      * very exact system time expression.
      * 
      * @return the current timestamp in nanoseconds.
-     * @since Android 1.0
      */
     public static native long nanoTime();
 
     /**
      * Causes the virtual machine to stop running and the program to exit. If
      * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a
-     * {@code true} argument, then all all objects will be properly
+     * {@code true} argument, then all objects will be properly
      * garbage-collected and finalized first.
      * 
      * @param code
@@ -224,7 +211,6 @@
      *             if the running thread has not enough permission to exit the
      *             virtual machine.
      * @see SecurityManager#checkExit
-     * @since Android 1.0
      */
     public static void exit(int code) {
         Runtime.getRuntime().exit(code);
@@ -234,8 +220,6 @@
      * Indicates to the virtual machine that it would be a good time to run the
      * garbage collector. Note that this is a hint only. There is no guarantee
      * that the garbage collector will actually be run.
-     * 
-     * @since Android 1.0
      */
     public static void gc() {
         Runtime.getRuntime().gc();
@@ -253,8 +237,6 @@
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPermission()} method does not allow the querying of
      *             single environment variables.
-     * 
-     * @since Android 1.0
      */
     public static String getenv(String name) {
         if (name == null) {
@@ -283,7 +265,6 @@
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPermission()} method does not allow the querying of
      *             all environment variables.
-     * @since Android 1.0
      */
     public static Map<String, String> getenv() {
         SecurityManager secMgr = System.getSecurityManager();
@@ -326,7 +307,6 @@
      *             if an I/O error occurred.
      * @see SelectorProvider
      * @see SelectorProvider#inheritedChannel()
-     * @since Android 1.0
      */
     public static Channel inheritedChannel() throws IOException {
         return SelectorProvider.provider().inheritedChannel();
@@ -341,7 +321,6 @@
      * @throws SecurityException
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPropertiesAccess()} method does not allow the operation.
-     * @since Android 1.0
      */
     public static Properties getProperties() {
         SecurityManager secMgr = System.getSecurityManager();
@@ -401,7 +380,6 @@
      * @throws SecurityException
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPropertyAccess()} method does not allow the operation.
-     * @since Android 1.0
      */
     public static String getProperty(String prop) {
         return getProperty(prop, null);
@@ -421,7 +399,6 @@
      * @throws SecurityException
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPropertyAccess()} method does not allow the operation.
-     * @since Android 1.0
      */
     public static String getProperty(String prop, String defaultValue) {
         if (prop.length() == 0) {
@@ -447,7 +424,6 @@
      * @throws SecurityException
      *             if a security manager exists and write access to the
      *             specified property is not allowed.
-     * @since Android 1.0
      */
     public static String setProperty(String prop, String value) {
         if (prop.length() == 0) {
@@ -473,7 +449,6 @@
      * @throws SecurityException
      *             if a security manager exists and write access to the
      *             specified property is not allowed.
-     * @since Android 1.0
      */
     public static String clearProperty(String key) {
         if (key == null) {
@@ -491,6 +466,17 @@
     }
 
     /**
+     * Returns the {@link java.io.Console} associated with this VM, or null.
+     * Not all VMs will have an associated console. A console is typically only
+     * available for programs run from the command line.
+     * @since 1.6
+     * @hide
+     */
+    public static Console console() {
+        return Console.getConsole();
+    }
+
+    /**
      * Returns null. Android does not use {@code SecurityManager}. This method
      * is only provided for source compatibility.
      * 
@@ -510,7 +496,6 @@
      *            the object to calculate the hash code.
      * @return the hash code for the given object.
      * @see java.lang.Object#hashCode
-     * @since Android 1.0
      */
     public static native int identityHashCode(Object anObject);
 
@@ -521,7 +506,6 @@
      *            the path of the file to be loaded.
      * @throws SecurityException
      *             if the library was not allowed to be loaded.
-     * @since Android 1.0
      */
     public static void load(String pathName) {
         SecurityManager smngr = System.getSecurityManager();
@@ -542,7 +526,6 @@
      *             if the library could not be loaded.
      * @throws SecurityException
      *             if the library was not allowed to be loaded.
-     * @since Android 1.0
      */
     public static void loadLibrary(String libName) {
         SecurityManager smngr = System.getSecurityManager();
@@ -554,9 +537,7 @@
 
     /**
      * Provides a hint to the virtual machine that it would be useful to attempt
-     * to perform any outstanding object finalizations.
-     * 
-     * @since Android 1.0
+     * to perform any outstanding object finalization.
      */
     public static void runFinalization() {
         Runtime.getRuntime().runFinalization();
@@ -570,7 +551,6 @@
      * @param flag
      *            the flag determines if finalization on exit is enabled.
      * @deprecated this method is unsafe.
-     * @since Android 1.0
      */
     @SuppressWarnings("deprecation")
     @Deprecated
@@ -586,7 +566,6 @@
      * @throws SecurityException
      *             if a {@link SecurityManager} is installed and its {@code
      *             checkPropertiesAccess()} method does not allow the operation.
-     * @since Android 1.0
      */
     public static void setProperties(Properties p) {
         SecurityManager secMgr = System.getSecurityManager();
@@ -624,7 +603,6 @@
      * @param userLibName
      *            the name of the library to look up.
      * @return the platform specific filename for the library.
-     * @since Android 1.0
      */
     public static native String mapLibraryName(String userLibName);
 
diff --git a/luni-kernel/src/main/java/java/lang/Thread.java b/luni-kernel/src/main/java/java/lang/Thread.java
index 4f9f988..625d718 100644
--- a/luni-kernel/src/main/java/java/lang/Thread.java
+++ b/luni-kernel/src/main/java/java/lang/Thread.java
@@ -69,7 +69,6 @@
  * @see java.lang.Object
  * @see java.lang.ThreadGroup
  * 
- * @since Android 1.0
  */
 public class Thread implements Runnable {
 
@@ -90,8 +89,6 @@
     /**
      * A representation of a thread's state. A given thread may only be in one
      * state at a time.
-     *
-     * @since Android 1.0
      */
     public enum State {
         /**
@@ -122,22 +119,16 @@
 
     /**
      * The maximum priority value allowed for a thread.
-     *
-     * @since Android 1.0
      */
     public final static int MAX_PRIORITY = 10;
 
     /**
      * The minimum priority value allowed for a thread.
-     *
-     * @since Android 1.0
      */
     public final static int MIN_PRIORITY = 1;
 
     /**
      * The normal (default) priority value assigned to threads.
-     *
-     * @since Android 1.0
      */
     public final static int NORM_PRIORITY = 5;
 
@@ -201,6 +192,9 @@
     /** the park state of the thread */
     private int parkState = ParkState.UNPARKED;
 
+    /** The synchronization object responsible for this thread parking. */
+    private Object parkBlocker;
+
     /**
      * Constructs a new {@code Thread} with no {@code Runnable} object and a
      * newly generated name. The new {@code Thread} will belong to the same
@@ -208,8 +202,6 @@
      *
      * @see java.lang.ThreadGroup
      * @see java.lang.Runnable
-     *
-     * @since Android 1.0
      */
     public Thread() {
         create(null, null, null, 0);
@@ -226,8 +218,6 @@
      *
      * @see java.lang.ThreadGroup
      * @see java.lang.Runnable
-     *
-     * @since Android 1.0
      */
     public Thread(Runnable runnable) {
         create(null, runnable, null, 0);
@@ -246,8 +236,6 @@
      *
      * @see java.lang.ThreadGroup
      * @see java.lang.Runnable
-     *
-     * @since Android 1.0
      */
     public Thread(Runnable runnable, String threadName) {
         if (threadName == null) {
@@ -268,7 +256,6 @@
      * @see java.lang.ThreadGroup
      * @see java.lang.Runnable
      *
-     * @since Android 1.0
      */
     public Thread(String threadName) {
         if (threadName == null) {
@@ -298,8 +285,6 @@
      * @see java.lang.Runnable
      * @see java.lang.SecurityException
      * @see java.lang.SecurityManager
-     *
-     * @since Android 1.0
      */
     public Thread(ThreadGroup group, Runnable runnable) {
         create(group, runnable, null, 0);
@@ -325,8 +310,6 @@
      * @see java.lang.Runnable
      * @see java.lang.SecurityException
      * @see java.lang.SecurityManager
-     *
-     * @since Android 1.0
      */
     public Thread(ThreadGroup group, Runnable runnable, String threadName) {
         if (threadName == null) {
@@ -353,8 +336,6 @@
      * @see java.lang.Runnable
      * @see java.lang.SecurityException
      * @see java.lang.SecurityManager
-     *
-     * @since Android 1.0
      */
     public Thread(ThreadGroup group, String threadName) {
         if (threadName == null) {
@@ -389,8 +370,6 @@
      * @see java.lang.Runnable
      * @see java.lang.SecurityException
      * @see java.lang.SecurityManager
-     *
-     * @since Android 1.0
      */
     public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
         if (threadName == null) {
@@ -530,8 +509,6 @@
      * Thread}'s group and its subgroups.
      *
      * @return the number of {@code Thread}s
-     *
-     * @since Android 1.0
      */
     public static int activeCount() {
         return currentThread().getThreadGroup().activeCount();
@@ -549,8 +526,6 @@
      *
      * @see java.lang.SecurityException
      * @see java.lang.SecurityManager
-     *
-     * @since Android 1.0
      */
     public final void checkAccess() {
         // Forwards the message to the SecurityManager (if there's one) passing
@@ -569,8 +544,6 @@
      * @deprecated The results of this call were never well defined. To make
      *             things worse, it would depend on whether the Thread was
      *             suspended or not, and suspend was deprecated too.
-     *
-     * @since Android 1.0
      */
     @Deprecated
     public int countStackFrames() {
@@ -581,8 +554,6 @@
      * Returns the Thread of the caller, that is, the current Thread.
      *
      * @return the current Thread.
-     *
-     * @since Android 1.0
      */
     public static Thread currentThread() {
         return VMThread.currentThread();
@@ -592,8 +563,6 @@
      * Destroys the receiver without any monitor cleanup.
      *
      * @deprecated Not implemented.
-     *
-     * @since Android 1.0
      */
     @Deprecated
     public void destroy() {
@@ -605,8 +574,6 @@
      * stack for this Thread.
      *
      * @see Throwable#printStackTrace()
-     *
-     * @since Android 1.0
      */
     public static void dumpStack() {
         new Throwable("stack dump").printStackTrace();
@@ -626,8 +593,6 @@
      *             {@link SecurityManager#checkAccess(Thread)}
      * @see java.lang.SecurityException
      * @see java.lang.SecurityManager
-     *
-     * @since Android 1.0
      */
     public static int enumerate(Thread[] threads) {
         Thread thread = Thread.currentThread();
@@ -646,8 +611,6 @@
      *             if the current SecurityManager fails the
      *             {@link SecurityManager#checkPermission(java.security.Permission)}
      *             call.
-     *
-     * @since Android 1.0
      */
     public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
         SecurityManager securityManager = System.getSecurityManager();
@@ -691,8 +654,6 @@
      *
      * @throws SecurityException
      *             if the aforementioned security check fails.
-     *
-     * @since Android 1.0
      */
     public ClassLoader getContextClassLoader() {
         // First, if the conditions
@@ -719,8 +680,6 @@
      *
      * @return an {@link UncaughtExceptionHandler} or <code>null</code> if
      *         none exists.
-     *
-     * @since Android 1.0
      */
     public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
         return defaultUncaughtHandler;
@@ -733,8 +692,6 @@
      * has been terminated.
      *
      * @return the thread's ID.
-     *
-     * @since Android 1.0
      */
     public long getId() {
         return id;
@@ -744,8 +701,6 @@
      * Returns the name of the Thread.
      *
      * @return the Thread's name
-     *
-     * @since Android 1.0
      */
     public final String getName() {
         return name;
@@ -756,8 +711,6 @@
      *
      * @return the Thread's priority
      * @see Thread#setPriority
-     *
-     * @since Android 1.0
      */
     public final int getPriority() {
         return priority;
@@ -776,8 +729,6 @@
      *             if the current SecurityManager fails the
      *             {@link SecurityManager#checkPermission(java.security.Permission)}
      *             call.
-     *
-     * @since Android 1.0
      */
     public StackTraceElement[] getStackTrace() {
         SecurityManager securityManager = System.getSecurityManager();
@@ -794,8 +745,6 @@
      * monitoring purposes.
      *
      * @return a {@link State} value.
-     *
-     * @since Android 1.0
      */
     public State getState() {
         // TODO This is ugly and should be implemented better.
@@ -819,8 +768,6 @@
      * Returns the ThreadGroup to which this Thread belongs.
      *
      * @return the Thread's ThreadGroup
-     *
-     * @since Android 1.0
      */
     public final ThreadGroup getThreadGroup() {
         // TODO This should actually be done at native termination.
@@ -837,8 +784,6 @@
      * then <code>null</code> is returned.
      *
      * @return an {@link UncaughtExceptionHandler} instance or {@code null}.
-     *
-     * @since Android 1.0
      */
     public UncaughtExceptionHandler getUncaughtExceptionHandler() {
         if (uncaughtHandler != null)
@@ -877,8 +822,6 @@
      * @see java.lang.SecurityManager
      * @see Thread#interrupted
      * @see Thread#isInterrupted
-     *
-     * @since Android 1.0
      */
     public void interrupt() {
         checkAccess();
@@ -903,8 +846,6 @@
      * @see Thread#currentThread
      * @see Thread#interrupt
      * @see Thread#isInterrupted
-     *
-     * @since Android 1.0
      */
     public static boolean interrupted() {
         return VMThread.interrupted();
@@ -916,10 +857,8 @@
      * the receiver hasn't been started yet or if it has already started and run
      * to completion and died.
      *
-     * @return a <code>boolean</code> indicating the lifeness of the Thread
+     * @return a <code>boolean</code> indicating the liveness of the Thread
      * @see Thread#start
-     *
-     * @since Android 1.0
      */
     public final boolean isAlive() {
         return (vmThread != null);
@@ -934,8 +873,6 @@
      *
      * @return a <code>boolean</code> indicating whether the Thread is a daemon
      * @see Thread#setDaemon
-     *
-     * @since Android 1.0
      */
     public final boolean isDaemon() {
         return daemon;
@@ -949,8 +886,6 @@
      * @return a <code>boolean</code> indicating the interrupt status
      * @see Thread#interrupt
      * @see Thread#interrupted
-     *
-     * @since Android 1.0
      */
     public boolean isInterrupted() {
         VMThread vmt = this.vmThread;
@@ -969,8 +904,6 @@
      *         the receiver while it was in the <code>join()</code> call
      * @see Object#notifyAll
      * @see java.lang.ThreadDeath
-     *
-     * @since Android 1.0
      */
     public final void join() throws InterruptedException {
         VMThread t = vmThread;
@@ -995,8 +928,6 @@
      *         the receiver while it was in the <code>join()</code> call
      * @see Object#notifyAll
      * @see java.lang.ThreadDeath
-     *
-     * @since Android 1.0
      */
     public final void join(long millis) throws InterruptedException {
         join(millis, 0);
@@ -1013,8 +944,6 @@
      *         the receiver while it was in the <code>join()</code> call
      * @see Object#notifyAll
      * @see java.lang.ThreadDeath
-     *
-     * @since Android 1.0
      */
     public final void join(long millis, int nanos) throws InterruptedException {
         if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) {
@@ -1070,8 +999,6 @@
      *             if <code>checkAccess()</code> fails with a SecurityException
      * @see Thread#suspend()
      * @deprecated Used with deprecated method {@link Thread#suspend}
-     *
-     * @since Android 1.0
      */
     @Deprecated
     public final void resume() {
@@ -1088,8 +1015,6 @@
      * holds. If no Runnable is set, does nothing.
      *
      * @see Thread#start
-     *
-     * @since Android 1.0
      */
     public void run() {
         if (target != null) {
@@ -1109,8 +1034,6 @@
      *         checkPermission call.
      * @see java.lang.ClassLoader
      * @see #getContextClassLoader()
-     *
-     * @since Android 1.0
      */
     public void setContextClassLoader(ClassLoader cl) {
         SecurityManager securityManager = System.getSecurityManager();
@@ -1130,8 +1053,6 @@
      * @throws SecurityException
      *             if <code>checkAccess()</code> fails with a SecurityException
      * @see Thread#isDaemon
-     *
-     * @since Android 1.0
      */
     public final void setDaemon(boolean isDaemon) {
         checkAccess();
@@ -1160,8 +1081,6 @@
      * @throws SecurityException
      *             if the current SecurityManager fails the checkPermission
      *             call.
-     *
-     * @since Android 1.0
      */
     public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
         SecurityManager securityManager = System.getSecurityManager();
@@ -1195,8 +1114,6 @@
      * @throws SecurityException if <code>checkAccess()</code> fails with a
      *         SecurityException
      * @see Thread#getName
-     *
-     * @since Android 1.0
      */
     public final void setName(String threadName) {
         if (threadName == null) {
@@ -1227,14 +1144,12 @@
      *             if the new priority is greater than Thread.MAX_PRIORITY or
      *             less than Thread.MIN_PRIORITY
      * @see Thread#getPriority
-     *
-     * @since Android 1.0
      */
     public final void setPriority(int priority) {
         checkAccess();
 
         if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
-            throw new IllegalArgumentException("Prioritiy out of range"); // TODO Externalize?
+            throw new IllegalArgumentException("Priority out of range"); // TODO Externalize?
         }
 
         if (priority > group.getMaxPriority()) {
@@ -1259,8 +1174,6 @@
      *            The handler to set or <code>null</code>.
      * @throws SecurityException
      *             if the current SecurityManager fails the checkAccess call.
-     *
-     * @since Android 1.0
      */
     public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
         checkAccess();
@@ -1279,8 +1192,6 @@
      *             if <code>interrupt()</code> was called for this Thread while
      *             it was sleeping
      * @see Thread#interrupt()
-     *
-     * @since Android 1.0
      */
     public static void sleep(long time) throws InterruptedException {
         Thread.sleep(time, 0);
@@ -1299,8 +1210,6 @@
      *             if <code>interrupt()</code> was called for this Thread while
      *             it was sleeping
      * @see Thread#interrupt()
-     *
-     * @since Android 1.0
      */
     public static void sleep(long millis, int nanos) throws InterruptedException {
         VMThread.sleep(millis, nanos);
@@ -1314,8 +1223,6 @@
      * @throws IllegalThreadStateException if the Thread has been started before
      *
      * @see Thread#run
-     *
-     * @since Android 1.0
      */
     public synchronized void start() {
         if (hasBeenStarted) {
@@ -1336,8 +1243,6 @@
      *         SecurityException
      * @deprecated because stopping a thread in this manner is unsafe and can
      * leave your application and the VM in an unpredictable state.
-     *
-     * @since Android 1.0
      */
     @Deprecated
     public final void stop() {
@@ -1357,8 +1262,6 @@
      *         <code>null</code>
      * @deprecated because stopping a thread in this manner is unsafe and can
      * leave your application and the VM in an unpredictable state.
-     *
-     * @since Android 1.0
      */
     @Deprecated
     public final synchronized void stop(Throwable throwable) {
@@ -1391,8 +1294,6 @@
      *             if <code>checkAccess()</code> fails with a SecurityException
      * @see Thread#resume()
      * @deprecated May cause deadlocks.
-     *
-     * @since Android 1.0
      */
     @Deprecated
     public final void suspend() {
@@ -1409,8 +1310,6 @@
      * Thread. It includes the Thread's name, priority, and group name.
      *
      * @return a printable representation for the receiver.
-     *
-     * @since Android 1.0
      */
     @Override
     public String toString() {
@@ -1420,8 +1319,6 @@
     /**
      * Causes the calling Thread to yield execution time to another Thread that
      * is ready to run. The actual scheduling is implementation-dependent.
-     *
-     * @since Android 1.0
      */
     public static void yield() {
         VMThread.yield();
@@ -1434,8 +1331,6 @@
      * @param object the object to test for the monitor lock
      * @return true if the current thread has a monitor lock on the specified
      *         object; false otherwise
-     *
-     * @since Android 1.0
      */
     public static boolean holdsLock(Object object) {
         return currentThread().vmThread.holdsLock(object);
@@ -1446,8 +1341,6 @@
      * terminated by an uncaught exception. Upon such termination, the handler
      * is notified of the terminating thread and causal exception. If there is
      * no explicit handler set then the thread's group is the default handler.
-     *
-     * @since Android 1.0
      */
     public static interface UncaughtExceptionHandler {
         /**
@@ -1457,8 +1350,6 @@
          *
          * @param thread the thread that has an uncaught exception
          * @param ex the exception that was thrown
-         *
-         * @since Android 1.0
          */
         void uncaughtException(Thread thread, Throwable ex);
     }
diff --git a/luni-kernel/src/main/java/java/lang/ThreadGroup.java b/luni-kernel/src/main/java/java/lang/ThreadGroup.java
index 33fa31e..690fb45 100644
--- a/luni-kernel/src/main/java/java/lang/ThreadGroup.java
+++ b/luni-kernel/src/main/java/java/lang/ThreadGroup.java
@@ -18,22 +18,10 @@
 package java.lang;
 
 /**
- * A {@code ThreadGroup} is a means of organizing {@link Thread}s into a
- * hierarchical structure. A {@code ThreadGroup} can contain zero or more
- * {@code Thread}s and zero or more other {@code ThreadGroup}s. Each {@code
- * Thread} and each {@code ThreadGroup} (except the root group) has a unique
- * parent {@code ThreadGroup}. The result is a tree whose inner nodes are
- * {@code ThreadGroup}s and whose leaf nodes are {@code Threads}. The unique
- * root of the tree is a {@code ThreadGroup} that is created at VM startup and
- * has the name "system". The benefit of using {@code ThreadGroup}s, in addition
- * to the mere housekeeping aspect, is that all {@code Thread}s in a {@code
- * ThreadGroup} can be manipulated together, that is, the {@code ThreadGroup}
- * has methods that delegate to all its all {@code Thread}s.
- * 
+ * {@code ThreadGroup} is a means of organizing threads into a hierarchical structure.
+ * This class is obsolete. See <i>Effective Java</i> Item 73, "Avoid thread groups" for details.
  * @see Thread
  * @see SecurityManager
- * 
- * @since Android 1.0
  */
 public class ThreadGroup implements Thread.UncaughtExceptionHandler {
 
@@ -94,15 +82,12 @@
     // END android-removed
 
     /**
-     * Constructs a new ThreadGroup with the name provided. The new ThreadGroup
-     * will be child of the ThreadGroup to which the
-     * {@code Thread.currentThread()} belongs.
+     * Constructs a new {@code ThreadGroup} with the given name. The new {@code ThreadGroup}
+     * will be child of the {@code ThreadGroup} to which the calling thread belongs.
      * 
-     * @param name the name for the ThreadGroup being created
-     * 
+     * @param name the name
      * @throws SecurityException if {@code checkAccess()} for the parent
      *         group fails with a SecurityException
-     * 
      * @see java.lang.Thread#currentThread
      */
 
@@ -111,14 +96,12 @@
     }
 
     /**
-     * Constructs a new ThreadGroup with the name provided, as child of the
-     * ThreadGroup {@code parent}.
+     * Constructs a new {@code ThreadGroup} with the given name, as a child of the
+     * given {@code ThreadGroup}.
      * 
-     * @param parent the parent ThreadGroup
-     * @param name the name for the ThreadGroup being created
-     * 
-     * @throws NullPointerException if {@code parent} is
-     *         {@code null}
+     * @param parent the parent
+     * @param name the name
+     * @throws NullPointerException if {@code parent == null}
      * @throws SecurityException if {@code checkAccess()} for the parent
      *         group fails with a SecurityException
      * @throws IllegalThreadStateException if {@code parent} has been
@@ -152,12 +135,11 @@
     }
 
     /**
-     * Returns the number of Threads which are children of the receiver,
-     * directly or indirectly and are running.
+     * Returns the number of running {@code Thread}s which are children of this thread group,
+     * directly or indirectly.
      * 
-     * @return the number of children Threads
+     * @return the number of children
      */
-
     public int activeCount() {
         // BEGIN android-changed
         int count = 0;
@@ -180,10 +162,10 @@
     }
 
     /**
-     * Returns the number of ThreadGroups which are children of the receiver,
+     * Returns the number of {@code ThreadGroup}s which are children of this group,
      * directly or indirectly.
      * 
-     * @return the number of children ThreadGroups
+     * @return the number of children
      */
     public int activeGroupCount() {
         int count = 0;
@@ -198,15 +180,12 @@
     }
 
     /**
-     * Adds a Thread to the receiver. This should only be visible to class
+     * Adds a {@code Thread} to this thread group. This should only be visible to class
      * java.lang.Thread, and should only be called when a new Thread is created
      * and initialized by the constructor.
      * 
-     * @param thread Thread to add to the receiver
-     * 
-     * @throws IllegalThreadStateException if the receiver has been destroyed
-     *         already
-     * 
+     * @param thread Thread to add
+     * @throws IllegalThreadStateException if this group has been destroyed already
      * @see #remove(java.lang.Thread)
      */
     final void add(Thread thread) throws IllegalThreadStateException {
@@ -227,12 +206,10 @@
     }
 
     /**
-     * Adds a ThreadGroup to the receiver.
+     * Adds a {@code ThreadGroup} to this thread group.
      * 
-     * @param g ThreadGroup to add to the receiver
-     * 
-     * @throws IllegalThreadStateException if the receiver has been destroyed
-     *         already
+     * @param g ThreadGroup to add
+     * @throws IllegalThreadStateException if this group has been destroyed already
      */
     private void add(ThreadGroup g) throws IllegalThreadStateException {
         synchronized (this.childrenGroupsLock) {
@@ -268,14 +245,12 @@
     }
 
     /**
-     * Checks the accessibility of the ThreadGroup from the perspective of the
-     * caller. If there is a SecurityManager installed, calls
-     * {@code checkAccess} with the receiver as a parameter, otherwise does
+     * Checks the accessibility of this {@code ThreadGroup} from the perspective of the
+     * caller. If there is a {@code SecurityManager} installed, calls
+     * {@code checkAccess} with this thread group as a parameter, otherwise does
      * nothing.
      */
     public final void checkAccess() {
-        // Forwards the message to the SecurityManager (if there's one) passing
-        // the receiver as parameter
         SecurityManager currentManager = System.getSecurityManager();
         if (currentManager != null) {
             currentManager.checkAccess(this);
@@ -283,18 +258,17 @@
     }
 
     /**
-     * Destroys the receiver and recursively all its subgroups. It is only legal
-     * to destroy a ThreadGroup that has no Threads in it. Any daemon
-     * ThreadGroup is destroyed automatically when it becomes empty (no Threads
-     * and no ThreadGroups in it).
+     * Destroys this thread group and recursively all its subgroups. It is only legal
+     * to destroy a {@code ThreadGroup} that has no threads in it. Any daemon
+     * {@code ThreadGroup} is destroyed automatically when it becomes empty (no threads
+     * or thread groups in it).
      * 
-     * @throws IllegalThreadStateException if the receiver or any of its
+     * @throws IllegalThreadStateException if this thread group or any of its
      *         subgroups has been destroyed already or if it still contains
      *         threads.
      * @throws SecurityException if {@code this.checkAccess()} fails with
      *         a SecurityException
      */
-
     public final void destroy() {
         checkAccess();
 
@@ -334,8 +308,8 @@
     }
 
     /*
-     * Auxiliary method that destroys the receiver and recursively all its
-     * subgroups if the receiver is a daemon ThreadGroup.
+     * Auxiliary method that destroys this thread group and recursively all its
+     * subgroups if this is a daemon ThreadGroup.
      * 
      * @see #destroy
      * @see #setDaemon
@@ -359,8 +333,11 @@
      * stores the threads in the given array. Returns when the array is full or
      * no more threads remain, whichever happens first.
      * 
-     * @param threads the array into which the Threads will be copied
-     * @return the number of Threads that were copied
+     * <p>Note that this method will silently ignore any threads that don't fit in the
+     * supplied array.
+     * 
+     * @param threads the array into which the {@code Thread}s will be copied
+     * @return the number of {@code Thread}s that were copied
      */
     public int enumerate(Thread[] threads) {
         return enumerate(threads, true);
@@ -371,11 +348,13 @@
      * sub-groups) and stores the threads in the given array. Returns when the
      * array is full or no more threads remain, whichever happens first.
      * 
-     * @param threads the array into which the Threads will be copied
-     * @param recurse indicates whether Threads in subgroups should be
-     *        recursively copied as well
-     * @return the number of Threads that were copied
+     * <p>Note that this method will silently ignore any threads that don't fit in the
+     * supplied array.
      * 
+     * @param threads the array into which the {@code Thread}s will be copied
+     * @param recurse indicates whether {@code Thread}s in subgroups should be
+     *        recursively copied as well
+     * @return the number of {@code Thread}s that were copied
      */
     public int enumerate(Thread[] threads, boolean recurse) {
         return enumerateGeneric(threads, recurse, 0, true);
@@ -386,9 +365,11 @@
      * and stores the groups in the given array. Returns when the array is full
      * or no more groups remain, whichever happens first.
      * 
-     * @param groups the array into which the ThreadGroups will be copied
-     * @return the number of ThreadGroups that were copied
+     * <p>Note that this method will silently ignore any thread groups that don't fit in the
+     * supplied array.
      * 
+     * @param groups the array into which the {@code ThreadGroup}s will be copied
+     * @return the number of {@code ThreadGroup}s that were copied
      */
     public int enumerate(ThreadGroup[] groups) {
         return enumerate(groups, true);
@@ -396,14 +377,16 @@
 
     /**
      * Iterates over all thread groups in this group (and, optionally, its
-     * sub-groups) and and stores the groups in the given array. Returns when
+     * sub-groups) and stores the groups in the given array. Returns when
      * the array is full or no more groups remain, whichever happens first.
      * 
-     * @param groups the array into which the ThreadGroups will be copied
-     * @param recurse indicates whether ThreadGroups in subgroups should be
-     *        recursively copied as well or not
-     * @return the number of ThreadGroups that were copied
+     * <p>Note that this method will silently ignore any thread groups that don't fit in the
+     * supplied array.
      * 
+     * @param groups the array into which the {@code ThreadGroup}s will be copied
+     * @param recurse indicates whether {@code ThreadGroup}s in subgroups should be
+     *        recursively copied as well or not
+     * @return the number of {@code ThreadGroup}s that were copied
      */
     public int enumerate(ThreadGroup[] groups, boolean recurse) {
         return enumerateGeneric(groups, recurse, 0, false);
@@ -460,7 +443,7 @@
     }
 
     /**
-     * Returns the maximum allowed priority for a Thread in the receiver.
+     * Returns the maximum allowed priority for a {@code Thread} in this thread group.
      * 
      * @return the maximum priority
      * 
@@ -471,20 +454,19 @@
     }
 
     /**
-     * Returns the name of the receiver.
+     * Returns the name of this thread group.
      * 
-     * @return the receiver's name
+     * @return the group's name
      */
     public final String getName() {
         return name;
     }
 
     /**
-     * Returns the receiver's parent ThreadGroup. It can be {@code null}  if the
-     * receiver is the the root ThreadGroup.
+     * Returns this thread group's parent {@code ThreadGroup}. It can be null if this
+     * is the the root ThreadGroup.
      * 
-     * @return the parent ThreadGroup
-     * 
+     * @return the parent
      */
     public final ThreadGroup getParent() {
         if (parent != null) {
@@ -494,7 +476,7 @@
     }
 
     /**
-     * Interrupts every Thread in the receiver and recursively in all its
+     * Interrupts every {@code Thread} in this group and recursively in all its
      * subgroups.
      * 
      * @throws SecurityException if {@code this.checkAccess()} fails with
@@ -519,9 +501,9 @@
     }
 
     /**
-     * Checks whether the receiver is a daemon ThreadGroup.
+     * Checks whether this thread group is a daemon {@code ThreadGroup}.
      * 
-     * @return true if (and only if) the receiver is a daemon ThreadGroup
+     * @return true if this thread group is a daemon {@code ThreadGroup}
      * 
      * @see #setDaemon
      * @see #destroy
@@ -531,10 +513,9 @@
     }
 
     /**
-     * Checks whether the receiver has already been destroyed.
+     * Checks whether this thread group has already been destroyed.
      * 
-     * @return true if (and only if) the receiver has already been destroyed
-     * 
+     * @return true if this thread group has already been destroyed
      * @see #destroy
      */
     public synchronized boolean isDestroyed() {
@@ -543,8 +524,8 @@
 
     /**
      * Outputs to {@code System.out} a text representation of the
-     * hierarchy of Threads and ThreadGroups in the receiver (and recursively).
-     * Proper indentation is done to suggest the nesting of groups inside groups
+     * hierarchy of {@code Thread}s and {@code ThreadGroup}s in this thread group (and recursively).
+     * Proper indentation is used to show the nesting of groups inside groups
      * and threads inside groups.
      */
     public void list() {
@@ -555,7 +536,7 @@
 
     /*
      * Outputs to {@code System.out}a text representation of the
-     * hierarchy of Threads and ThreadGroups in the receiver (and recursively).
+     * hierarchy of Threads and ThreadGroups in this thread group (and recursively).
      * The indentation will be four spaces per level of nesting.
      * 
      * @param levels How many levels of nesting, so that proper indentation can
@@ -587,13 +568,11 @@
     }
 
     /**
-     * Checks whether the receiver is a direct or indirect parent group of a
-     * given ThreadGroup.
+     * Checks whether this thread group is a direct or indirect parent group of a
+     * given {@code ThreadGroup}.
      * 
-     * @param g the potential child ThreadGroup
-     * 
-     * @return true if (and only if) the receiver is parent of {@code g}
-     * 
+     * @param g the potential child {@code ThreadGroup}
+     * @return true if this thread group is parent of {@code g}
      */
     public final boolean parentOf(ThreadGroup g) {
         while (g != null) {
@@ -606,10 +585,10 @@
     }
 
     /**
-     * Removes a Thread from the receiver. This should only be visible to class
+     * Removes a {@code Thread} from this group. This should only be visible to class
      * java.lang.Thread, and should only be called when a Thread dies.
      * 
-     * @param thread Thread to remove from the receiver
+     * @param thread Thread to remove
      * 
      * @see #add(Thread)
      */
@@ -630,9 +609,9 @@
     }
 
     /**
-     * Removes an immediate subgroup from the receiver.
+     * Removes an immediate subgroup.
      * 
-     * @param g ThreadGroup to remove from the receiver
+     * @param g ThreadGroup to remove
      * 
      * @see #add(Thread)
      * @see #add(ThreadGroup)
@@ -652,7 +631,7 @@
     }
 
     /**
-     * Resumes every Thread in the receiver and recursively in all its
+     * Resumes every thread in this group and recursively in all its
      * subgroups.
      * 
      * @throws SecurityException if {@code this.checkAccess()} fails with
@@ -682,12 +661,10 @@
     }
 
     /**
-     * Configures the receiver to be a daemon ThreadGroup or not. Daemon
-     * ThreadGroups are automatically destroyed when they become empty.
+     * Sets whether this is a daemon {@code ThreadGroup} or not. Daemon
+     * thread groups are automatically destroyed when they become empty.
      * 
-     * @param isDaemon the new value defining if receiver should be daemon or
-     *                 not
-     * 
+     * @param isDaemon the new value
      * @throws SecurityException if {@code checkAccess()} for the parent
      *         group fails with a SecurityException
      * 
@@ -700,12 +677,12 @@
     }
 
     /**
-     * Configures the maximum allowed priority for a Thread in the receiver and
+     * Configures the maximum allowed priority for a {@code Thread} in this group and
      * recursively in all its subgroups.
      * 
-     * One can never change the maximum priority of a ThreadGroup to be higher
-     * than it was. Such an attempt will not result in an exception, it will
-     * simply leave the ThreadGroup with its current maximum priority.
+     * <p>A caller can never increase the maximum priority of a thread group.
+     * Such an attempt will not result in an exception, it will
+     * simply leave the thread group with its current maximum priority.
      * 
      * @param newMax the new maximum priority to be set
      * 
@@ -737,11 +714,11 @@
     }
 
     /**
-     * Sets the parent ThreadGroup of the receiver, and adds the receiver to the
-     * parent's collection of immediate children (if {@code parent} is
+     * Sets the parent {@code ThreadGroup} of this thread group, and adds this
+     * thread group to the parent's collection of immediate children (if {@code parent} is
      * not {@code null}).
      * 
-     * @param parent The parent ThreadGroup, or null if the receiver is to be
+     * @param parent The parent ThreadGroup, or null to make this thread group
      *        the root ThreadGroup
      * 
      * @see #getParent
@@ -755,7 +732,7 @@
     }
 
     /**
-     * Stops every Thread in the receiver and recursively in all its subgroups.
+     * Stops every thread in this group and recursively in all its subgroups.
      * 
      * @throws SecurityException if {@code this.checkAccess()} fails with
      *         a SecurityException
@@ -804,7 +781,7 @@
     }
 
     /**
-     * Suspends every Thread in the receiver and recursively in all its
+     * Suspends every thread in this group and recursively in all its
      * subgroups.
      * 
      * @throws SecurityException if {@code this.checkAccess()} fails with
@@ -852,31 +829,21 @@
         return suspendCurrent;
     }
 
-    /**
-     * Returns a string containing a concise, human-readable description of the
-     * receiver.
-     * 
-     * @return a printable representation of the ThreadGroup
-     */
     @Override
     public String toString() {
-        return getClass().getName() + "[name=" + this.getName() + ",maxpri="
+        return getClass().getName() + "[name=" + this.getName() + ",maxPriority="
                 + this.getMaxPriority() + "]";
     }
 
     /**
-     * Handles uncaught exceptions. Any uncaught exception in any Thread
-     * is forwarded (by the VM) to the Thread's ThreadGroup by sending this
-     * message (uncaughtException). This allows users to define custom
-     * ThreadGroup classes and custom behavior for when a Thread has an
-     * uncaughtException or when it does (ThreadDeath).
+     * Handles uncaught exceptions. Any uncaught exception in any {@code Thread}
+     * is forwarded to the thread's {@code ThreadGroup} by invoking this
+     * method.
+     * 
+     * <p>New code should use {@link Thread#setUncaughtExceptionHandler} instead of thread groups.
      * 
      * @param t the Thread that terminated with an uncaught exception
      * @param e the uncaught exception itself
-     * 
-     * @see Thread#stop()
-     * @see Thread#stop(Throwable)
-     * @see ThreadDeath
      */
     public void uncaughtException(Thread t, Throwable e) {
         // BEGIN android-changed
@@ -896,9 +863,9 @@
     /**
      * Non-standard method for adding a thread to a group, required by Dalvik.
      * 
-     * @param thread Thread to add to the receiver
+     * @param thread Thread to add
      * 
-     * @throws IllegalThreadStateException if the receiver has been destroyed
+     * @throws IllegalThreadStateException if the thread has been destroyed
      *         already
      * 
      * @see #add(java.lang.Thread)
@@ -911,9 +878,9 @@
     /**
      * Non-standard method for adding a thread to a group, required by Dalvik.
      * 
-     * @param thread Thread to add to the receiver
+     * @param thread Thread to add
      * 
-     * @throws IllegalThreadStateException if the receiver has been destroyed
+     * @throws IllegalThreadStateException if the thread has been destroyed
      *         already
      * 
      * @see #remove(java.lang.Thread)
diff --git a/luni-kernel/src/main/java/java/lang/Throwable.java b/luni-kernel/src/main/java/java/lang/Throwable.java
index 12b4e9b..c94631b 100644
--- a/luni-kernel/src/main/java/java/lang/Throwable.java
+++ b/luni-kernel/src/main/java/java/lang/Throwable.java
@@ -41,8 +41,6 @@
  * @see Error
  * @see Exception
  * @see RuntimeException
- * 
- * @since Android 1.0
  */
 public class Throwable implements java.io.Serializable {
     private static final long serialVersionUID = -3042686055658047285L;
@@ -72,8 +70,6 @@
 
     /**
      * Constructs a new {@code Throwable} that includes the current stack trace.
-     * 
-     * @since Android 1.0
      */
     public Throwable() {
         super();
@@ -86,7 +82,6 @@
      * 
      * @param detailMessage
      *            the detail message for this {@code Throwable}.
-     * @since Android 1.0
      */
     public Throwable(String detailMessage) {
         this();
@@ -101,7 +96,6 @@
      *            the detail message for this {@code Throwable}.
      * @param throwable
      *            the cause of this {@code Throwable}.
-     * @since Android 1.0
      */
     public Throwable(String detailMessage, Throwable throwable) {
         this();
@@ -115,7 +109,6 @@
      * 
      * @param throwable
      *            the cause of this {@code Throwable}.
-     * @since Android 1.0
      */
     public Throwable(Throwable throwable) {
         this();
@@ -131,7 +124,6 @@
      * trace to represent the location where the exception was re-thrown.
      * 
      * @return this {@code Throwable} instance.
-     * @since Android 1.0
      */
     public Throwable fillInStackTrace() {
         // Fill in the intermediate representation
@@ -148,7 +140,6 @@
      * provided at creation time.
      * 
      * @return this {@code Throwable}'s detail message.
-     * @since Android 1.0
      */
     public String getMessage() {
         return detailMessage;
@@ -158,11 +149,9 @@
      * Returns the extra information message which was provided when this
      * {@code Throwable} was created. Returns {@code null} if no message was
      * provided at creation time. Subclasses may override this method to return
-     * localized text for the message. The Android reference implementation
-     * returns the unlocalized detail message.
+     * localized text for the message. Android returns the regular detail message.
      * 
      * @return this {@code Throwable}'s localized detail message.
-     * @since Android 1.0
      */
     public String getLocalizedMessage() {
         return getMessage();
@@ -178,7 +167,6 @@
      *         the call stack. Changes in the array obtained from this call will
      *         not change the call stack stored in this {@code Throwable}.
      * @see #printStackTrace()
-     * @since Android 1.0
      */
     public StackTraceElement[] getStackTrace() {
         return getInternalStackTrace().clone();
@@ -198,7 +186,6 @@
      * @throws NullPointerException
      *             if any element in {@code trace} is {@code null}.
      * @see #printStackTrace()
-     * @since Android 1.0
      */
     public void setStackTrace(StackTraceElement[] trace) {
         StackTraceElement[] newTrace = trace.clone();
@@ -214,7 +201,6 @@
      * Writes a printable representation of this {@code Throwable}'s stack trace
      * to the {@code System.err} stream.
      * 
-     * @since Android 1.0
      */
     public void printStackTrace() {
         printStackTrace(System.err);
@@ -268,7 +254,6 @@
      * 
      * @param err
      *            the stream to write the stack trace on.
-     * @since Android 1.0
      */
     public void printStackTrace(PrintStream err) {
         err.println(toString());
@@ -305,7 +290,6 @@
      * 
      * @param err
      *            the writer to write the stack trace on.
-     * @since Android 1.0
      */
     public void printStackTrace(PrintWriter err) {
         err.println(toString());
@@ -356,7 +340,6 @@
      *             if {@code Throwable} is this object.
      * @throws IllegalStateException
      *             if the cause has already been initialized.
-     * @since Android 1.0
      */
     public Throwable initCause(Throwable throwable) {
         // BEGIN android-note
@@ -377,7 +360,6 @@
      * no cause.
      * 
      * @return Throwable this {@code Throwable}'s cause.
-     * @since Android 1.0
      */
     public Throwable getCause() {
         if (cause == this) {
@@ -407,4 +389,3 @@
     native private static StackTraceElement[] nativeGetStackTrace(Object stackState);
     // END android-added
 }
-
diff --git a/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java b/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java
index b5b2de0..46ffcad 100644
--- a/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java
+++ b/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java
@@ -44,8 +44,6 @@
  * Phantom references are useful for implementing cleanup operations that are
  * necessary before an object gets garbage-collected. They are sometimes more
  * flexible than the {@link Object#finalize()} method.
- * 
- * @since Android 1.0
  */
 public class PhantomReference<T> extends Reference<T> {
 
@@ -57,8 +55,6 @@
      * 
      * @param r the referent to track
      * @param q the queue to register the phantom reference object with
-     * 
-     * @since Android 1.0
      */
     public PhantomReference(T r, ReferenceQueue<? super T> q) {
         super();
@@ -71,8 +67,6 @@
      * accessible.
      * 
      * @return {@code null} (always)
-     * 
-     * @since Android 1.0
      */
     @Override
     public T get() {
diff --git a/luni-kernel/src/main/java/java/lang/ref/Reference.java b/luni-kernel/src/main/java/java/lang/ref/Reference.java
index c695830..9b59b35 100644
--- a/luni-kernel/src/main/java/java/lang/ref/Reference.java
+++ b/luni-kernel/src/main/java/java/lang/ref/Reference.java
@@ -39,8 +39,6 @@
  * also not desirable to do so, since references require very close cooperation
  * with the system's garbage collector. The existing, specialized reference
  * classes should be used instead.
- * 
- * @since Android 1.0
  */
 public abstract class Reference<T> {
 
@@ -86,8 +84,6 @@
     /**
      * Makes the referent {@code null}. This does not force the reference
      * object to be enqueued.
-     * 
-     * @since Android 1.0
      */
     public void clear() {
         referent = null;
@@ -103,8 +99,6 @@
      * 
      * @return {@code true} if this call has caused the {@code Reference} to
      * become enqueued, or {@code false} otherwise
-     * 
-     * @since Android 1.0
      */
     @SuppressWarnings("unchecked")
     private synchronized boolean enqueueInternal() {
@@ -128,8 +122,6 @@
      * 
      * @return {@code true} if this call has caused the {@code Reference} to
      * become enqueued, or {@code false} otherwise
-     * 
-     * @since Android 1.0
      */
     public boolean enqueue() {
         return enqueueInternal();
@@ -140,8 +132,6 @@
      * 
      * @return the referent to which reference refers, or {@code null} if the
      *         object has been cleared.
-     * 
-     * @since Android 1.0
      */
     public T get() {
         return referent;
@@ -152,8 +142,6 @@
      * 
      * @return {@code true} if the {@code Reference} has been enqueued, {@code
      *         false} otherwise
-     * 
-     * @since Android 1.0
      */
     public boolean isEnqueued() {
         return queueNext != null;
diff --git a/luni-kernel/src/main/java/java/lang/ref/SoftReference.java b/luni-kernel/src/main/java/java/lang/ref/SoftReference.java
index 757289e..2bf8746 100644
--- a/luni-kernel/src/main/java/java/lang/ref/SoftReference.java
+++ b/luni-kernel/src/main/java/java/lang/ref/SoftReference.java
@@ -83,8 +83,6 @@
  *     known to be weakly-referenced.  
  *   </li>
  * </ul>
- * 
- * @since Android 1.0
  */
 public class SoftReference<T> extends Reference<T> {
 
@@ -93,8 +91,6 @@
      * reference is not registered with any reference queue.
      * 
      * @param r the referent to track
-     * 
-     * @since Android 1.0
      */
     public SoftReference(T r) {
         super();
@@ -109,27 +105,10 @@
      * @param q the queue to register to the reference object with. A null value
      *          results in a weak reference that is not associated with any
      *          queue.
-     * 
-     * @since Android 1.0
      */
     public SoftReference(T r, ReferenceQueue<? super T> q) {
         super();
         referent = r;
         queue = q;
     }
-
-// BEGIN android-removed
-//    /**
-//     * Return the referent of the reference object.
-//     * 
-//     * @return the referent to which reference refers, or {@code null} if the
-//     *         referent has been cleared.
-//     * 
-//     * @since Android 1.0
-//     */
-//    @Override
-//    public T get() {
-//        return super.get();
-//    }
-// END android-removed
 }
diff --git a/luni-kernel/src/main/java/java/lang/ref/WeakReference.java b/luni-kernel/src/main/java/java/lang/ref/WeakReference.java
index cbd2248..e326a24 100644
--- a/luni-kernel/src/main/java/java/lang/ref/WeakReference.java
+++ b/luni-kernel/src/main/java/java/lang/ref/WeakReference.java
@@ -82,8 +82,6 @@
  *     known to be weakly-referenced.  
  *   </li>
  * </ul>
- * 
- * @since Android 1.0
  */
 public class WeakReference<T> extends Reference<T> {
 
@@ -92,8 +90,6 @@
      * reference is not registered with any reference queue.
      * 
      * @param r the referent to track
-     * 
-     * @since Android 1.0
      */
     public WeakReference(T r) {
         super();
@@ -108,8 +104,6 @@
      * @param q the queue to register to the reference object with. A null value
      *          results in a weak reference that is not associated with any
      *          queue.
-     * 
-     * @since Android 1.0
      */
     public WeakReference(T r, ReferenceQueue<? super T> q) {
         super();
diff --git a/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java b/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java
index 0178276..8990156 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java
@@ -54,8 +54,6 @@
  * @see Constructor
  * @see Method
  * @see ReflectPermission
- * 
- * @since Android 1.0
  */
 public class AccessibleObject implements AnnotatedElement {
 
@@ -110,8 +108,6 @@
      *             
      * @see #setAccessible(boolean)
      * @see ReflectPermission
-     * 
-     * @since Android 1.0
      */
     public static void setAccessible(AccessibleObject[] objects, boolean flag)
             throws SecurityException {
@@ -131,8 +127,6 @@
      * Constructs a new {@code AccessibleObject} instance. {@code
      * AccessibleObject} instances can only be constructed by the virtual
      * machine.
-     * 
-     * @since Android 1.0
      */
     protected AccessibleObject() {
         super();
@@ -144,8 +138,6 @@
      * 
      * @return {@code true} if this object is accessible without security
      *         checks, {@code false} otherwise
-     *         
-     * @since Android 1.0
      */
     public boolean isAccessible() {
         return flag;
@@ -164,8 +156,6 @@
      *             if the request is denied
      *             
      * @see ReflectPermission
-     * 
-     * @since Android 1.0
      */
     public void setAccessible(boolean flag) throws SecurityException {
         SecurityManager smgr = System.getSecurityManager();
diff --git a/luni-kernel/src/main/java/java/lang/reflect/Array.java b/luni-kernel/src/main/java/java/lang/reflect/Array.java
index d633e69..8a12f71 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/Array.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/Array.java
@@ -34,8 +34,6 @@
 
 /**
  * This class provides static methods to create and access arrays dynamically.
- *
- * @since Android 1.0
  */
 public final class Array {
     
@@ -64,8 +62,6 @@
      *             if {@code array} is not an array
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static Object get(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -76,19 +72,19 @@
             return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE;
         
         if (array instanceof byte[])
-            return new Byte(((byte[]) array)[index]);
+            return Byte.valueOf(((byte[]) array)[index]);
         
         if (array instanceof char[])
-            return new Character(((char[]) array)[index]);
+            return Character.valueOf(((char[]) array)[index]);
         
         if (array instanceof short[])
-            return new Short(((short[]) array)[index]);
+            return Short.valueOf(((short[]) array)[index]);
         
         if (array instanceof int[])
-            return new Integer(((int[]) array)[index]);
+            return Integer.valueOf(((int[]) array)[index]);
         
         if (array instanceof long[])
-            return new Long(((long[]) array)[index]);
+            return Long.valueOf(((long[]) array)[index]);
         
         if (array instanceof float[])
             return new Float(((float[]) array)[index]);
@@ -121,8 +117,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static boolean getBoolean(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -156,8 +150,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static byte getByte(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -187,8 +179,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static char getChar(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -222,8 +212,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static double getDouble(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -253,8 +241,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static float getFloat(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -284,8 +270,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static int getInt(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -309,8 +293,6 @@
      *             if the {@code array} is {@code null}
      * @throws IllegalArgumentException
      *             if {@code array} is not an array
-     * 
-     * @since Android 1.0
      */
     public static int getLength(Object array) {
         if (array instanceof Object[])
@@ -365,8 +347,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static long getLong(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -396,8 +376,6 @@
      *             index position can not be converted to the return type
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static short getShort(Object array, int index)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -427,8 +405,6 @@
      * @throws IllegalArgumentException
      *             if the array of dimensions is of size zero, or exceeds the
      *             limit of the number of dimension for an array (currently 255)
-     * 
-     * @since Android 1.0
      */
     public static Object newInstance(Class<?> componentType, int[] dimensions)
             throws NegativeArraySizeException, IllegalArgumentException {
@@ -465,8 +441,6 @@
      *             if the component type is null
      * @throws NegativeArraySizeException
      *             if {@code size < 0}
-     * 
-     * @since Android 1.0
      */
     public static Object newInstance(Class<?> componentType, int size)
             throws NegativeArraySizeException {
@@ -528,8 +502,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void set(Object array, int index, Object value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -588,8 +560,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setBoolean(Object array, int index, boolean value) {
         if (array instanceof boolean[]) {
@@ -617,8 +587,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setByte(Object array, int index, byte value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -647,8 +615,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setChar(Object array, int index, char value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -681,8 +647,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setDouble(Object array, int index, double value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -715,8 +679,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setFloat(Object array, int index, float value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -745,8 +707,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setInt(Object array, int index, int value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -775,8 +735,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setLong(Object array, int index, long value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
@@ -805,8 +763,6 @@
      *             converted to the array type by a widening conversion
      * @throws ArrayIndexOutOfBoundsException
      *             if {@code  index < 0 || index >= array.length}
-     * 
-     * @since Android 1.0
      */
     public static void setShort(Object array, int index, short value)
             throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
diff --git a/luni-kernel/src/main/java/java/lang/reflect/Constructor.java b/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
index 3918d7e..784f273 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/Constructor.java
@@ -46,8 +46,6 @@
  * accessed, and the constructor can be invoked dynamically.
  * 
  * @param <T> the class that declares this constructor
- *
- * @since Android 1.0
  */
 public final class Constructor<T> extends AccessibleObject implements GenericDeclaration,
         Member {
@@ -132,8 +130,6 @@
      * including the type parameters.
      *
      * @return the string representation of the constructor's declaration
-     * 
-     * @since Android 1.0
      */
     public String toGenericString() {
         StringBuilder sb = new StringBuilder(80);
@@ -185,8 +181,6 @@
      * @throws MalformedParameterizedTypeException
      *             if any parameter type points to a type that cannot be
      *             instantiated for some reason
-     * 
-     * @since Android 1.0
      */
     public Type[] getGenericParameterTypes() {
         initGenericTypes();
@@ -207,7 +201,6 @@
      * @throws MalformedParameterizedTypeException
      *             if any exception type points to a type that cannot be
      *             instantiated for some reason
-     * @since Android 1.0
      */
     public Type[] getGenericExceptionTypes() {
         initGenericTypes();
@@ -228,8 +221,6 @@
      * set, then an array of empty arrays is returned.
      * 
      * @return an array of arrays of {@code Annotation} instances
-     * 
-     * @since Android 1.0
      */
     public Annotation[][] getParameterAnnotations() {
         Annotation[][] parameterAnnotations
@@ -248,8 +239,6 @@
      *
      * @return {@code true} if a vararg is declare, otherwise
      *         {@code false}
-     * 
-     * @since Android 1.0
      */
     public boolean isVarArgs() {
         int mods = getConstructorModifiers(declaringClass, slot);
@@ -262,8 +251,6 @@
      * 
      * @return {@code true} if this constructor is synthetic, {@code false}
      *         otherwise
-     * 
-     * @since Android 1.0
      */
     public boolean isSynthetic() {
         int mods = getConstructorModifiers(declaringClass, slot);
@@ -283,8 +270,6 @@
      *         constructor, {@code false} otherwise
      * 
      * @see #hashCode
-     * 
-     * @since Android 1.0
      */
     @Override
     public boolean equals(Object object) {
@@ -295,8 +280,6 @@
      * Returns the class that declares this constructor.
      *
      * @return the declaring class
-     * 
-     * @since Android 1.0
      */
     public Class<T> getDeclaringClass() {
         return declaringClass;
@@ -308,8 +291,6 @@
      * returned.
      * 
      * @return the declared exception classes
-     * 
-     * @since Android 1.0
      */
     public Class<?>[] getExceptionTypes() {
         if (exceptionTypes == null)
@@ -324,8 +305,6 @@
      * @return the modifiers for this constructor
      * 
      * @see Modifier
-     * 
-     * @since Android 1.0
      */
     public int getModifiers() {
         return getConstructorModifiers(declaringClass, slot);
@@ -337,8 +316,6 @@
      * Returns the name of this constructor.
      *
      * @return the name of this constructor
-     * 
-     * @since Android 1.0
      */
     public String getName() {
         return declaringClass.getName();
@@ -350,8 +327,6 @@
      * no parameters, an empty array will be returned.
      *
      * @return the parameter types
-     * 
-     * @since Android 1.0
      */
     public Class<?>[] getParameterTypes() {
         return parameterTypes.clone();
@@ -385,8 +360,6 @@
      * @return the hash code
      * 
      * @see #equals
-     * 
-     * @since Android 1.0
      */
     @Override
     public int hashCode() {
@@ -438,8 +411,6 @@
      *                if an exception was thrown by the invoked constructor
      * 
      * @see AccessibleObject
-     * 
-     * @since Android 1.0
      */
     public T newInstance(Object... args) throws InstantiationException, IllegalAccessException,
             IllegalArgumentException, InvocationTargetException {
@@ -468,8 +439,6 @@
      * {@code public String(byte[],String) throws UnsupportedEncodingException}
      *
      * @return a printable representation for this constructor
-     * 
-     * @since Android 1.0
      */
     @Override
     public String toString() {
diff --git a/luni-kernel/src/main/java/java/lang/reflect/Field.java b/luni-kernel/src/main/java/java/lang/reflect/Field.java
index 0ea16df..baaafdd 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/Field.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/Field.java
@@ -43,8 +43,6 @@
 /**
  * This class represents a field. Information about the field can be accessed,
  * and the field's value can be accessed dynamically.
- * 
- * @since Android 1.0
  */
 public final class Field extends AccessibleObject implements Member {
 
@@ -132,7 +130,6 @@
      * Indicates whether or not this field is synthetic.
      * 
      * @return {@code true} if this field is synthetic, {@code false} otherwise
-     * @since Android 1.0
      */
     public boolean isSynthetic() {
         int flags = getFieldModifiers(declaringClass, slot);
@@ -144,7 +141,6 @@
      * generic type.
      * 
      * @return the string representation of this field
-     * @since Android 1.0
      */
     public String toGenericString() {
         StringBuilder sb = new StringBuilder(80);
@@ -166,7 +162,6 @@
      * 
      * @return {@code true} if this field is an enumeration constant, {@code
      *         false} otherwise
-     * @since Android 1.0
      */
     public boolean isEnumConstant() {
         int flags = getFieldModifiers(declaringClass, slot);
@@ -184,7 +179,6 @@
      * @throws MalformedParameterizedTypeException
      *             if the generic type points to a type that cannot be
      *             instantiated for some reason
-     * @since Android 1.0
      */
     public Type getGenericType() {
         initGenericType();
@@ -208,7 +202,6 @@
      * @return {@code true} if the specified object is equal to this method,
      *         {@code false} otherwise
      * @see #hashCode
-     * @since Android 1.0
      */
     @Override
     public boolean equals(Object object) {
@@ -241,7 +234,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public Object get(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getField(object, declaringClass, type, slot, flag);
@@ -269,7 +261,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public boolean getBoolean(Object object) throws IllegalAccessException,
             IllegalArgumentException {
@@ -298,7 +289,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getBField(object, declaringClass, type, slot, flag, TYPE_BYTE);
@@ -326,7 +316,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getCField(object, declaringClass, type, slot, flag, TYPE_CHAR);
@@ -336,7 +325,6 @@
      * Returns the class that declares this field.
      *
      * @return the declaring class
-     * @since Android 1.0
      */
     public Class<?> getDeclaringClass() {
         return declaringClass;
@@ -364,7 +352,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE);
@@ -392,7 +379,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getFField(object, declaringClass, type, slot, flag, TYPE_FLOAT);
@@ -420,7 +406,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getIField(object, declaringClass, type, slot, flag, TYPE_INTEGER);
@@ -448,7 +433,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getJField(object, declaringClass, type, slot, flag, TYPE_LONG);
@@ -460,7 +444,6 @@
      *
      * @return the modifiers for this field
      * @see Modifier
-     * @since Android 1.0
      */
     public int getModifiers() {
         return getFieldModifiers(declaringClass, slot);
@@ -472,7 +455,6 @@
      * Returns the name of this field.
      *
      * @return the name of this field
-     * @since Android 1.0
      */
     public String getName() {
         return name;
@@ -500,7 +482,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException {
         return getSField(object, declaringClass, type, slot, flag, TYPE_SHORT);
@@ -512,7 +493,6 @@
      * of the class
      * 
      * @return the constructor's signature.
-     * @since Android 1.0
      */
     @SuppressWarnings("unused")
     private String getSignature() {
@@ -523,7 +503,6 @@
      * Return the {@link Class} associated with the type of this field.
      * 
      * @return the type of this field
-     * @since Android 1.0
      */
     public Class<?> getType() {
         return type;
@@ -539,7 +518,6 @@
      * 
      * @return the hash code for this field
      * @see #equals
-     * @since Android 1.0
      */
     @Override
     public int hashCode() {
@@ -576,7 +554,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void set(Object object, Object value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -610,7 +587,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setBoolean(Object object, boolean value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -643,7 +619,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setByte(Object object, byte value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -676,7 +651,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setChar(Object object, char value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -709,7 +683,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setDouble(Object object, double value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -742,7 +715,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setFloat(Object object, float value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -775,7 +747,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setInt(Object object, int value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -808,7 +779,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setLong(Object object, long value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -841,7 +811,6 @@
      *             if the object is not compatible with the declaring class
      * @throws IllegalAccessException
      *             if this field is not accessible
-     * @since Android 1.0
      */
     public void setShort(Object object, short value) throws IllegalAccessException,
             IllegalArgumentException {
@@ -865,7 +834,6 @@
      * java.lang.System.in}
      * 
      * @return a printable representation for this field
-     * @since Android 1.0
      */
     @Override
     public String toString() {
diff --git a/luni-kernel/src/main/java/java/lang/reflect/Method.java b/luni-kernel/src/main/java/java/lang/reflect/Method.java
index dabf9a4..6678f8c 100644
--- a/luni-kernel/src/main/java/java/lang/reflect/Method.java
+++ b/luni-kernel/src/main/java/java/lang/reflect/Method.java
@@ -44,8 +44,6 @@
 /**
  * This class represents a method. Information about the method can be accessed,
  * and the method can be invoked dynamically.
- * 
- * @since Android 1.0
  */
 public final class Method extends AccessibleObject implements GenericDeclaration, Member {
     
@@ -134,8 +132,6 @@
      * the type parameters.
      *
      * @return the string representation of this method
-     * 
-     * @since Android 1.0
      */
     public String toGenericString() {
         StringBuilder sb = new StringBuilder(80);
@@ -194,8 +190,6 @@
      * @throws MalformedParameterizedTypeException
      *             if any parameter type points to a type that cannot be
      *             instantiated for some reason
-     * 
-     * @since Android 1.0
      */
     public Type[] getGenericParameterTypes() {
         initGenericTypes();
@@ -215,8 +209,6 @@
      * @throws MalformedParameterizedTypeException
      *             if any exception type points to a type that cannot be
      *             instantiated for some reason
-     * 
-     * @since Android 1.0
      */
     public Type[] getGenericExceptionTypes() {
         initGenericTypes();
@@ -235,8 +227,6 @@
      * @throws MalformedParameterizedTypeException
      *             if the return type points to a type that cannot be
      *             instantiated for some reason
-     * 
-     * @since Android 1.0
      */
     public Type getGenericReturnType() {
         initGenericTypes();
@@ -270,8 +260,6 @@
      * and array of empty arrays is returned.
      *
      * @return an array of arrays of {@code Annotation} instances
-     * 
-     * @since Android 1.0
      */
     public Annotation[][] getParameterAnnotations() {
         Annotation[][] parameterAnnotations
@@ -289,8 +277,6 @@
      * Indicates whether or not this method takes a variable number argument.
      *
      * @return {@code true} if a vararg is declared, {@code false} otherwise
-     * 
-     * @since Android 1.0
      */
     public boolean isVarArgs() {
         int modifiers = getMethodModifiers(declaringClass, slot);
@@ -301,8 +287,6 @@
      * Indicates whether or not this method is a bridge.
      *
      * @return {@code true} if this method is a bridge, {@code false} otherwise
-     * 
-     * @since Android 1.0
      */
     public boolean isBridge() {
         int modifiers = getMethodModifiers(declaringClass, slot);
@@ -313,8 +297,6 @@
      * Indicates whether or not this method is synthetic.
      *
      * @return {@code true} if this method is synthetic, {@code false} otherwise
-     * 
-     * @since Android 1.0
      */
     public boolean isSynthetic() {
         int modifiers = getMethodModifiers(declaringClass, slot);
@@ -330,8 +312,6 @@
      * @throws TypeNotPresentException
      *             if this annotation member is of type {@code Class} and no
      *             definition can be found
-     * 
-     * @since Android 1.0
      */
     public Object getDefaultValue() {
         return getDefaultValue(declaringClass, slot);
@@ -351,8 +331,6 @@
      *         method, {@code false} otherwise
      *         
      * @see #hashCode
-     * 
-     * @since Android 1.0
      */
     @Override
     public boolean equals(Object object) {
@@ -363,8 +341,6 @@
      * Returns the class that declares this method.
      *
      * @return the declaring class
-     * 
-     * @since Android 1.0
      */
     public Class<?> getDeclaringClass() {
         return declaringClass;
@@ -375,8 +351,6 @@
      * this method has no declared exceptions, an empty array is returned.
      * 
      * @return the declared exception classes
-     * 
-     * @since Android 1.0
      */
     public Class<?>[] getExceptionTypes() {
         if (exceptionTypes == null) {
@@ -393,8 +367,6 @@
      * @return the modifiers for this method
      * 
      * @see Modifier
-     * 
-     * @since Android 1.0
      */
     public int getModifiers() {
         return getMethodModifiers(declaringClass, slot);
@@ -407,8 +379,6 @@
      * instance.
      * 
      * @return the name of this method
-     * 
-     * @since Android 1.0
      */
     public String getName() {
         return name;
@@ -420,8 +390,6 @@
      * empty array will be returned.
      * 
      * @return the parameter types
-     * 
-     * @since Android 1.0
      */
     public Class<?>[] getParameterTypes() {
         return parameterTypes.clone();
@@ -432,8 +400,6 @@
      * method.
      * 
      * @return the return type
-     * 
-     * @since Android 1.0
      */
     public Class<?> getReturnType() {
         return returnType;
@@ -447,8 +413,6 @@
      * @return hash code for this method
      * 
      * @see #equals
-     * 
-     * @since Android 1.0
      */
     @Override
     public int hashCode() {
@@ -508,8 +472,6 @@
      *             if an exception was thrown by the invoked method
      * 
      * @see AccessibleObject
-     * 
-     * @since Android 1.0
      */
     public Object invoke(Object receiver, Object... args)
             throws IllegalAccessException, IllegalArgumentException,
@@ -546,8 +508,6 @@
      * ,InvocationTargetException}
      * 
      * @return a printable representation for this method
-     * 
-     * @since Android 1.0
      */
     @Override
     public String toString() {
diff --git a/luni-kernel/src/main/native/Register.cpp b/luni-kernel/src/main/native/Register.cpp
new file mode 100644
index 0000000..8980cc5
--- /dev/null
+++ b/luni-kernel/src/main/native/Register.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ScopedLocalFrame.h"
+
+namespace android {
+    extern int register_dalvik_system_TouchDex(JNIEnv* env);
+}
+
+extern int register_com_ibm_icu4jni_converters_NativeConverter(JNIEnv* env);
+extern int register_com_ibm_icu4jni_lang_UCharacter(JNIEnv* env);
+extern int register_com_ibm_icu4jni_regex_NativeRegEx(JNIEnv* env);
+extern int register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv* env);
+extern int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv* env);
+extern int register_com_ibm_icu4jni_text_NativeDecimalFormat(JNIEnv* env);
+extern int register_com_ibm_icu4jni_text_NativeIDN(JNIEnv* env);
+extern int register_com_ibm_icu4jni_text_NativeNormalizer(JNIEnv* env);
+extern int register_com_ibm_icu4jni_util_Resources(JNIEnv* env);
+extern int register_java_io_Console(JNIEnv* env);
+extern int register_java_io_File(JNIEnv* env);
+extern "C" int register_java_io_FileDescriptor(JNIEnv* env);
+extern "C" int register_java_io_ObjectInputStream(JNIEnv* env);
+extern "C" int register_java_io_ObjectOutputStream(JNIEnv* env);
+extern "C" int register_java_io_ObjectStreamClass(JNIEnv* env);
+extern "C" int register_java_lang_Double(JNIEnv* env);
+extern "C" int register_java_lang_Float(JNIEnv* env);
+extern "C" int register_java_lang_Math(JNIEnv* env);
+extern int register_java_lang_ProcessManager(JNIEnv* env);
+extern "C" int register_java_lang_StrictMath(JNIEnv* env);
+extern int register_java_lang_System(JNIEnv* env);
+extern int register_java_net_InetAddress(JNIEnv* env);
+extern int register_java_net_NetworkInterface(JNIEnv* env);
+extern "C" int register_java_util_zip_Adler32(JNIEnv* env);
+extern "C" int register_java_util_zip_CRC32(JNIEnv* env);
+extern "C" int register_java_util_zip_Deflater(JNIEnv* env);
+extern "C" int register_java_util_zip_Inflater(JNIEnv* env);
+extern "C" int register_org_apache_harmony_dalvik_NativeTestTarget(JNIEnv* env);
+extern int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv* env);
+extern int register_org_apache_harmony_luni_platform_OSMemory(JNIEnv* env);
+extern int register_org_apache_harmony_luni_platform_OSNetworkSystem(JNIEnv* env);
+extern "C" int register_org_apache_harmony_luni_util_NumberConvert(JNIEnv* env);
+extern "C" int register_org_apache_harmony_luni_util_fltparse(JNIEnv* env);
+extern int register_org_apache_harmony_text_BidiWrapper(JNIEnv* env);
+extern int register_org_apache_harmony_xml_ExpatParser(JNIEnv* env);
+extern int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env);
+extern "C" int register_org_openssl_NativeBN(JNIEnv* env);
+
+// DalvikVM calls this on startup, so we can statically register all our native methods.
+extern "C" int registerCoreLibrariesJni(JNIEnv* env) {
+    ScopedLocalFrame localFrame(env);
+
+    bool result =
+            register_com_ibm_icu4jni_converters_NativeConverter(env) != -1 &&
+            register_com_ibm_icu4jni_lang_UCharacter(env) != -1 &&
+            register_com_ibm_icu4jni_regex_NativeRegEx(env) != -1 &&
+            register_com_ibm_icu4jni_text_NativeBreakIterator(env) != -1 &&
+            register_com_ibm_icu4jni_text_NativeCollator(env) != -1 &&
+            register_com_ibm_icu4jni_text_NativeDecimalFormat(env) != -1 &&
+            register_com_ibm_icu4jni_text_NativeIDN(env) != -1 &&
+            register_com_ibm_icu4jni_text_NativeNormalizer(env) != -1 &&
+            register_com_ibm_icu4jni_util_Resources(env) != -1 &&
+            register_java_io_Console(env) != -1 &&
+            register_java_io_File(env) != -1 &&
+            register_java_io_FileDescriptor(env) != -1 &&
+            register_java_io_ObjectInputStream(env) != -1 &&
+            register_java_io_ObjectOutputStream(env) != -1 &&
+            register_java_io_ObjectStreamClass(env) != -1 &&
+            register_java_lang_Double(env) != -1 &&
+            register_java_lang_Float(env) != -1 &&
+            register_java_lang_Math(env) != -1 &&
+            register_java_lang_ProcessManager(env) != -1 &&
+            register_java_lang_StrictMath(env) != -1 &&
+            register_java_lang_System(env) != -1 &&
+            register_java_net_InetAddress(env) != -1 &&
+            register_java_net_NetworkInterface(env) != -1 &&
+            register_java_util_zip_Adler32(env) != -1 &&
+            register_java_util_zip_CRC32(env) != -1 &&
+            register_java_util_zip_Deflater(env) != -1 &&
+            register_java_util_zip_Inflater(env) != -1 &&
+            register_org_apache_harmony_luni_platform_OSFileSystem(env) != -1 &&
+            register_org_apache_harmony_luni_platform_OSMemory(env) != -1 &&
+            register_org_apache_harmony_luni_platform_OSNetworkSystem(env) != -1 &&
+            register_org_apache_harmony_luni_util_NumberConvert(env) != -1 &&
+            register_org_apache_harmony_luni_util_fltparse(env) != -1 &&
+            register_org_apache_harmony_text_BidiWrapper(env) != -1 &&
+            register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(env) != -1 &&
+            register_org_openssl_NativeBN(env) != -1 &&
+            // Initialize the Android classes last, as they have dependencies on the "corer" core classes.
+            android::register_dalvik_system_TouchDex(env) != -1 &&
+            register_org_apache_harmony_dalvik_NativeTestTarget(env) != -1 &&
+            register_org_apache_harmony_xml_ExpatParser(env) != -1;
+
+    return result ? 0 : -1;
+}
diff --git a/luni-kernel/src/main/native/java_lang_ProcessManager.cpp b/luni-kernel/src/main/native/java_lang_ProcessManager.cpp
index 045d980..666a8c7 100644
--- a/luni-kernel/src/main/native/java_lang_ProcessManager.cpp
+++ b/luni-kernel/src/main/native/java_lang_ProcessManager.cpp
@@ -29,7 +29,6 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "utils/Log.h"
-#include "AndroidSystemNatives.h"
 
 /** Environment variables. */
 extern char **environ;
@@ -415,8 +414,6 @@
     { "exec",             "([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Z)I",
                                                          (void*) java_lang_ProcessManager_exec },
 };
-
 int register_java_lang_ProcessManager(JNIEnv* env) {
-    return jniRegisterNativeMethods(
-            env, "java/lang/ProcessManager", methods, NELEM(methods));
+    return jniRegisterNativeMethods(env, "java/lang/ProcessManager", methods, NELEM(methods));
 }
diff --git a/luni-kernel/src/main/native/java_lang_System.cpp b/luni-kernel/src/main/native/java_lang_System.cpp
index 52150d3..b114dab 100644
--- a/luni-kernel/src/main/native/java_lang_System.cpp
+++ b/luni-kernel/src/main/native/java_lang_System.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include "AndroidSystemNatives.h"
 #include "JNIHelp.h"
 
 #include <stdlib.h>
@@ -84,17 +83,11 @@
     env->ReleaseStringUTFChars(sig, fieldSig);
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "getEnvByName",   "(Ljava/lang/String;)Ljava/lang/String;",                    (void*) java_getEnvByName  },
     { "getEnvByIndex",  "(I)Ljava/lang/String;",                                     (void*) java_getEnvByIndex },
     { "setFieldImpl",   "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", (void*) java_setFieldImpl },
 };
-
 int register_java_lang_System(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/lang/System",
-            gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods));
 }
diff --git a/luni-kernel/src/main/native/sub.mk b/luni-kernel/src/main/native/sub.mk
index fcb7d0d..7f6417b 100644
--- a/luni-kernel/src/main/native/sub.mk
+++ b/luni-kernel/src/main/native/sub.mk
@@ -4,7 +4,8 @@
 
 LOCAL_SRC_FILES := \
 	java_lang_ProcessManager.cpp \
-	java_lang_System.cpp
+	java_lang_System.cpp \
+	Register.cpp
 
 LOCAL_C_INCLUDES +=
 
diff --git a/luni-kernel/src/test/java/java/lang/reflect/AllTests.java b/luni-kernel/src/test/java/java/lang/reflect/AllTests.java
index 7cf1475..8d99672 100644
--- a/luni-kernel/src/test/java/java/lang/reflect/AllTests.java
+++ b/luni-kernel/src/test/java/java/lang/reflect/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(java.lang.reflect.ConstructorTest.class);
         suite.addTestSuite(java.lang.reflect.MethodTest.class);
         return suite;
diff --git a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java
index a59cc3e..e9cf80e 100644
--- a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java
+++ b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(tests.api.org.apache.harmony.kernel.dalvik.ThreadsTest.class);
         return suite;
     }
diff --git a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
index c24e297..8ba2445 100644
--- a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
+++ b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java
@@ -21,15 +21,10 @@
 import junit.framework.Assert;
 import junit.framework.TestCase;
 import sun.misc.Unsafe;
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 
 /**
  * Tests for the <code>park()</code> functionality of {@link Unsafe}.
  */
-@TestTargetClass(Unsafe.class)
 public class ThreadsTest extends TestCase {
     private static Unsafe UNSAFE = null;
     private static RuntimeException INITIALIZEFAILED = null;
@@ -54,13 +49,6 @@
     }
 
     /** Test the case where the park times out. */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "unpark",
-        args = {Object.class}
-    )    
-    @AndroidOnly("Accesses Android-specific private field")
     public void test_parkFor_1() {
         Parker parker = new Parker(false, 500);
         Thread parkerThread = new Thread(parker);
@@ -73,13 +61,6 @@
     }
 
     /** Test the case where the unpark happens before the timeout. */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "unpark",
-        args = {Object.class}
-    )    
-    @AndroidOnly("Accesses Android-specific private field")
     public void test_parkFor_2() {
         Parker parker = new Parker(false, 1000);
         Thread parkerThread = new Thread(parker);
@@ -92,13 +73,6 @@
     }
 
     /** Test the case where the thread is preemptively unparked. */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "unpark",
-        args = {Object.class}
-    )    
-    @AndroidOnly("Accesses Android-specific private field")
     public void test_parkFor_3() {
         Parker parker = new Parker(false, 1000);
         Thread parkerThread = new Thread(parker);
@@ -109,13 +83,6 @@
     }
 
     /** Test the case where the park times out. */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "unpark",
-        args = {Object.class}
-    )    
-    @AndroidOnly("Accesses Android-specific private field")
     public void test_parkUntil_1() {
         Parker parker = new Parker(true, 500);
         Thread parkerThread = new Thread(parker);
@@ -128,13 +95,6 @@
     }
 
     /** Test the case where the unpark happens before the timeout. */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "unpark",
-        args = {Object.class}
-    )    
-    @AndroidOnly("Accesses Android-specific private field")
     public void test_parkUntil_2() {
         Parker parker = new Parker(true, 1000);
         Thread parkerThread = new Thread(parker);
@@ -147,13 +107,6 @@
     }
 
     /** Test the case where the thread is preemptively unparked. */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "unpark",
-        args = {Object.class}
-    )    
-    @AndroidOnly("Accesses Android-specific private field")
     public void test_parkUntil_3() {
         Parker parker = new Parker(true, 1000);
         Thread parkerThread = new Thread(parker);
diff --git a/luni/src/main/java/java/io/BufferedInputStream.java b/luni/src/main/java/java/io/BufferedInputStream.java
index 6888a87..369e0d0 100644
--- a/luni/src/main/java/java/io/BufferedInputStream.java
+++ b/luni/src/main/java/java/io/BufferedInputStream.java
@@ -67,43 +67,22 @@
     protected int pos;
 
     /**
-     * Constructs a new {@code BufferedInputStream} on the {@link InputStream}
-     * {@code in}. The default buffer size (8 KB) is allocated and all reads
-     * can now be filtered through this stream.
+     * Constructs a new {@code BufferedInputStream}, providing {@code in} with a buffer
+     * of 8192 bytes.
      *
-     * @param in
-     *            the InputStream the buffer reads from.
+     * @param in the {@code InputStream} the buffer reads from.
      */
     public BufferedInputStream(InputStream in) {
-        super(in);
-        buf = new byte[8192];
-
-        // BEGIN android-added
-        /*
-         * For Android, we want to discourage the use of this constructor (with
-         * its arguably too-large default), so we note its use in the log. We
-         * don't disable it, nor do we alter the default, however, because we
-         * still aim to behave compatibly, and the default value, though not
-         * documented, is established by convention.
-         */
-        Logger.global.info(
-                "Default buffer size used in BufferedInputStream " +
-                "constructor. It would be " +
-                "better to be explicit if an 8k buffer is required.");
-        // END android-added
+        this(in, 8192);
     }
 
     /**
-     * Constructs a new {@code BufferedInputStream} on the {@link InputStream}
-     * {@code in}. The buffer size is specified by the parameter {@code size}
-     * and all reads are now filtered through this stream.
+     * Constructs a new {@code BufferedInputStream}, providing {@code in} with {@code size} bytes
+     * of buffer.
      *
-     * @param in
-     *            the input stream the buffer reads from.
-     * @param size
-     *            the size of buffer to allocate.
-     * @throws IllegalArgumentException
-     *             if {@code size < 0}.
+     * @param in the {@code InputStream} the buffer reads from.
+     * @param size the size of buffer in bytes.
+     * @throws IllegalArgumentException if {@code size <= 0}.
      */
     public BufferedInputStream(InputStream in, int size) {
         super(in);
diff --git a/luni/src/main/java/java/io/BufferedOutputStream.java b/luni/src/main/java/java/io/BufferedOutputStream.java
index d61e522..d255e27 100644
--- a/luni/src/main/java/java/io/BufferedOutputStream.java
+++ b/luni/src/main/java/java/io/BufferedOutputStream.java
@@ -51,42 +51,22 @@
     protected int count;
 
     /**
-     * Constructs a new {@code BufferedOutputStream} on the {@link OutputStream}
-     * {@code out}. The buffer size is set to the default value of 8 KB.
+     * Constructs a new {@code BufferedOutputStream}, providing {@code out} with a buffer
+     * of 8192 bytes.
      *
-     * @param out
-     *            the {@code OutputStream} for which write operations are
-     *            buffered.
+     * @param out the {@code OutputStream} the buffer writes to.
      */
     public BufferedOutputStream(OutputStream out) {
-        super(out);
-        buf = new byte[8192];
-
-        // BEGIN android-added
-        /*
-         * For Android, we want to discourage the use of this constructor (with
-         * its arguably too-large default), so we note its use in the log. We
-         * don't disable it, nor do we alter the default, however, because we
-         * still aim to behave compatibly, and the default value, though not
-         * documented, is established by convention.
-         */
-        Logger.global.info(
-                "Default buffer size used in BufferedOutputStream " +
-                "constructor. It would be " +
-                "better to be explicit if an 8k buffer is required.");
-        // END android-added
+        this(out, 8192);
     }
 
     /**
-     * Constructs a new {@code BufferedOutputStream} on the {@link OutputStream}
-     * {@code out}. The buffer size is set to {@code size}.
+     * Constructs a new {@code BufferedOutputStream}, providing {@code out} with {@code size} bytes
+     * of buffer.
      *
-     * @param out
-     *            the output stream for which write operations are buffered.
-     * @param size
-     *            the size of the buffer in bytes.
-     * @throws IllegalArgumentException
-     *             if {@code size <= 0}.
+     * @param out the {@code OutputStream} the buffer writes to.
+     * @param size the size of buffer in bytes.
+     * @throws IllegalArgumentException if {@code size <= 0}.
      */
     public BufferedOutputStream(OutputStream out, int size) {
         super(out);
diff --git a/luni/src/main/java/java/io/BufferedReader.java b/luni/src/main/java/java/io/BufferedReader.java
index 353f17c..356c4d7 100644
--- a/luni/src/main/java/java/io/BufferedReader.java
+++ b/luni/src/main/java/java/io/BufferedReader.java
@@ -75,43 +75,22 @@
     private int markLimit = -1;
 
     /**
-     * Constructs a new BufferedReader on the Reader {@code in}. The
-     * buffer gets the default size (8 KB).
-     * 
-     * @param in
-     *            the Reader that is buffered.
+     * Constructs a new {@code BufferedReader}, providing {@code in} with a buffer
+     * of 8192 characters.
+     *
+     * @param in the {@code Reader} the buffer reads from.
      */
     public BufferedReader(Reader in) {
-        super(in);
-        this.in = in;
-        buf = new char[8192];
-
-        // BEGIN android-only
-        /*
-         * For Android, we want to discourage the use of this
-         * constructor (with its arguably too-large default), so we
-         * note its use in the log. We don't disable it, nor do we
-         * alter the default, however, because we still aim to behave
-         * compatibly, and the default value, though not documented,
-         * is established by convention.
-         */
-        Logger.global.info(
-                "Default buffer size used in BufferedReader " +
-                "constructor. It would be " +
-                "better to be explicit if an 8k-char buffer is required.");
-        // END android-only
+        this(in, 8192);
     }
 
     /**
-     * Constructs a new BufferedReader on the Reader {@code in}. The buffer
-     * size is specified by the parameter {@code size}.
-     * 
-     * @param in
-     *            the Reader that is buffered.
-     * @param size
-     *            the size of the buffer to allocate.
-     * @throws IllegalArgumentException
-     *             if {@code size <= 0}.
+     * Constructs a new {@code BufferedReader}, providing {@code in} with {@code size} characters
+     * of buffer.
+     *
+     * @param in the {@code InputStream} the buffer reads from.
+     * @param size the size of buffer in characters.
+     * @throws IllegalArgumentException if {@code size <= 0}.
      */
     public BufferedReader(Reader in, int size) {
         super(in);
diff --git a/luni/src/main/java/java/io/BufferedWriter.java b/luni/src/main/java/java/io/BufferedWriter.java
index 39b20ba..1da93f8 100644
--- a/luni/src/main/java/java/io/BufferedWriter.java
+++ b/luni/src/main/java/java/io/BufferedWriter.java
@@ -55,44 +55,22 @@
             .doPrivileged(new PriviAction<String>("line.separator")); //$NON-NLS-1$
 
     /**
-     * Constructs a new {@code BufferedWriter} with {@code out} as the writer
-     * for which to buffer write operations. The buffer size is set to the
-     * default value of 8 KB.
+     * Constructs a new {@code BufferedWriter}, providing {@code out} with a buffer
+     * of 8192 bytes.
      *
-     * @param out
-     *            the writer for which character writing is buffered.
+     * @param out the {@code Writer} the buffer writes to.
      */
     public BufferedWriter(Writer out) {
-        super(out);
-        this.out = out;
-        buf = new char[8192];
-
-        // BEGIN android-added
-        /*
-         * For Android, we want to discourage the use of this constructor (with
-         * its arguably too-large default), so we note its use in the log. We
-         * don't disable it, nor do we alter the default, however, because we
-         * still aim to behave compatibly, and the default value, though not
-         * documented, is established by convention.
-         */
-        Logger.global.info(
-                "Default buffer size used in BufferedWriter " +
-                "constructor. It would be " +
-                "better to be explicit if an 8k-char buffer is required.");
-        // END android-added
+        this(out, 8192);
     }
 
     /**
-     * Constructs a new {@code BufferedWriter} with {@code out} as the writer
-     * for which to buffer write operations. The buffer size is set to {@code
-     * size}.
+     * Constructs a new {@code BufferedWriter}, providing {@code out} with {@code size} bytes
+     * of buffer.
      *
-     * @param out
-     *            the writer for which character writing is buffered.
-     * @param size
-     *            the size of the buffer in bytes.
-     * @throws IllegalArgumentException
-     *             if {@code size <= 0}.
+     * @param out the {@code OutputStream} the buffer writes to.
+     * @param size the size of buffer in bytes.
+     * @throws IllegalArgumentException if {@code size <= 0}.
      */
     public BufferedWriter(Writer out, int size) {
         super(out);
diff --git a/luni/src/main/java/java/io/Console.java b/luni/src/main/java/java/io/Console.java
new file mode 100644
index 0000000..1da92f0
--- /dev/null
+++ b/luni/src/main/java/java/io/Console.java
@@ -0,0 +1,208 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package java.io;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Formatter;
+
+/**
+ * Provides access to the console, if available. The system-wide instance can
+ * be accessed via {@link java.lang.System.console}.
+ * @since 1.6
+ * @hide
+ */
+public final class Console implements Flushable {
+    private static final Object CONSOLE_LOCK = new Object();
+
+    private static final Console console = makeConsole();
+    private static native boolean isatty(int fd);
+
+    private final ConsoleReader reader;
+    private final PrintWriter writer;
+
+    /**
+     * Secret accessor for {@code System.console}.
+     * @hide
+     */
+    public static Console getConsole() {
+        return console;
+    }
+
+    private static Console makeConsole() {
+        if (!isatty(0) || !isatty(1)) {
+            return null;
+        }
+        try {
+            return new Console();
+        } catch (IOException ex) {
+            throw new AssertionError(ex);
+        }
+    }
+
+    private Console() throws IOException {
+        this.reader = new ConsoleReader(System.in);
+        this.writer = new ConsoleWriter(System.out);
+    }
+
+    public void flush() {
+        writer.flush();
+    }
+
+    /**
+     * Writes a formatted string to the console using
+     * the specified format string and arguments.
+     *
+     * @param format the format string (see {@link java.util.Formatter#format})
+     * @param args
+     *            the list of arguments passed to the formatter. If there are
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
+     * @return the console instance.
+     */
+    public Console format(String format, Object... args) {
+        Formatter f = new Formatter(writer);
+        f.format(format, args);
+        f.flush();
+        return this;
+    }
+
+    /**
+     * Equivalent to {@code format(format, args)}.
+     */
+    public Console printf(String format, Object... args) {
+        return format(format, args);
+    }
+
+    /**
+     * Returns the {@link Reader} associated with this console.
+     */
+    public Reader reader() {
+        return reader;
+    }
+
+    /**
+     * Reads a line from the console.
+     *
+     * @return the line, or null at EOF.
+     */
+    public String readLine() {
+        try {
+            return reader.readLine();
+        } catch (IOException e) {
+            throw new IOError(e);
+        }
+    }
+
+    /**
+     * Reads a line from this console, using the specified prompt.
+     * The prompt is given as a format string and optional arguments.
+     * Note that this can be a source of errors: if it is possible that your
+     * prompt contains {@code %} characters, you must use the format string {@code "%s"}
+     * and pass the actual prompt as a parameter.
+     *
+     * @param format the format string (see {@link java.util.Formatter#format})
+     * @param args
+     *            the list of arguments passed to the formatter. If there are
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
+     * @return the line, or null at EOF.
+     */
+    public String readLine(String format, Object... args) {
+        synchronized (CONSOLE_LOCK) {
+            format(format, args);
+            return readLine();
+        }
+    }
+
+    /**
+     * Reads a password from the console. The password will not be echoed to the display.
+     *
+     * @return a character array containing the password, or null at EOF.
+     */
+    public char[] readPassword() {
+        synchronized (CONSOLE_LOCK) {
+            int previousState = setEcho(false, 0);
+            try {
+                String password = readLine();
+                writer.println(); // We won't have echoed the user's newline.
+                return (password == null) ? null : password.toCharArray();
+            } finally {
+                setEcho(true, previousState);
+            }
+        }
+    }
+
+    private static int setEcho(boolean on, int previousState) {
+        try {
+            return setEchoImpl(on, previousState);
+        } catch (IOException ex) {
+            throw new IOError(ex);
+        }
+    }
+    private static native int setEchoImpl(boolean on, int previousState) throws IOException;
+
+    /**
+     * Reads a password from the console. The password will not be echoed to the display.
+     * A formatted prompt is also displayed.
+     *
+     * @param format the format string (see {@link java.util.Formatter#format})
+     * @param args
+     *            the list of arguments passed to the formatter. If there are
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
+     * @return a character array containing the password, or null at EOF.
+     */
+    public char[] readPassword(String format, Object... args) {
+        synchronized (CONSOLE_LOCK) {
+            format(format, args);
+            return readPassword();
+        }
+    }
+
+    /**
+     * Returns the {@link Writer} associated with this console.
+     */
+    public PrintWriter writer() {
+        return writer;
+    }
+
+    private static class ConsoleReader extends BufferedReader {
+        public ConsoleReader(InputStream in) throws IOException {
+            super(new InputStreamReader(in, System.getProperty("file.encoding")), 256);
+            lock = CONSOLE_LOCK;
+        }
+
+        @Override
+        public void close() {
+            // Console.reader cannot be closed.
+        }
+    }
+
+    private static class ConsoleWriter extends PrintWriter {
+        public ConsoleWriter(OutputStream out) {
+            super(out, true);
+            lock = CONSOLE_LOCK;
+        }
+
+        @Override
+        public void close() {
+            // Console.writer cannot be closed.
+            flush();
+        }
+    }
+}
diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java
index 2910f91..a53b3c1 100644
--- a/luni/src/main/java/java/io/File.java
+++ b/luni/src/main/java/java/io/File.java
@@ -311,6 +311,33 @@
     }
 
     /**
+     * Tests whether or not this process is allowed to execute this file.
+     * Note that this is a best-effort result; the only way to be certain is
+     * to actually attempt the operation.
+     *
+     * @return {@code true} if this file can be executed, {@code false} otherwise.
+     * @throws SecurityException
+     *             If a security manager exists and
+     *             SecurityManager.checkExec(java.lang.String) disallows read
+     *             permission to this file object
+     * @see java.lang.SecurityManager#checkExec(String)
+     *
+     * @since 1.6
+     * @hide
+     */
+    public boolean canExecute() {
+        if (path.length() == 0) {
+            return false;
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkExec(path); // Seems bogus, but this is what the RI does.
+        }
+        return canExecuteImpl(pathBytes);
+    }
+    private native boolean canExecuteImpl(byte[] filePath);
+
+    /**
      * Indicates whether the current context is allowed to read from this file.
      *
      * @return {@code true} if this file can be read, {@code false} otherwise.
@@ -326,10 +353,9 @@
         if (security != null) {
             security.checkRead(path);
         }
-        return isReadableImpl(pathBytes);
+        return canReadImpl(pathBytes);
     }
-
-    private native boolean isReadableImpl(byte[] filePath);
+    private native boolean canReadImpl(byte[] filePath);
 
     /**
      * Indicates whether the current context is allowed to write to this file.
@@ -348,10 +374,9 @@
         if (security != null) {
             security.checkWrite(path);
         }
-        return isWritableImpl(pathBytes);
+        return canWriteImpl(pathBytes);
     }
-
-    private native boolean isWritableImpl(byte[] filePath);
+    private native boolean canWriteImpl(byte[] filePath);
 
     /**
      * Returns the relative sort ordering of the paths for this file and the
@@ -756,7 +781,7 @@
      * Indicates if this file's pathname is absolute. Whether a pathname is
      * absolute is platform specific. On Android, absolute paths start with
      * the character '/'.
-     * 
+     *
      * @return {@code true} if this file's pathname is absolute, {@code false}
      *         otherwise.
      * @see #getPath
@@ -887,16 +912,38 @@
     private native boolean setLastModifiedImpl(byte[] path, long time);
 
     /**
-     * Marks this file or directory to be read-only as defined by the operating
-     * system.
+     * Equivalent to setWritable(false, false).
      *
-     * @return {@code true} if the operation is successful, {@code false}
-     *         otherwise.
-     * @throws SecurityException
-     *             if a {@code SecurityManager} is installed and it denies write
-     *             access to this file.
+     * @see #setWritable(boolean, boolean)
      */
     public boolean setReadOnly() {
+        return setWritable(false, false);
+    }
+
+    /**
+     * Manipulates the execute permissions for the abstract path designated by
+     * this file.
+     *
+     * @param executable
+     *            To allow execute permission if true, otherwise disallow
+     * @param ownerOnly
+     *            To manipulate execute permission only for owner if true,
+     *            otherwise for everyone. The manipulation will apply to
+     *            everyone regardless of this value if the underlying system
+     *            does not distinguish owner and other users.
+     * @return true if and only if the operation succeeded. If the user does not
+     *         have permission to change the access permissions of this abstract
+     *         pathname the operation will fail. If the underlying file system
+     *         does not support execute permission and the value of executable
+     *         is false, this operation will fail.
+     * @throws SecurityException -
+     *             If a security manager exists and
+     *             SecurityManager.checkWrite(java.lang.String) disallows write
+     *             permission to this file object
+     * @since 1.6
+     * @hide
+     */
+    public boolean setExecutable(boolean executable, boolean ownerOnly) {
         if (path.length() == 0) {
             return false;
         }
@@ -904,10 +951,141 @@
         if (security != null) {
             security.checkWrite(path);
         }
-        return setReadOnlyImpl(pathBytes);
+        return setExecutableImpl(pathBytes, executable, ownerOnly);
     }
 
-    private native boolean setReadOnlyImpl(byte[] path);
+    /**
+     * Equivalent to setExecutable(executable, true).
+     *
+     * @param executable
+     *            To allow execute permission if true, otherwise disallow
+     * @return true if and only if the operation succeeded. If the user does not
+     *         have permission to change the access permissions of this abstract
+     *         pathname the operation will fail. If the underlying file system
+     *         does not support execute permission and the value of executable
+     *         is false, this operation will fail.
+     * @throws SecurityException -
+     *             If a security manager exists and
+     *             SecurityManager.checkWrite(java.lang.String) disallows write
+     *             permission to this file object
+     * @since 1.6
+     * @hide
+     */
+    public boolean setExecutable(boolean executable) {
+        return setExecutable(executable, true);
+    }
+
+    private native boolean setExecutableImpl(byte[] path, boolean executable, boolean ownerOnly);
+
+    /**
+     * Manipulates the read permissions for the abstract path designated by this
+     * file.
+     *
+     * @param readable
+     *            To allow read permission if true, otherwise disallow
+     * @param ownerOnly
+     *            To manipulate read permission only for owner if true,
+     *            otherwise for everyone. The manipulation will apply to
+     *            everyone regardless of this value if the underlying system
+     *            does not distinguish owner and other users.
+     * @return true if and only if the operation succeeded. If the user does not
+     *         have permission to change the access permissions of this abstract
+     *         pathname the operation will fail. If the underlying file system
+     *         does not support read permission and the value of readable is
+     *         false, this operation will fail.
+     * @throws SecurityException -
+     *             If a security manager exists and
+     *             SecurityManager.checkWrite(java.lang.String) disallows write
+     *             permission to this file object
+     * @since 1.6
+     * @hide
+     */
+    public boolean setReadable(boolean readable, boolean ownerOnly) {
+        if (path.length() == 0) {
+            return false;
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkWrite(path);
+        }
+        return setReadableImpl(pathBytes, readable, ownerOnly);
+    }
+
+    /**
+     * Equivalent to setReadable(readable, true).
+     *
+     * @param readable
+     *            To allow read permission if true, otherwise disallow
+     * @return true if and only if the operation succeeded. If the user does not
+     *         have permission to change the access permissions of this abstract
+     *         pathname the operation will fail. If the underlying file system
+     *         does not support read permission and the value of readable is
+     *         false, this operation will fail.
+     * @throws SecurityException -
+     *             If a security manager exists and
+     *             SecurityManager.checkWrite(java.lang.String) disallows write
+     *             permission to this file object
+     * @since 1.6
+     * @hide
+     */
+    public boolean setReadable(boolean readable) {
+        return setReadable(readable, true);
+    }
+
+    private native boolean setReadableImpl(byte[] path, boolean readable, boolean ownerOnly);
+
+    /**
+     * Manipulates the write permissions for the abstract path designated by this
+     * file.
+     *
+     * @param writable
+     *            To allow write permission if true, otherwise disallow
+     * @param ownerOnly
+     *            To manipulate write permission only for owner if true,
+     *            otherwise for everyone. The manipulation will apply to
+     *            everyone regardless of this value if the underlying system
+     *            does not distinguish owner and other users.
+     * @return true if and only if the operation succeeded. If the user does not
+     *         have permission to change the access permissions of this abstract
+     *         pathname the operation will fail.
+     * @throws SecurityException -
+     *             If a security manager exists and
+     *             SecurityManager.checkWrite(java.lang.String) disallows write
+     *             permission to this file object
+     * @since 1.6
+     * @hide
+     */
+    public boolean setWritable(boolean writable, boolean ownerOnly) {
+        if (path.length() == 0) {
+            return false;
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkWrite(path);
+        }
+        return setWritableImpl(pathBytes, writable, ownerOnly);
+    }
+
+    /**
+     * Equivalent to setWritable(writable, true).
+     *
+     * @param writable
+     *            To allow write permission if true, otherwise disallow
+     * @return true if and only if the operation succeeded. If the user does not
+     *         have permission to change the access permissions of this abstract
+     *         pathname the operation will fail.
+     * @throws SecurityException -
+     *             If a security manager exists and
+     *             SecurityManager.checkWrite(java.lang.String) disallows write
+     *             permission to this file object
+     * @since 1.6
+     * @hide
+     */
+    public boolean setWritable(boolean writable) {
+        return setWritable(writable, true);
+    }
+
+    private native boolean setWritableImpl(byte[] path, boolean writable, boolean ownerOnly);
 
     /**
      * Returns the length of this file in bytes.
@@ -1308,7 +1486,10 @@
      * @return a URL for this file.
      * @throws java.net.MalformedURLException
      *             if the path cannot be transformed into a URL.
+     * @deprecated use {@link #toURI} and {@link java.net.URI#toURL} to get
+     * correct escaping of illegal characters.
      */
+    @Deprecated
     @SuppressWarnings("nls")
     public URL toURL() throws java.net.MalformedURLException {
         String name = getAbsoluteName();
@@ -1343,10 +1524,67 @@
         stream.writeChar(separatorChar);
     }
 
-    private void readObject(ObjectInputStream stream) throws IOException,
-            ClassNotFoundException {
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         stream.defaultReadObject();
         char inSeparator = stream.readChar();
         init(path.replace(inSeparator, separatorChar));
     }
+
+    /**
+     * Returns the total size in bytes of the partition containing this path.
+     * Returns 0 if this path does not exist.
+     *
+     * @since 1.6
+     * @hide
+     */
+    public long getTotalSpace() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(new RuntimePermission("getFileSystemAttributes"));
+        }
+        return getTotalSpaceImpl(pathBytes);
+    }
+    private native long getTotalSpaceImpl(byte[] filePath);
+
+    /**
+     * Returns the number of usable free bytes on the partition containing this path.
+     * Returns 0 if this path does not exist.
+     *
+     * <p>Note that this is likely to be an optimistic over-estimate and should not
+     * be taken as a guarantee your application can actually write this many bytes.
+     * On Android (and other Unix-based systems), this method returns the number of free bytes
+     * available to non-root users, regardless of whether you're actually running as root,
+     * and regardless of any quota or other restrictions that might apply to the user.
+     * (The {@code getFreeSpace} method returns the number of bytes potentially available to root.)
+     *
+     * @since 1.6
+     * @hide
+     */
+    public long getUsableSpace() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(new RuntimePermission("getFileSystemAttributes"));
+        }
+        return getUsableSpaceImpl(pathBytes);
+    }
+    private native long getUsableSpaceImpl(byte[] filePath);
+
+    /**
+     * Returns the number of free bytes on the partition containing this path.
+     * Returns 0 if this path does not exist.
+     *
+     * <p>Note that this is likely to be an optimistic over-estimate and should not
+     * be taken as a guarantee your application can actually write this many bytes.
+     *
+     * @since 1.6
+     * @hide
+     */
+    public long getFreeSpace() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(new RuntimePermission("getFileSystemAttributes"));
+        }
+        return getFreeSpaceImpl(pathBytes);
+    }
+    private native long getFreeSpaceImpl(byte[] filePath);
 }
diff --git a/luni/src/main/java/java/io/FileInputStream.java b/luni/src/main/java/java/io/FileInputStream.java
index 6b91544..e8aed58 100644
--- a/luni/src/main/java/java/io/FileInputStream.java
+++ b/luni/src/main/java/java/io/FileInputStream.java
@@ -137,33 +137,7 @@
     @Override
     public int available() throws IOException {
         openCheck();
-
-        // BEGIN android-added
-
-        // Android always uses the ioctl() method of determining bytes
-        // available. See the long discussion in
-        // org_apache_harmony_luni_platform_OSFileSystem.cpp about its
-        // use.
-
-        return fileSystem.ioctlAvailable(fd.descriptor);
-        // END android-added
-
-        // BEGIN android-deleted
-        // synchronized (repositioningLock) {
-        //     // stdin requires special handling
-        //     if (fd == FileDescriptor.in) {
-        //         return (int) fileSystem.ttyAvailable();
-        //     }
-        //
-        //     long currentPosition = fileSystem.seek(fd.descriptor, 0L,
-        //             IFileSystem.SEEK_CUR);
-        //     long endOfFilePosition = fileSystem.seek(fd.descriptor, 0L,
-        //             IFileSystem.SEEK_END);
-        //     fileSystem.seek(fd.descriptor, currentPosition,
-        //             IFileSystem.SEEK_SET);
-        //     return (int) (endOfFilePosition - currentPosition);
-        // }
-        // END android-deleted
+        return fileSystem.ioctlAvailable(fd);
     }
 
     /**
diff --git a/luni/src/main/java/java/io/FileOutputStream.java b/luni/src/main/java/java/io/FileOutputStream.java
index ac76b97..912f2f4 100644
--- a/luni/src/main/java/java/io/FileOutputStream.java
+++ b/luni/src/main/java/java/io/FileOutputStream.java
@@ -34,8 +34,6 @@
  *
  * @see BufferedOutputStream
  * @see FileInputStream
- *
- * @since Android 1.0
  */
 public class FileOutputStream extends OutputStream implements Closeable {
 
diff --git a/luni/src/main/java/java/io/IOError.java b/luni/src/main/java/java/io/IOError.java
new file mode 100644
index 0000000..d47b93c
--- /dev/null
+++ b/luni/src/main/java/java/io/IOError.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.io;
+
+/**
+ * This error is thrown when a severe I/O error has happened.
+ * 
+ * @since 1.6
+ * @hide
+ */
+public class IOError extends Error {
+    private static final long serialVersionUID = 67100927991680413L;
+
+    /**
+     * Constructs a new instance with its cause filled in.
+     * 
+     * @param cause
+     *            The detail cause for the error.
+     */
+    public IOError(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/luni/src/main/java/java/io/IOException.java b/luni/src/main/java/java/io/IOException.java
index 24cea9f..fbd2048 100644
--- a/luni/src/main/java/java/io/IOException.java
+++ b/luni/src/main/java/java/io/IOException.java
@@ -37,11 +37,38 @@
     /**
      * Constructs a new {@code IOException} with its stack trace and detail
      * message filled in.
-     * 
+     *
      * @param detailMessage
      *            the detail message for this exception.
      */
     public IOException(String detailMessage) {
         super(detailMessage);
     }
+
+    /**
+     * Constructs a new instance of this class with detail message and cause
+     * filled in.
+     *
+     * @param message
+     *            The detail message for the exception.
+     * @param cause
+     *            The detail cause for the exception.
+     * @since 1.6
+     * @hide
+     */
+    public IOException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new instance of this class with its detail cause filled in.
+     *
+     * @param cause
+     *            The detail cause for the exception.
+     * @since 1.6
+     * @hide
+     */
+    public IOException(Throwable cause) {
+        super(cause == null ? null : cause.toString(), cause);
+    }
 }
diff --git a/luni/src/main/java/java/io/InputStreamReader.java b/luni/src/main/java/java/io/InputStreamReader.java
index 0b4de82..93581d4 100644
--- a/luni/src/main/java/java/io/InputStreamReader.java
+++ b/luni/src/main/java/java/io/InputStreamReader.java
@@ -44,13 +44,11 @@
 public class InputStreamReader extends Reader {
     private InputStream in;
 
-    private static final int BUFFER_SIZE = 8192;
-
     private boolean endOfInput = false;
 
-    CharsetDecoder decoder;
+    private CharsetDecoder decoder;
 
-    ByteBuffer bytes = ByteBuffer.allocate(BUFFER_SIZE);
+    private final ByteBuffer bytes = ByteBuffer.allocate(8192);
 
     /**
      * Constructs a new {@code InputStreamReader} on the {@link InputStream}
diff --git a/luni/src/main/java/java/io/ObjectInputStream.java b/luni/src/main/java/java/io/ObjectInputStream.java
index 9d79641a..8af16e8 100644
--- a/luni/src/main/java/java/io/ObjectInputStream.java
+++ b/luni/src/main/java/java/io/ObjectInputStream.java
@@ -22,6 +22,7 @@
 // yet migrated that API. As a consequence, there's a lot of changes here...
 // END android-note
 
+import dalvik.system.VMStack;
 import java.io.EmulatedFields.ObjectSlot;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
@@ -34,18 +35,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
-
-// BEGIN android-added
-import dalvik.system.VMStack;
-// END android-added
-
-// BEGIN android-removed
-// import org.apache.harmony.misc.accessors.ObjectAccessor;
-// import org.apache.harmony.misc.accessors.AccessorFactory;
-// END android-removed
-
 import org.apache.harmony.kernel.vm.VM;
-import org.apache.harmony.luni.internal.nls.Messages;
 import org.apache.harmony.luni.util.Msg;
 import org.apache.harmony.luni.util.PriviAction;
 
@@ -125,14 +115,14 @@
         new HashMap<String, Class<?>>();
 
     static {
-        PRIMITIVE_CLASSES.put("byte", byte.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("short", short.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("int", int.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("long", long.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("boolean", boolean.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("char", char.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("float", float.class); //$NON-NLS-1$
-        PRIMITIVE_CLASSES.put("double", double.class); //$NON-NLS-1$
+        PRIMITIVE_CLASSES.put("byte", byte.class);
+        PRIMITIVE_CLASSES.put("short", short.class);
+        PRIMITIVE_CLASSES.put("int", int.class);
+        PRIMITIVE_CLASSES.put("long", long.class);
+        PRIMITIVE_CLASSES.put("boolean", boolean.class);
+        PRIMITIVE_CLASSES.put("char", char.class);
+        PRIMITIVE_CLASSES.put("float", float.class);
+        PRIMITIVE_CLASSES.put("double", double.class);
     }
 
     // BEGIN android-removed
@@ -406,7 +396,7 @@
                             try {
                                 Method method = implementationClass
                                         .getMethod(
-                                                "readFields", //$NON-NLS-1$
+                                                "readFields",
                                                 ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
                                 if (method.getDeclaringClass() != thisClass) {
                                     return Boolean.TRUE;
@@ -416,7 +406,7 @@
                             try {
                                 Method method = implementationClass
                                         .getMethod(
-                                                "readUnshared", //$NON-NLS-1$
+                                                "readUnshared",
                                                 ObjectStreamClass.EMPTY_CONSTRUCTOR_PARAM_TYPES);
                                 if (method.getDeclaringClass() != thisClass) {
                                     return Boolean.TRUE;
@@ -694,11 +684,11 @@
         // Force buffer null check first!
         if (offset > buffer.length || offset < 0) {
             // K002e=Offset out of bounds \: {0}
-            throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset)); //$NON-NLS-1$
+            throw new ArrayIndexOutOfBoundsException(Msg.getString("K002e", offset));
         }
         if (length < 0 || length > buffer.length - offset) {
             // K0031=Length out of bounds \: {0}
-            throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length)); //$NON-NLS-1$
+            throw new ArrayIndexOutOfBoundsException(Msg.getString("K0031", length));
         }
         if (length == 0) {
             return 0;
@@ -838,7 +828,7 @@
                 return null;
             default:
                 throw new StreamCorruptedException(Msg.getString(
-                        "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
+                        "K00d2", Integer.toHexString(tc & 0xff)));
         }
     }
 
@@ -882,13 +872,13 @@
                 return null;
             case TC_EXCEPTION:
                 Exception exc = readException();
-                throw new WriteAbortedException(Msg.getString("K00d3"), exc); //$NON-NLS-1$
+                throw new WriteAbortedException(Msg.getString("K00d3"), exc);
             case TC_RESET:
                 resetState();
                 return null;
             default:
                 throw new StreamCorruptedException(Msg.getString(
-                        "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
+                        "K00d2", Integer.toHexString(tc & 0xff)));
         }
     }
 
@@ -936,14 +926,14 @@
                 case TC_REFERENCE:
                     if (unshared) {
                         readNewHandle();
-                        throw new InvalidObjectException(Msg.getString("KA002")); //$NON-NLS-1$
+                        throw new InvalidObjectException(Msg.getString("KA002"));
                     }
                     return readCyclicReference();
                 case TC_NULL:
                     return null;
                 case TC_EXCEPTION:
                     Exception exc = readException();
-                    throw new WriteAbortedException(Msg.getString("K00d3"), exc); //$NON-NLS-1$
+                    throw new WriteAbortedException(Msg.getString("K00d3"), exc);
                 case TC_RESET:
                     resetState();
                     break;
@@ -954,7 +944,7 @@
                     throw e;
                 default:
                     throw new StreamCorruptedException(Msg.getString(
-                            "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
+                            "K00d2", Integer.toHexString(tc & 0xff)));
             }
             // Only TC_RESET falls through
         } while (true);
@@ -1100,7 +1090,7 @@
             return classSig;
         }
 
-        while (classSig.startsWith("[L", start) //$NON-NLS-1$
+        while (classSig.startsWith("[L", start)
                 && classSig.charAt(end - 1) == ';') {
             start += 2;
             end--;
@@ -1282,7 +1272,7 @@
                             break;
                         default:
                             throw new StreamCorruptedException(Msg.getString(
-                                    "K00d5", fieldDesc.getTypeCode())); //$NON-NLS-1$
+                                    "K00d5", fieldDesc.getTypeCode()));
                     }
                     // END android-changed
                 } catch (NoSuchFieldError err) {
@@ -1319,9 +1309,9 @@
                         Class<?> valueType = toSet.getClass();
                         if (!fieldType.isAssignableFrom(valueType)) {
                             throw new ClassCastException(Msg.getString(
-                                    "K00d4", new String[] { //$NON-NLS-1$
+                                    "K00d4", new String[] {
                                     fieldType.toString(), valueType.toString(),
-                                            classDesc.getName() + "." //$NON-NLS-1$
+                                            classDesc.getName() + "."
                                                     + fieldName }));
                         }
                         try {
@@ -1625,7 +1615,7 @@
         ObjectStreamClass classDesc = readClassDesc();
 
         if (classDesc == null) {
-            throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
+            throw new InvalidClassException(Msg.getString("K00d1"));
         }
 
         Integer newHandle = nextHandle();
@@ -1683,7 +1673,7 @@
                 }
             } else {
                 throw new ClassNotFoundException(Msg.getString(
-                        "K00d7", classDesc.getName())); //$NON-NLS-1$
+                        "K00d7", classDesc.getName()));
             }
         } else {
             // Array of Objects
@@ -1727,7 +1717,7 @@
             }
             return localClass;
         }
-        throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
+        throw new InvalidClassException(Msg.getString("K00d1"));
     }
 
     /*
@@ -1746,7 +1736,7 @@
                 return null;
             default:
                 throw new StreamCorruptedException(Msg.getString(
-                        "K00d2", Integer.toHexString(tc & 0xff))); //$NON-NLS-1$
+                        "K00d2", Integer.toHexString(tc & 0xff)));
         }
     }
 
@@ -1769,7 +1759,7 @@
         if (0L != classDesc.getSerialVersionUID()
                 || 0L != superClass.getSerialVersionUID()) {
             throw new InvalidClassException(superClass.getName(), Msg
-                    .getString("K00da", superClass, //$NON-NLS-1$
+                    .getString("K00da", superClass,
                             superClass));
         }
         byte tc = nextTC();
@@ -1797,7 +1787,7 @@
             case TC_REFERENCE:
                 if (unshared) {
                     readNewHandle();
-                    throw new InvalidObjectException(Msg.getString("KA002")); //$NON-NLS-1$
+                    throw new InvalidObjectException(Msg.getString("KA002"));
                 }
                 name = (String) readCyclicReference();
                 break;
@@ -1904,14 +1894,11 @@
      * @throws IOException
      *             if an error occurs while reading from the source stream.
      */
-    protected ObjectStreamClass readClassDescriptor() throws IOException,
-            ClassNotFoundException {
-
+    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
         ObjectStreamClass newClassDesc = new ObjectStreamClass();
         String name = input.readUTF();
         if (name.length() == 0) {
-            // luni.07 = The stream is corrupted
-            throw new IOException(Messages.getString("luni.07")); //$NON-NLS-1$
+            throw new IOException("The stream is corrupted");
         }
         newClassDesc.setName(name);
         newClassDesc.setSerialVersionUID(input.readLong());
@@ -2008,7 +1995,7 @@
             // Has to have an empty constructor
             if (constructor == null) {
                 throw new InvalidClassException(constructorClass.getName(), Msg
-                        .getString("K00dc")); //$NON-NLS-1$
+                        .getString("K00dc"));
             }
 
             int constructorModifiers = constructor.getModifiers();
@@ -2019,7 +2006,7 @@
                     || (wasExternalizable && !Modifier
                             .isPublic(constructorModifiers))) {
                 throw new InvalidClassException(constructorClass.getName(), Msg
-                        .getString("K00dc")); //$NON-NLS-1$
+                        .getString("K00dc"));
             }
 
             // We know we are testing from a subclass, so the only other case
@@ -2032,7 +2019,7 @@
                 // visibility. Check if same package
                 if (!inSamePackage(constructorClass, objectClass)) {
                     throw new InvalidClassException(constructorClass.getName(),
-                            Msg.getString("K00dc")); //$NON-NLS-1$
+                            Msg.getString("K00dc"));
                 }
             }
 
@@ -2066,7 +2053,7 @@
         ObjectStreamClass classDesc = readClassDesc();
 
         if (classDesc == null) {
-            throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
+            throw new InvalidClassException(Msg.getString("K00d1"));
         }
 
         Integer newHandle = nextHandle();
@@ -2453,7 +2440,7 @@
         Object res = objectsRead.get(handle);
 
         if (res == UNSHARED_OBJ) {
-            throw new InvalidObjectException(Msg.getString("KA010")); //$NON-NLS-1$
+            throw new InvalidObjectException(Msg.getString("KA010"));
         }
 
         return res;
@@ -2506,7 +2493,7 @@
             throw new NotActiveException();
         }
         if (object == null) {
-            throw new InvalidObjectException(Msg.getString("K00d9")); //$NON-NLS-1$
+            throw new InvalidObjectException(Msg.getString("K00d9"));
         }
         // From now on it is just insertion in a SortedCollection. Since
         // the Java class libraries don't provide that, we have to
@@ -2721,7 +2708,7 @@
         if (loadedStreamClass.getSerialVersionUID() != localStreamClass
                 .getSerialVersionUID()) {
             throw new InvalidClassException(loadedStreamClass.getName(), Msg
-                    .getString("K00da", loadedStreamClass, //$NON-NLS-1$
+                    .getString("K00da", loadedStreamClass,
                             localStreamClass));
         }
 
@@ -2730,7 +2717,7 @@
 
         if (!loadedClassBaseName.equals(localClassBaseName)) {
             throw new InvalidClassException(loadedStreamClass.getName(), Msg
-                    .getString("KA015", loadedClassBaseName, //$NON-NLS-1$
+                    .getString("KA015", loadedClassBaseName,
                             localClassBaseName));
         }
 
diff --git a/luni/src/main/java/java/io/ObjectStreamClass.java b/luni/src/main/java/java/io/ObjectStreamClass.java
index ac356ea..5a99c8b 100644
--- a/luni/src/main/java/java/io/ObjectStreamClass.java
+++ b/luni/src/main/java/java/io/ObjectStreamClass.java
@@ -957,15 +957,14 @@
     }
 
     /**
-     * Returns the descriptor corresponding to the class {@code cl}. If the
-     * class is not serializable or externalizable then {@code null} is
-     * returned.
+     * Returns the descriptor for a serializable class.
+     * Returns null if the class doesn't implement {@code Serializable} or {@code Externalizable}.
      *
      * @param cl
-     *            a java.langClass for which to obtain the corresponding
+     *            a java.lang.Class for which to obtain the corresponding
      *            descriptor
-     * @return the corresponding descriptor if the {@code cl} is serializable or
-     *         externalizable; {@code null} otherwise.
+     * @return the corresponding descriptor if the class is serializable or
+     *         externalizable; null otherwise.
      */
     public static ObjectStreamClass lookup(Class<?> cl) {
         ObjectStreamClass osc = lookupStreamClass(cl);
@@ -978,6 +977,21 @@
     }
 
     /**
+     * Returns the descriptor for any class, whether or not the class
+     * implements Serializable or Externalizable.
+     * 
+     * @param cl
+     *            a java.lang.Class for which to obtain the corresponding
+     *            descriptor
+     * @return the descriptor
+     * @since 1.6
+     * @hide
+     */
+    public static ObjectStreamClass lookupAny(Class<?> cl) {
+        return  lookupStreamClass(cl);
+    }
+
+    /**
      * Return the descriptor (ObjectStreamClass) corresponding to the class
      * {@code cl}. Returns an ObjectStreamClass even if instances of the
      * class cannot be serialized
diff --git a/luni/src/main/java/java/io/ObjectStreamField.java b/luni/src/main/java/java/io/ObjectStreamField.java
index 3baebf7..ae642df 100644
--- a/luni/src/main/java/java/io/ObjectStreamField.java
+++ b/luni/src/main/java/java/io/ObjectStreamField.java
@@ -134,6 +134,7 @@
         }
         this.name = name;
         this.typeString = signature.replace('.', '/').intern();
+        defaultResolve();
         this.isDeserialized = true;
     }
 
@@ -348,34 +349,17 @@
     }
 
     void resolve(ClassLoader loader) {
+        if (typeString == null && isPrimitive()){
+            // primitive type declared in a serializable class
+            typeString = String.valueOf(getTypeCode());
+        }
+
         if (typeString.length() == 1) {
-            switch (typeString.charAt(0)) {
-                case 'I':
-                    type = Integer.TYPE;
-                    return;
-                case 'B':
-                    type = Byte.TYPE;
-                    return;
-                case 'C':
-                    type = Character.TYPE;
-                    return;
-                case 'S':
-                    type = Short.TYPE;
-                    return;
-                case 'Z':
-                    type = Boolean.TYPE;
-                    return;
-                case 'J':
-                    type = Long.TYPE;
-                    return;
-                case 'F':
-                    type = Float.TYPE;
-                    return;
-                case 'D':
-                    type = Double.TYPE;
-                    return;
+            if (defaultResolve()) {
+                return;
             }
         }
+
         String className = typeString.replace('/', '.');
         if (className.charAt(0) == 'L') {
             // remove L and ;
@@ -383,15 +367,14 @@
         }
         try {
             Class<?> cl = Class.forName(className, false, loader);
-            type = (cl.getClassLoader() == null) ? cl
-                    : new WeakReference<Class<?>>(cl);
+            type = (cl.getClassLoader() == null) ? cl : new WeakReference<Class<?>>(cl);
         } catch (ClassNotFoundException e) {
             // Ignored
         }
     }
 
     /**
-     * Indicats whether this field is unshared.
+     * Indicates whether this field is unshared.
      *
      * @return {@code true} if this field is unshared, {@code false} otherwise.
      */
@@ -402,4 +385,40 @@
     void setUnshared(boolean unshared) {
         this.unshared = unshared;
     }
+
+    /**
+     * Resolves typeString into type. Returns true if the type is primitive
+     * and false otherwise.
+     */
+    private boolean defaultResolve() {
+        switch (typeString.charAt(0)) {
+        case 'I':
+            type = Integer.TYPE;
+            return true;
+        case 'B':
+            type = Byte.TYPE;
+            return true;
+        case 'C':
+            type = Character.TYPE;
+            return true;
+        case 'S':
+            type = Short.TYPE;
+            return true;
+        case 'Z':
+            type = Boolean.TYPE;
+            return true;
+        case 'J':
+            type = Long.TYPE;
+            return true;
+        case 'F':
+            type = Float.TYPE;
+            return true;
+        case 'D':
+            type = Double.TYPE;
+            return true;
+        default:
+            type = Object.class;
+            return false;
+        }
+    }
 }
diff --git a/luni/src/main/java/java/io/OutputStreamWriter.java b/luni/src/main/java/java/io/OutputStreamWriter.java
index 226eea3..e5b4e71 100644
--- a/luni/src/main/java/java/io/OutputStreamWriter.java
+++ b/luni/src/main/java/java/io/OutputStreamWriter.java
@@ -41,7 +41,7 @@
  */
 public class OutputStreamWriter extends Writer {
 
-    private OutputStream out;
+    private final OutputStream out;
 
     private CharsetEncoder encoder;
 
diff --git a/luni/src/main/java/java/io/PipedInputStream.java b/luni/src/main/java/java/io/PipedInputStream.java
index 025d6b1..0f4ed0a 100644
--- a/luni/src/main/java/java/io/PipedInputStream.java
+++ b/luni/src/main/java/java/io/PipedInputStream.java
@@ -59,7 +59,7 @@
      * {@code in == out}. Writing when the buffer is full will block until free
      * space is available.
      */
-    protected byte buffer[];
+    protected byte[] buffer;
 
     /**
      * The index in {@code buffer} where the next byte will be written.
@@ -103,6 +103,40 @@
     }
 
     /**
+     * Constructs a new unconnected {@code PipedInputStream} with the given
+     * buffer size. The resulting stream must be connected to a
+     * {@code PipedOutputStream} before data may be read from it.
+     * 
+     * @param pipeSize the size of the buffer in bytes.
+     * @throws IllegalArgumentException if pipeSize is less than or equal to zero.
+     * @since 1.6
+     * @hide
+     */
+    public PipedInputStream(int pipeSize) {
+        if (pipeSize <= 0) {
+            throw new IllegalArgumentException("pipe size " + pipeSize + " too small");
+        }
+        buffer = new byte[pipeSize];
+    }
+
+    /**
+     * Constructs a new {@code PipedInputStream} connected to the given {@code PipedOutputStream},
+     * with the given buffer size. Any data written to the output stream can be read from this
+     * input stream.
+     * 
+     * @param out the {@code PipedOutputStream} to connect to.
+     * @param pipeSize the size of the buffer in bytes.
+     * @throws IOException if an I/O error occurs.
+     * @throws IllegalArgumentException if pipeSize is less than or equal to zero.
+     * @since 1.6
+     * @hide
+     */
+    public PipedInputStream(PipedOutputStream out, int pipeSize) throws IOException {
+        this(pipeSize);
+        connect(out);
+    }
+
+    /**
      * {@inheritDoc}
      *
      * <p>Unlike most streams, {@code PipedInputStream} returns 0 rather than throwing
@@ -156,7 +190,9 @@
         if (isConnected) {
             throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
         }
-        buffer = new byte[PipedInputStream.PIPE_SIZE];
+        if (buffer == null) { // We may already have allocated the buffer.
+            buffer = new byte[PipedInputStream.PIPE_SIZE];
+        }
         isConnected = true;
     }
 
diff --git a/luni/src/main/java/java/io/PipedReader.java b/luni/src/main/java/java/io/PipedReader.java
index d137a0d..29319fa 100644
--- a/luni/src/main/java/java/io/PipedReader.java
+++ b/luni/src/main/java/java/io/PipedReader.java
@@ -103,6 +103,40 @@
     }
 
     /**
+     * Constructs a new unconnected {@code PipedReader} with the given buffer size.
+     * The resulting reader must be connected to a {@code PipedWriter} before
+     * data may be read from it.
+     * 
+     * @param pipeSize the size of the buffer in chars.
+     * @throws IllegalArgumentException if pipeSize is less than or equal to zero.
+     * @since 1.6
+     * @hide
+     */
+    public PipedReader(int pipeSize) {
+        if (pipeSize <= 0) {
+            throw new IllegalArgumentException("pipe size " + pipeSize + " too small");
+        }
+        buffer = new char[pipeSize];
+    }
+
+    /**
+     * Constructs a new {@code PipedReader} connected to the given {@code PipedWriter},
+     * with the given buffer size. Any data written to the writer can be read from
+     * this reader.
+     * 
+     * @param out the {@code PipedWriter} to connect to.
+     * @param pipeSize the size of the buffer in chars.
+     * @throws IOException if an I/O error occurs
+     * @throws IllegalArgumentException if pipeSize is less than or equal to zero.
+     * @since 1.6
+     * @hide
+     */
+    public PipedReader(PipedWriter out, int pipeSize) throws IOException {
+        this(pipeSize);
+        connect(out);
+    }
+
+    /**
      * Closes this reader. This implementation releases the buffer used for
      * the pipe and notifies all threads waiting to read or write.
      *
@@ -112,6 +146,7 @@
     @Override
     public synchronized void close() throws IOException {
         buffer = null;
+        isClosed = true;
         notifyAll();
     }
 
@@ -139,7 +174,9 @@
         if (isConnected) {
             throw new IOException(Msg.getString("K007a")); //$NON-NLS-1$
         }
-        buffer = new char[PIPE_SIZE];
+        if (buffer == null) { // We may already have allocated the buffer.
+            buffer = new char[PIPE_SIZE];
+        }
         isConnected = true;
     }
 
diff --git a/luni/src/main/java/java/io/PrintStream.java b/luni/src/main/java/java/io/PrintStream.java
index 0f30147..962b58f 100644
--- a/luni/src/main/java/java/io/PrintStream.java
+++ b/luni/src/main/java/java/io/PrintStream.java
@@ -242,6 +242,15 @@
     }
 
     /**
+     * Sets the error state of the stream to false.
+     * @since 1.6
+     * @hide
+     */
+    protected void clearError() {
+        ioError = false;
+    }
+
+    /**
      * Closes this print stream. Flushes this stream and then closes the target
      * stream. If an I/O error occurs, this stream's error state is set to
      * {@code true}.
@@ -278,24 +287,21 @@
     }
 
     /**
-     * Writes a string formatted by an intermediate {@code Formatter} to the
-     * target stream using the specified format string and arguments. For the
-     * locale, the default value of the current virtual machine instance is
-     * used.
+     * Formats {@code args} according to the format string {@code format}, and writes the result
+     * to this stream. This method uses the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      *
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this stream.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintStream format(String format, Object... args) {
         return format(Locale.getDefault(), format, args);
@@ -308,19 +314,17 @@
      * @param l
      *            the locale used in the method. No localization will be applied
      *            if {@code l} is {@code null}.
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this stream.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintStream format(Locale l, String format, Object... args) {
         if (format == null) {
@@ -335,20 +339,17 @@
      * this stream's {@code #format(String, Object...)} method. For the locale,
      * the default value of the current virtual machine instance is used.
      *
-     * @param format
-     *            the format string used for
-     *            {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this stream.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintStream printf(String format, Object... args) {
         return format(format, args);
@@ -361,19 +362,17 @@
      * @param l
      *            the locale used in the method. No localization will be applied
      *            if {@code l} is {@code null}.
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this stream.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}.
      */
     public PrintStream printf(Locale l, String format, Object... args) {
         return format(l, format, args);
@@ -579,7 +578,6 @@
      * @param inum
      *            the integer value to print to the target stream.
      * @see #print(String)
-     * @since Android 1.0
      */
     public void println(int inum) {
         println(String.valueOf(inum));
@@ -592,7 +590,6 @@
      * @param lnum
      *            the long value to print to the target stream.
      * @see #print(String)
-     * @since Android 1.0
      */
     public void println(long lnum) {
         println(String.valueOf(lnum));
@@ -605,7 +602,6 @@
      * @param obj
      *            the object to print to the target stream.
      * @see #print(String)
-     * @since Android 1.0
      */
     public void println(Object obj) {
         println(String.valueOf(obj));
@@ -623,7 +619,6 @@
      * @param str
      *            the string to print to the target stream.
      * @see #write(int)
-     * @since Android 1.0
      */
     public synchronized void println(String str) {
         print(str);
@@ -643,7 +638,7 @@
     }
 
     /**
-     * Sets the error flag of this print stream to {@code true}.
+     * Sets the error flag of this print stream to true.
      */
     protected void setError() {
         ioError = true;
diff --git a/luni/src/main/java/java/io/PrintWriter.java b/luni/src/main/java/java/io/PrintWriter.java
index 3b6bb9c..650c61d 100644
--- a/luni/src/main/java/java/io/PrintWriter.java
+++ b/luni/src/main/java/java/io/PrintWriter.java
@@ -134,12 +134,7 @@
      *             target file.
      */
     public PrintWriter(File file) throws FileNotFoundException {
-        // BEGIN android-modified
-        this(new OutputStreamWriter(
-                     new BufferedOutputStream(
-                             new FileOutputStream(file), 8192)),
-                false);
-        // END android-modified
+        this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file))), false);
     }
 
     /**
@@ -165,12 +160,8 @@
      */
     public PrintWriter(File file, String csn) throws FileNotFoundException,
             UnsupportedEncodingException {
-        // BEGIN android-modified
-        this(new OutputStreamWriter(
-                     new BufferedOutputStream(
-                             new FileOutputStream(file), 8192), csn),
+        this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file)), csn),
                 false);
-        // END android-modified
     }
 
     /**
@@ -190,12 +181,8 @@
      *             target file.
      */
     public PrintWriter(String fileName) throws FileNotFoundException {
-        // BEGIN android-modified
-        this(new OutputStreamWriter(
-                     new BufferedOutputStream(
-                             new FileOutputStream(fileName), 8192)),
+        this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(fileName))),
                 false);
-        // END android-modified
     }
 
      /**
@@ -222,12 +209,8 @@
      */
     public PrintWriter(String fileName, String csn)
             throws FileNotFoundException, UnsupportedEncodingException {
-        // BEGIN android-modified
-        this(new OutputStreamWriter(
-                     new BufferedOutputStream(
-                             new FileOutputStream(fileName), 8192), csn),
+        this(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(fileName)), csn),
                 false);
-        // END android-modified
     }
 
     /**
@@ -249,6 +232,17 @@
     }
 
     /**
+     * Sets the error state of the stream to false.
+     * @since 1.6
+     * @hide
+     */
+    protected void clearError() {
+        synchronized (lock) {
+            ioError = false;
+        }
+    }
+
+    /**
      * Closes this print writer. Flushes this writer and then closes the target.
      * If an I/O error occurs, this writer's error flag is set to {@code true}.
      */
@@ -287,24 +281,22 @@
     }
 
     /**
-     * Writes a string formatted by an intermediate {@code Formatter} to the
-     * target using the specified format string and arguments. For the locale,
-     * the default value of the current virtual machine instance is used. If
-     * automatic flushing is enabled then the buffer is flushed as well.
+     * Formats {@code args} according to the format string {@code format}, and writes the result
+     * to this stream. This method uses the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * If automatic flushing is enabled then the buffer is flushed as well.
      *
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this writer.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintWriter format(String format, Object... args) {
         return format(Locale.getDefault(), format, args);
@@ -318,19 +310,17 @@
      * @param l
      *            the locale used in the method. No localization will be applied
      *            if {@code l} is {@code null}.
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this writer.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintWriter format(Locale l, String format, Object... args) {
         if (format == null) {
@@ -348,19 +338,17 @@
      * this writer's {@code #format(String, Object...)} method. For the locale,
      * the default value of the current virtual machine instance is used.
      *
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this writer.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintWriter printf(String format, Object... args) {
         return format(format, args);
@@ -373,19 +361,17 @@
      * @param l
      *            the locale used in the method. No localization will be applied
      *            if {@code l} is {@code null}.
-     * @param format
-     *            the format string used for {@link java.util.Formatter#format}.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
      *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by the {@code format} string,
-     *            then the additional arguments are ignored.
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return this writer.
      * @throws IllegalFormatException
      *             if the format string is illegal or incompatible with the
      *             arguments, if there are not enough arguments or if any other
      *             error regarding the format string or arguments is detected.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      */
     public PrintWriter printf(Locale l, String format, Object... args) {
         return format(l, format, args);
@@ -635,7 +621,7 @@
     }
 
     /**
-     * Sets the error flag of this writer to {@code true}.
+     * Sets the error flag of this writer to true.
      */
     protected void setError() {
         synchronized (lock) {
diff --git a/luni/src/main/java/java/io/SerializablePermission.java b/luni/src/main/java/java/io/SerializablePermission.java
index 7ff6524..8e385f0 100644
--- a/luni/src/main/java/java/io/SerializablePermission.java
+++ b/luni/src/main/java/java/io/SerializablePermission.java
@@ -35,8 +35,6 @@
  * </table>
  * 
  * @see ObjectStreamConstants
- * 
- * @since Android 1.0
  */
 public final class SerializablePermission extends BasicPermission {
     private static final long serialVersionUID = 8537212141160296410L;
@@ -50,7 +48,6 @@
      * 
      * @param permissionName
      *            the name of the new permission.
-     * @since Android 1.0
      */
     public SerializablePermission(String permissionName) {
         super(permissionName);
@@ -64,7 +61,6 @@
      *            the name of the new permission.
      * @param actions
      *            ignored.
-     * @since Android 1.0
      */
     public SerializablePermission(String name, String actions) {
         super(name, actions);
diff --git a/luni/src/main/java/java/io/package.html b/luni/src/main/java/java/io/package.html
index c3daed5..d074aa0 100644
--- a/luni/src/main/java/java/io/package.html
+++ b/luni/src/main/java/java/io/package.html
@@ -10,7 +10,5 @@
       unbuffered. And on top of that there are classes that help to abstract
       data streams as streams of chars, strings or even objects.
     </p>
-    
-    @since Android 1.0
   </body>
 </html>
diff --git a/luni/src/main/java/java/lang/CaseMapper.java b/luni/src/main/java/java/lang/CaseMapper.java
index c74bda0..f2f5ac8 100644
--- a/luni/src/main/java/java/lang/CaseMapper.java
+++ b/luni/src/main/java/java/lang/CaseMapper.java
@@ -16,18 +16,17 @@
 
 package java.lang;
 
+import com.ibm.icu4jni.lang.UCharacter;
 import java.util.Locale;
 
 /**
  * Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html.
  */
 class CaseMapper {
-    // Intention-revealing constants for various important characters.
-    private static final char LATIN_CAPITAL_I = 'I';
-    private static final char LATIN_SMALL_I = 'i';
+    private static final char[] upperValues = "SS\u0000\u02bcN\u0000J\u030c\u0000\u0399\u0308\u0301\u03a5\u0308\u0301\u0535\u0552\u0000H\u0331\u0000T\u0308\u0000W\u030a\u0000Y\u030a\u0000A\u02be\u0000\u03a5\u0313\u0000\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5\u0313\u0342\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1fba\u0399\u0000\u0391\u0399\u0000\u0386\u0399\u0000\u0391\u0342\u0000\u0391\u0342\u0399\u0391\u0399\u0000\u1fca\u0399\u0000\u0397\u0399\u0000\u0389\u0399\u0000\u0397\u0342\u0000\u0397\u0342\u0399\u0397\u0399\u0000\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0000\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313\u0000\u03a5\u0342\u0000\u03a5\u0308\u0342\u1ffa\u0399\u0000\u03a9\u0399\u0000\u038f\u0399\u0000\u03a9\u0342\u0000\u03a9\u0342\u0399\u03a9\u0399\u0000FF\u0000FI\u0000FL\u0000FFIFFLST\u0000ST\u0000\u0544\u0546\u0000\u0544\u0535\u0000\u0544\u053b\u0000\u054e\u0546\u0000\u0544\u053d\u0000".toCharArray();
+    private static final char[] upperValues2 = "\u000b\u0000\f\u0000\r\u0000\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>\u0000\u0000?@A\u0000BC\u0000\u0000\u0000\u0000D\u0000\u0000\u0000\u0000\u0000EFG\u0000HI\u0000\u0000\u0000\u0000J\u0000\u0000\u0000\u0000\u0000KL\u0000\u0000MN\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000OPQ\u0000RS\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000TUV\u0000WX\u0000\u0000\u0000\u0000Y".toCharArray();
+    
     private static final char LATIN_CAPITAL_I_WITH_DOT = '\u0130';
-    private static final char LATIN_SMALL_DOTLESS_I = '\u0131';
-    private static final char COMBINING_DOT_ABOVE = '\u0307';
     private static final char GREEK_CAPITAL_SIGMA = '\u03a3';
     private static final char GREEK_SMALL_FINAL_SIGMA = '\u03c2';
     
@@ -45,20 +44,20 @@
      * accessible.
      */
     public static String toLowerCase(Locale locale, String s, char[] value, int offset, int count) {
+        // Punt hard cases to ICU4C.
         String languageCode = locale.getLanguage();
-        boolean turkishOrAzeri = languageCode.equals("tr") || languageCode.equals("az");
+        if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
+            return UCharacter.toLowerCase(s, locale.toString());
+        }
         
         char[] newValue = null;
         int newCount = 0;
         for (int i = offset, end = offset + count; i < end; ++i) {
             char ch = value[i];
             char newCh = ch;
-            if (turkishOrAzeri && ch == LATIN_CAPITAL_I_WITH_DOT) {
-                newCh = LATIN_SMALL_I;
-            } else if (turkishOrAzeri && ch == LATIN_CAPITAL_I && !followedBy(value, offset, count, i, COMBINING_DOT_ABOVE)) {
-                newCh = LATIN_SMALL_DOTLESS_I;
-            } else if (turkishOrAzeri && ch == COMBINING_DOT_ABOVE && precededBy(value, offset, count, i, LATIN_CAPITAL_I)) {
-                continue; // (We've already converted the preceding I, so we don't need to create newValue.)
+            if (ch == LATIN_CAPITAL_I_WITH_DOT || Character.isHighSurrogate(ch)) {
+                // Punt these hard cases.
+                return UCharacter.toLowerCase(s, locale.toString());
             } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(value, offset, count, i)) {
                 newCh = GREEK_SMALL_FINAL_SIGMA;
             } else {
@@ -108,4 +107,102 @@
         }
         return true;
     }
+    
+    /**
+     * Return the index of the specified character into the upperValues table.
+     * The upperValues table contains three entries at each position. These
+     * three characters are the upper case conversion. If only two characters
+     * are used, the third character in the table is \u0000.
+     * @return the index into the upperValues table, or -1
+     */
+    private static int upperIndex(int ch) {
+        int index = -1;
+        if (ch >= 0xdf) {
+            if (ch <= 0x587) {
+                switch (ch) {
+                case 0xdf: return 0;
+                case 0x149: return 1;
+                case 0x1f0: return 2;
+                case 0x390: return 3;
+                case 0x3b0: return 4;
+                case 0x587: return 5;
+                }
+            } else if (ch >= 0x1e96) {
+                if (ch <= 0x1e9a) {
+                    index = 6 + ch - 0x1e96;
+                } else if (ch >= 0x1f50 && ch <= 0x1ffc) {
+                    index = upperValues2[ch - 0x1f50];
+                    if (index == 0) {
+                        index = -1;
+                    }
+                } else if (ch >= 0xfb00) {
+                    if (ch <= 0xfb06) {
+                        index = 90 + ch - 0xfb00;
+                    } else if (ch >= 0xfb13 && ch <= 0xfb17) {
+                        index = 97 + ch - 0xfb13;
+                    }
+                }
+            }
+        }
+        return index;
+    }
+    
+    public static String toUpperCase(Locale locale, String s, char[] value, int offset, int count) {
+        String languageCode = locale.getLanguage();
+        if (languageCode.equals("tr") || languageCode.equals("az") || languageCode.equals("lt")) {
+            return UCharacter.toUpperCase(s, locale.toString());
+        }
+        
+        char[] output = null;
+        int i = 0;
+        for (int o = offset, end = offset + count; o < end; o++) {
+            char ch = value[o];
+            if (Character.isHighSurrogate(ch)) {
+                return UCharacter.toUpperCase(s, locale.toString());
+            }
+            int index = upperIndex(ch);
+            if (index == -1) {
+                if (output != null && i >= output.length) {
+                    char[] newoutput = new char[output.length + (count / 6) + 2];
+                    System.arraycopy(output, 0, newoutput, 0, output.length);
+                    output = newoutput;
+                }
+                char upch = Character.toUpperCase(ch);
+                if (ch != upch) {
+                    if (output == null) {
+                        output = new char[count];
+                        i = o - offset;
+                        System.arraycopy(value, offset, output, 0, i);
+                    }
+                    output[i++] = upch;
+                } else if (output != null) {
+                    output[i++] = ch;
+                }
+            } else {
+                int target = index * 3;
+                char val3 = upperValues[target + 2];
+                if (output == null) {
+                    output = new char[count + (count / 6) + 2];
+                    i = o - offset;
+                    System.arraycopy(value, offset, output, 0, i);
+                } else if (i + (val3 == 0 ? 1 : 2) >= output.length) {
+                    char[] newoutput = new char[output.length + (count / 6) + 3];
+                    System.arraycopy(output, 0, newoutput, 0, output.length);
+                    output = newoutput;
+                }
+                
+                char val = upperValues[target];
+                output[i++] = val;
+                val = upperValues[target + 1];
+                output[i++] = val;
+                if (val3 != 0) {
+                    output[i++] = val3;
+                }
+            }
+        }
+        if (output == null) {
+            return s;
+        }
+        return output.length == i || output.length - i < 8 ? new String(0, i, output) : new String(output, 0, i);
+    }
 }
diff --git a/luni/src/main/java/java/lang/Cloneable.java b/luni/src/main/java/java/lang/Cloneable.java
index eb702f0..d67e070 100644
--- a/luni/src/main/java/java/lang/Cloneable.java
+++ b/luni/src/main/java/java/lang/Cloneable.java
@@ -26,7 +26,6 @@
  * 
  * @see Object#clone
  * @see CloneNotSupportedException
- * @since Android 1.0
  */
 public interface Cloneable {
     // Marker interface
diff --git a/luni/src/main/java/java/lang/Double.java b/luni/src/main/java/java/lang/Double.java
index 95c7b81..a4a9dc2 100644
--- a/luni/src/main/java/java/lang/Double.java
+++ b/luni/src/main/java/java/lang/Double.java
@@ -51,16 +51,42 @@
     public static final double NaN = 0.0 / 0.0;
 
     /**
-     * Constant for the Positive Infinity value of the {@code double} type.
+     * Constant for the positive infinity value of the {@code double} type.
      */
     public static final double POSITIVE_INFINITY = 1.0 / 0.0;
 
     /**
-     * Constant for the Negative Infinity value of the {@code double} type.
+     * Constant for the negative infinity value of the {@code double} type.
      */
     public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
 
     /**
+     * Constant for the smallest positive normal value of the {@code double} type.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final double MIN_NORMAL = 2.2250738585072014E-308;
+
+    /**
+     * Maximum exponent that a finite value of the {@code double} type may have.
+     * Equal to {@code Math.getExponent(Double.MAX_VALUE)}.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final int MAX_EXPONENT = 1023;
+
+    /**
+     * Minimum exponent that a normal value of the {@code double} type may have.
+     * Equal to {@code Math.getExponent(Double.MIN_NORMAL)}.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final int MIN_EXPONENT = -1022;
+
+    /**
      * The {@link Class} object that represents the primitive type {@code
      * double}.
      *
diff --git a/luni/src/main/java/java/lang/Enum.java b/luni/src/main/java/java/lang/Enum.java
index e2ee32a..a59010c 100644
--- a/luni/src/main/java/java/lang/Enum.java
+++ b/luni/src/main/java/java/lang/Enum.java
@@ -191,6 +191,16 @@
         // END android-changed
     }
 
+    /**
+     * Enum types may not have finalizers.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    @Override
+    protected final void finalize() {
+    }
+
     /*
      * Helper to invoke the values() static method on T and answer the result.
      * Returns null if there is a problem.
diff --git a/luni/src/main/java/java/lang/EnumConstantNotPresentException.java b/luni/src/main/java/java/lang/EnumConstantNotPresentException.java
index aec32d0..71923bb 100644
--- a/luni/src/main/java/java/lang/EnumConstantNotPresentException.java
+++ b/luni/src/main/java/java/lang/EnumConstantNotPresentException.java
@@ -43,10 +43,8 @@
      *            the missing constant name.
      */
     @SuppressWarnings("unchecked")
-    public EnumConstantNotPresentException(Class<? extends Enum> enumType,
-            String constantName) {
-        // luni.03=The enum constant {0}.{1} is missing
-        super(Msg.getString("luni.03", enumType.getName(), constantName)); //$NON-NLS-1$
+    public EnumConstantNotPresentException(Class<? extends Enum> enumType, String constantName) {
+        super("enum constant " + enumType.getName() + "." + constantName + " is missing");
         this.enumType = enumType;
         this.constantName = constantName;
     }
diff --git a/luni/src/main/java/java/lang/Float.java b/luni/src/main/java/java/lang/Float.java
index 54cc246..2d2140d 100644
--- a/luni/src/main/java/java/lang/Float.java
+++ b/luni/src/main/java/java/lang/Float.java
@@ -48,16 +48,42 @@
     public static final float NaN = 0.0f / 0.0f;
 
     /**
-     * Constant for the Positive Infinity value of the {@code float} type.
+     * Constant for the positive infinity value of the {@code float} type.
      */
     public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
 
     /**
-     * Constant for the Negative Infinity value of the {@code float} type.
+     * Constant for the negative infinity value of the {@code float} type.
      */
     public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
 
     /**
+     * Constant for the smallest positive normal value of the {@code float} type.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final float MIN_NORMAL = 1.1754943508222875E-38f;
+
+    /**
+     * Maximum exponent that a finite value of the {@code float} type may have.
+     * Equal to {@code Math.getExponent(Float.MAX_VALUE)}.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final int MAX_EXPONENT = 127;
+
+    /**
+     * Minimum exponent that a normal value of the {@code float} type may have.
+     * Equal to {@code Math.getExponent(Float.MIN_NORMAL)}.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final int MIN_EXPONENT = -126;
+
+    /**
      * The {@link Class} object that represents the primitive type {@code
      * float}.
      *
diff --git a/luni/src/main/java/java/lang/Math.java b/luni/src/main/java/java/lang/Math.java
index f7b49b2..d286d20 100644
--- a/luni/src/main/java/java/lang/Math.java
+++ b/luni/src/main/java/java/lang/Math.java
@@ -22,7 +22,30 @@
  * functions, hyperbolic functions, exponential, logarithms, etc.
  */
 public final class Math {
+    private static final int FLOAT_EXPONENT_BIAS = 127;
 
+    private static final int FLOAT_EXPONENT_MASK = 0x7F800000;
+
+    private static final int DOUBLE_NON_MANTISSA_BITS = 12;
+
+    private static final int DOUBLE_MANTISSA_BITS = 52;
+
+    private static final int FLOAT_NON_MANTISSA_BITS = 9;
+
+    private static final int FLOAT_MANTISSA_BITS = 23;
+
+    private static final int DOUBLE_EXPONENT_BIAS = 1023;
+
+    private static final long DOUBLE_EXPONENT_MASK = 0x7ff0000000000000L;
+
+    private static final int FLOAT_MANTISSA_MASK = 0x007fffff;
+
+    private static final int FLOAT_SIGN_MASK = 0x80000000;
+
+    private static final long DOUBLE_MANTISSA_MASK = 0x000fffffffffffffL;
+
+    private static final long DOUBLE_SIGN_MASK = 0x8000000000000000L;
+    
     /**
      * The double value closest to e, the base of the natural logarithm.
      */
@@ -497,7 +520,7 @@
             return Double.NaN;
         }
         /* max(+0.0,-0.0) == +0.0 */
-        /* 0 == Double.doubleToRawLongBits(0.0d) */
+        /* Double.doubleToRawLongBits(0.0d) == 0 */
         if (Double.doubleToRawLongBits(d1) != 0) {
             return d2;
         }
@@ -534,7 +557,7 @@
             return Float.NaN;
         }
         /* max(+0.0,-0.0) == +0.0 */
-        /* 0 == Float.floatToRawIntBits(0.0f) */
+        /* Float.floatToRawIntBits(0.0f) == 0*/
         if (Float.floatToRawIntBits(f1) != 0) {
             return f2;
         }
@@ -739,8 +762,8 @@
      * <li>{@code round(-0.0) = +0.0}</li>
      * <li>{@code round((anything > Long.MAX_VALUE) = Long.MAX_VALUE}</li>
      * <li>{@code round((anything < Long.MIN_VALUE) = Long.MIN_VALUE}</li>
-     * <li>{@code round(+infintiy) = Long.MAX_VALUE}</li>
-     * <li>{@code round(-infintiy) = Long.MIN_VALUE}</li>
+     * <li>{@code round(+infinity) = Long.MAX_VALUE}</li>
+     * <li>{@code round(-infinity) = Long.MIN_VALUE}</li>
      * <li>{@code round(NaN) = +0.0}</li>
      * </ul>
      * 
@@ -803,7 +826,16 @@
      * @return the value of the signum function.
      */
     public static double signum(double d) {
-        return StrictMath.signum(d);
+        if (Double.isNaN(d)) {
+            return Double.NaN;
+        }
+        double sig = d;
+        if (d > 0) {
+            sig = 1.0;
+        } else if (d < 0) {
+            sig = -1.0;
+        }
+        return sig;
     }
 
     /**
@@ -826,7 +858,16 @@
      * @return the value of the signum function.
      */
     public static float signum(float f) {
-        return StrictMath.signum(f);
+        if (Float.isNaN(f)) {
+            return Float.NaN;
+        }
+        float sig = f;
+        if (f > 0) {
+            sig = 1.0f;
+        } else if (f < 0) {
+            sig = -1.0f;
+        }
+        return sig;
     }
 
     /**
@@ -903,7 +944,7 @@
      * </ul>
      * 
      * @param d
-     *            the angle whose tangens has to be computed, in radians.
+     *            the angle whose tangent has to be computed, in radians.
      * @return the tangent of the argument.
      */
     public static native double tan(double d);
@@ -1050,4 +1091,361 @@
     private native static double nextafter(double x, double y);
 
     private native static float nextafterf(float x, float y);
+
+    /**
+     * Returns a double with the given magnitude and the sign of {@code sign}.
+     * If {@code sign} is NaN, the sign of the result is arbitrary.
+     * If you need a determinate sign in such cases, use {@code StrictMath.copySign}.
+     * @since 1.6
+     * @hide
+     */
+    public static native double copySign(double magnitude, double sign);
+
+    /**
+     * Returns a float with the given magnitude and the sign of {@code sign}.
+     * If {@code sign} is NaN, the sign of the result is arbitrary.
+     * If you need a determinate sign in such cases, use {@code StrictMath.copySign}.
+     * @since 1.6
+     * @hide
+     */
+    public static native float copySign(float magnitude, float sign);
+
+    /**
+     * Answers the exponent of a float.
+     * 
+     * @param f
+     *            the given float
+     * @return the exponent of the float.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static int getExponent(float f) {
+        int bits = Float.floatToRawIntBits(f);
+        bits = (bits & FLOAT_EXPONENT_MASK) >> FLOAT_MANTISSA_BITS;
+        return bits - FLOAT_EXPONENT_BIAS;
+    }
+
+    /**
+     * Answers the exponent of a double.
+     * 
+     * @param d
+     *            the given double
+     * @return the exponent of the double.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static int getExponent(double d) {
+        long bits = Double.doubleToRawLongBits(d);
+        bits = (bits & DOUBLE_EXPONENT_MASK) >> DOUBLE_MANTISSA_BITS;
+        return (int) bits - DOUBLE_EXPONENT_BIAS;
+    }    
+    
+    /**
+     * Answers a double next to the first given double value in the direction of
+     * the second given double.
+     * 
+     * @param start
+     *            the double value to start
+     * @param direction
+     *            the double indicating the direction
+     * @return a double next to the first given double value in the direction of
+     *         the second given double.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static double nextAfter(double start, double direction) {
+        if (start == 0 && direction == 0) {
+            return direction;
+        }
+        return nextafter(start, direction);
+    }
+
+    /**
+     * Answers a float next to the first given float value in the direction of
+     * the second given double value.
+     * 
+     * @param start
+     *            the float value to start
+     * @param direction
+     *            the double indicating the direction
+     * @return a float next to the first given float value in the direction of
+     *         the second given double.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static float nextAfter(float start, double direction) {
+        if (Float.isNaN(start) || Double.isNaN(direction)) {
+            return Float.NaN;
+        }
+        if (start == 0 && direction == 0) {
+            return (float) direction;
+        }
+        if ((start == Float.MIN_VALUE && direction < start)
+                || (start == -Float.MIN_VALUE && direction > start)) {
+            return (start > 0 ? 0f : -0f);
+        }
+        if (Float.isInfinite(start) && (direction != start)) {
+            return (start > 0 ? Float.MAX_VALUE : -Float.MAX_VALUE);
+        }
+        if ((start == Float.MAX_VALUE && direction > start)
+                || (start == -Float.MAX_VALUE && direction < start)) {
+            return (start > 0 ? Float.POSITIVE_INFINITY
+                    : Float.NEGATIVE_INFINITY);
+        }
+        if (direction > start) {
+            if (start > 0) {
+                return Float.intBitsToFloat(Float.floatToIntBits(start) + 1);
+            }
+            if (start < 0) {
+                return Float.intBitsToFloat(Float.floatToIntBits(start) - 1);
+            }
+            return +Float.MIN_VALUE;
+        }
+        if (direction < start) {
+            if (start > 0) {
+                return Float.intBitsToFloat(Float.floatToIntBits(start) - 1);
+            }
+            if (start < 0) {
+                return Float.intBitsToFloat(Float.floatToIntBits(start) + 1);
+            }
+            return -Float.MIN_VALUE;
+        }
+        return (float) direction;
+    }
+    
+    /**
+     * Answers the next larger double value to d.
+     * 
+     * @param d
+     *            the double value to start
+     * @return the next larger double value of d.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static double nextUp(double d) {
+        if (Double.isNaN(d)) {
+            return Double.NaN;
+        }
+        if (d == Double.POSITIVE_INFINITY) {
+            return Double.POSITIVE_INFINITY;
+        }
+        if (d == 0) {
+            return Double.MIN_VALUE;
+        } else if (d > 0) {
+            return Double.longBitsToDouble(Double.doubleToLongBits(d) + 1);
+        } else {
+            return Double.longBitsToDouble(Double.doubleToLongBits(d) - 1);
+        }
+    }
+
+    /**
+     * Answers the next larger float value to d.
+     * 
+     * @param f
+     *            the float value to start
+     * @return the next larger float value of d.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static float nextUp(float f) {
+        if (Float.isNaN(f)) {
+            return Float.NaN;
+        }
+        if (f == Float.POSITIVE_INFINITY) {
+            return Float.POSITIVE_INFINITY;
+        }
+        if (f == 0) {
+            return Float.MIN_VALUE;
+        } else if (f > 0) {
+            return Float.intBitsToFloat(Float.floatToIntBits(f) + 1);
+        } else {
+            return Float.intBitsToFloat(Float.floatToIntBits(f) - 1);
+        }
+    }
+    
+    /**
+     * Answers a double value of d * 2^scaleFactor, the result may be rounded.
+     * 
+     * @param d
+     *            the base number
+     * @param scaleFactor
+     *            the power number
+     * @return d * 2^scaleFactor
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static double scalb(double d, int scaleFactor) {
+        if (Double.isNaN(d) || Double.isInfinite(d) || d == 0) {
+            return d;
+        }
+        // change double to long for calculation
+        long bits = Double.doubleToLongBits(d);
+        // the sign of the results must be the same of given d
+        long sign = bits & DOUBLE_SIGN_MASK;
+        // calculates the factor of the result
+        long factor = ((bits & DOUBLE_EXPONENT_MASK) >> DOUBLE_MANTISSA_BITS)
+                - DOUBLE_EXPONENT_BIAS + scaleFactor;
+
+        // calculates the factor of sub-normal values
+        int subNormalFactor = Long.numberOfLeadingZeros(bits
+                & ~DOUBLE_SIGN_MASK)
+                - DOUBLE_NON_MANTISSA_BITS;
+        if (subNormalFactor < 0) {
+            // not sub-normal values
+            subNormalFactor = 0;
+        } else {
+            factor = factor - subNormalFactor;
+        }
+        if (factor > Double.MAX_EXPONENT) {
+            return (d > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY);
+        }
+
+        long result;
+        // if result is a sub-normal
+        if (factor <= -DOUBLE_EXPONENT_BIAS) {
+            // the number of digits that shifts
+            long digits = factor + DOUBLE_EXPONENT_BIAS + subNormalFactor;
+            if (Math.abs(d) < Double.MIN_NORMAL) {
+                // origin d is already sub-normal
+                result = shiftLongBits(bits & DOUBLE_MANTISSA_MASK, digits);
+            } else {
+                // origin d is not sub-normal, change mantissa to sub-normal
+                result = shiftLongBits(bits & DOUBLE_MANTISSA_MASK
+                        | 0x0010000000000000L, digits - 1);
+            }
+        } else {
+            if (Math.abs(d) >= Double.MIN_NORMAL) {
+                // common situation
+                result = ((factor + DOUBLE_EXPONENT_BIAS) << DOUBLE_MANTISSA_BITS)
+                        | (bits & DOUBLE_MANTISSA_MASK);
+            } else {
+                // origin d is sub-normal, change mantissa to normal style
+                result = ((factor + DOUBLE_EXPONENT_BIAS) << DOUBLE_MANTISSA_BITS)
+                        | ((bits << (subNormalFactor + 1)) & DOUBLE_MANTISSA_MASK);
+            }
+        }
+        return Double.longBitsToDouble(result | sign);
+    }
+
+    /**
+     * Answers a float value of d * 2^scaleFactor, the result may be rounded.
+     * 
+     * @param d
+     *            the base number
+     * @param scaleFactor
+     *            the power number
+     * @return d * 2^scaleFactor
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static float scalb(float d, int scaleFactor) {
+        if (Float.isNaN(d) || Float.isInfinite(d) || d == 0) {
+            return d;
+        }
+        int bits = Float.floatToIntBits(d);
+        int sign = bits & FLOAT_SIGN_MASK;
+        int factor = ((bits & FLOAT_EXPONENT_MASK) >> FLOAT_MANTISSA_BITS)
+                - FLOAT_EXPONENT_BIAS + scaleFactor;
+        // calcutes the factor of sub-normal values
+        int subNormalFactor = Integer.numberOfLeadingZeros(bits
+                & ~FLOAT_SIGN_MASK)
+                - FLOAT_NON_MANTISSA_BITS;
+        if (subNormalFactor < 0) {
+            // not sub-normal values
+            subNormalFactor = 0;
+        } else {
+            factor = factor - subNormalFactor;
+        }
+        if (factor > Float.MAX_EXPONENT) {
+            return (d > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY);
+        }
+
+        int result;
+        // if result is a sub-normal
+        if (factor <= -FLOAT_EXPONENT_BIAS) {
+            // the number of digits that shifts
+            int digits = factor + FLOAT_EXPONENT_BIAS + subNormalFactor;
+            if (Math.abs(d) < Float.MIN_NORMAL) {
+                // origin d is already sub-normal
+                result = shiftIntBits(bits & FLOAT_MANTISSA_MASK, digits);
+            } else {
+                // origin d is not sub-normal, change mantissa to sub-normal
+                result = shiftIntBits(bits & FLOAT_MANTISSA_MASK | 0x00800000,
+                        digits - 1);
+            }
+        } else {
+            if (Math.abs(d) >= Float.MIN_NORMAL) {
+                // common situation
+                result = ((factor + FLOAT_EXPONENT_BIAS) << FLOAT_MANTISSA_BITS)
+                        | (bits & FLOAT_MANTISSA_MASK);
+            } else {
+                // origin d is sub-normal, change mantissa to normal style
+                result = ((factor + FLOAT_EXPONENT_BIAS) << FLOAT_MANTISSA_BITS)
+                        | ((bits << (subNormalFactor + 1)) & FLOAT_MANTISSA_MASK);
+            }
+        }
+        return Float.intBitsToFloat(result | sign);
+    }
+
+    // Shifts integer bits as float, if the digits is positive, left-shift; if
+    // not, shift to right and calculate its carry.
+    private static int shiftIntBits(int bits, int digits) {
+        if (digits > 0) {
+            return bits << digits;
+        }
+        // change it to positive
+        int absdigits = -digits;
+        if (!(Integer.numberOfLeadingZeros(bits & ~FLOAT_SIGN_MASK) <= (32 - absdigits))) {
+            return 0;
+        }
+        int ret = bits >> absdigits;
+        boolean halfbit = ((bits >> (absdigits - 1)) & 0x1) == 1;
+        if (halfbit) {
+            if (Integer.numberOfTrailingZeros(bits) < (absdigits - 1)) {
+                ret = ret + 1;
+            }
+            if (Integer.numberOfTrailingZeros(bits) == (absdigits - 1)) {
+                if ((ret & 0x1) == 1) {
+                    ret = ret + 1;
+                }
+            }
+        }
+        return ret;
+    }
+
+    // Shifts long bits as double, if the digits is positive, left-shift; if
+    // not, shift to right and calculate its carry.
+    private static long shiftLongBits(long bits, long digits) {
+        if (digits > 0) {
+            return bits << digits;
+        }
+        // change it to positive
+        long absdigits = -digits;
+        if (!(Long.numberOfLeadingZeros(bits & ~DOUBLE_SIGN_MASK) <= (64 - absdigits))) {
+            return 0;
+        }
+        long ret = bits >> absdigits;
+        boolean halfbit = ((bits >> (absdigits - 1)) & 0x1) == 1;
+        if (halfbit) {
+            // some bits will remain after shifting, calculates its carry
+            // subnormal
+            if (Long.numberOfTrailingZeros(bits) < (absdigits - 1)) {
+                ret = ret + 1;
+            }
+            if (Long.numberOfTrailingZeros(bits) == (absdigits - 1)) {
+                if ((ret & 0x1) == 1) {
+                    ret = ret + 1;
+                }
+            }
+        }
+        return ret;
+    }
 }
diff --git a/luni/src/main/java/java/lang/StrictMath.java b/luni/src/main/java/java/lang/StrictMath.java
index b375a0f..5c6ebc7 100644
--- a/luni/src/main/java/java/lang/StrictMath.java
+++ b/luni/src/main/java/java/lang/StrictMath.java
@@ -37,6 +37,29 @@
  * <a href="http://www.netlib.org/fdlibm/">http://www.netlib.org/fdlibm/</a>
  */
 public final class StrictMath {
+    private static final int FLOAT_EXPONENT_BIAS = 127;
+
+    private static final int FLOAT_EXPONENT_MASK = 0x7F800000;
+
+    private static final int DOUBLE_EXPONENT_BITS = 12;
+
+    private static final int DOUBLE_MANTISSA_BITS = 52;
+    
+    private static final int FLOAT_EXPONENT_BITS = 9;
+    
+    private static final int FLOAT_MANTISSA_BITS = 23;  
+
+    private static final int DOUBLE_EXPONENT_BIAS = 1023;
+
+    private static final long DOUBLE_EXPONENT_MASK = 0x7ff0000000000000L;
+
+    private static final int FLOAT_MANTISSA_MASK = 0x007fffff;
+
+    private static final int FLOAT_SIGN_MASK = 0x80000000;
+
+    private static final long DOUBLE_MANTISSA_MASK = 0x000fffffffffffffL;
+
+    private static final long DOUBLE_SIGN_MASK = 0x8000000000000000L;
 
     /**
      * The double value closest to e, the base of the natural logarithm.
@@ -73,9 +96,7 @@
      * @return the absolute value of the argument.
      */
     public static double abs(double d) {
-        long bits = Double.doubleToLongBits(d);
-        bits &= 0x7fffffffffffffffL;
-        return Double.longBitsToDouble(bits);
+        return Math.abs(d);
     }
 
     /**
@@ -95,9 +116,7 @@
      *         argument.
      */
     public static float abs(float f) {
-        int bits = Float.floatToIntBits(f);
-        bits &= 0x7fffffff;
-        return Float.intBitsToFloat(bits);
+        return Math.abs(f);
     }
 
     /**
@@ -112,7 +131,7 @@
      *         argument.
      */
     public static int abs(int i) {
-        return i >= 0 ? i : -i;
+        return Math.abs(i);
     }
 
     /**
@@ -127,7 +146,7 @@
      *         argument.
      */
     public static long abs(long l) {
-        return l >= 0 ? l : -l;
+        return Math.abs(l);
     }
 
     /**
@@ -544,7 +563,7 @@
      * @return the larger of {@code i1} and {@code i2}.
      */
     public static int max(int i1, int i2) {
-        return i1 > i2 ? i1 : i2;
+        return Math.max(i1, i2);
     }
 
     /**
@@ -558,7 +577,7 @@
      * @return the larger of {@code l1} and {@code l2}.
      */
     public static long max(long l1, long l2) {
-        return l1 > l2 ? l1 : l2;
+        return Math.max(l1, l2);
     }
 
     /**
@@ -638,7 +657,7 @@
      * @return the smaller of {@code i1} and {@code i2}.
      */
     public static int min(int i1, int i2) {
-        return i1 < i2 ? i1 : i2;
+        return Math.min(i1, i2);
     }
 
     /**
@@ -652,7 +671,7 @@
      * @return the smaller of {@code l1} and {@code l2}.
      */
     public static long min(long l1, long l2) {
-        return l1 < l2 ? l1 : l2;
+        return Math.min(l1, l2);
     }
 
     /**
@@ -702,9 +721,7 @@
      * @return a pseudo-random number.
      */
     public static double random() {
-        if (random == null)
-            random = new Random();
-        return random.nextDouble();
+        return Math.random();
     }
 
     /**
@@ -746,10 +763,7 @@
      * @return the closest integer to the argument.
      */
     public static long round(double d) {
-        // check for NaN
-        if (d != d)
-            return 0L;
-        return (long) Math.floor(d + 0.5d);
+        return Math.round(d);
     }
 
     /**
@@ -772,10 +786,7 @@
      * @return the closest integer to the argument.
      */
     public static int round(float f) {
-        // check for NaN
-        if (f != f)
-            return 0;
-        return (int) Math.floor(f + 0.5f);
+        return Math.round(f);
     }
     
     /**
@@ -798,16 +809,7 @@
      * @return the value of the signum function.
      */
     public static double signum(double d){
-        if(Double.isNaN(d)){
-            return Double.NaN;
-        }
-        double sig = d;
-        if(d > 0){
-            sig = 1.0;
-        }else if (d < 0){
-            sig = -1.0;
-        }
-        return sig;
+        return Math.signum(d);
     }
     
     /**
@@ -830,16 +832,7 @@
      * @return the value of the signum function.
      */
     public static float signum(float f){
-        if(Float.isNaN(f)){
-            return Float.NaN;
-        }
-        float sig = f;
-        if(f > 0){
-            sig = 1.0f;
-        }else if (f < 0){
-            sig = -1.0f;
-        }
-        return sig;
+        return Math.signum(f);
     }
 
     /**
@@ -911,7 +904,7 @@
      * </ul>
      *
      * @param d
-     *            the angle whose tangens has to be computed, in radians.
+     *            the angle whose tangent has to be computed, in radians.
      * @return the tangent of the argument.
      */
     public static native double tan(double d);
@@ -953,7 +946,7 @@
      * @return the degree measure of the angle.
      */
     public static double toDegrees(double angrad) {
-        return angrad * 180d / PI;
+        return Math.toDegrees(angrad);
     }
 
     /**
@@ -974,7 +967,7 @@
      * @return the radian measure of the angle.
      */
     public static double toRadians(double angdeg) {
-        return angdeg / 180d * PI;
+        return Math.toRadians(angdeg);
     }
     
     /**
@@ -987,8 +980,8 @@
      * <ul>
      * <li>{@code ulp(+0.0) = Double.MIN_VALUE}</li>
      * <li>{@code ulp(-0.0) = Double.MIN_VALUE}</li>
-     * <li>{@code ulp(+infintiy) = infinity}</li>
-     * <li>{@code ulp(-infintiy) = infinity}</li>
+     * <li>{@code ulp(+infinity) = infinity}</li>
+     * <li>{@code ulp(-infinity) = infinity}</li>
      * <li>{@code ulp(NaN) = NaN}</li>
      * </ul>
      *
@@ -1017,8 +1010,8 @@
      * <ul>
      * <li>{@code ulp(+0.0) = Float.MIN_VALUE}</li>
      * <li>{@code ulp(-0.0) = Float.MIN_VALUE}</li>
-     * <li>{@code ulp(+infintiy) = infinity}</li>
-     * <li>{@code ulp(-infintiy) = infinity}</li>
+     * <li>{@code ulp(+infinity) = infinity}</li>
+     * <li>{@code ulp(-infinity) = infinity}</li>
      * <li>{@code ulp(NaN) = NaN}</li>
      * </ul>
      *
@@ -1042,4 +1035,285 @@
     private native static double nextafter(double x, double y);
 
     private native static float nextafterf(float x, float y); 
+    
+    /**
+     * Returns a double with the given magnitude and the sign of {@code sign}.
+     * If {@code sign} is NaN, the sign of the result is positive.
+     * @since 1.6
+     * @hide
+     */
+    public static double copySign(double magnitude, double sign) {
+        return Math.copySign(magnitude, sign);
+    }
+
+    /**
+     * Returns a float with the given magnitude and the sign of {@code sign}.
+     * If {@code sign} is NaN, the sign of the result is positive.
+     * @since 1.6
+     * @hide
+     */
+    public static float copySign(float magnitude, float sign) {
+        return Math.copySign(magnitude, sign);
+    }
+
+    /**
+     * Answers the exponent of a float.
+     * 
+     * @param f
+     *            the given float
+     * @return the exponent of the float.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static int getExponent(float f) {
+        return Math.getExponent(f);
+    }
+    
+    /**
+     * Answers the exponent of a double.
+     * 
+     * @param d
+     *            the given double
+     * @return the exponent of the double.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static int getExponent(double d){
+        return Math.getExponent(d);
+    }
+    
+    /**
+     * Answers a double next to the first given double value in the direction of
+     * the second given double.
+     * 
+     * @param start
+     *            the double value to start
+     * @param direction
+     *            the double indicating the direction
+     * @return a double next to the first given double value in the direction of
+     *         the second given double.
+     *         
+     * @since 1.6
+     * @hide
+     */
+    public static double nextAfter(double start, double direction) {
+        if (start == 0 && direction == 0) {
+            return direction;
+        }
+        return nextafter(start, direction);
+    }
+
+    /**
+     * Answers a float next to the first given float value in the direction of
+     * the second given double value.
+     * 
+     * @param start
+     *            the float value to start
+     * @param direction
+     *            the double indicating the direction
+     * @return a float next to the first given float value in the direction of
+     *         the second given double.
+     *         
+     * @since 1.6
+     * @hide
+     */
+    public static float nextAfter(float start, double direction) {
+        return Math.nextAfter(start, direction);
+    }
+
+    /**
+     * Answers the next larger double value to d.
+     * 
+     * @param d
+     *            the double value to start
+     * @return the next larger double value of d.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static double nextUp(double d) {
+        return Math.nextUp(d);
+    }
+    
+    /**
+     * Answers the next larger float value to d.
+     * 
+     * @param f
+     *            the float value to start
+     * @return the next larger float value of d.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static float nextUp(float f) {
+        return Math.nextUp(f);
+    }
+    
+    /**
+     * Answers a double value of d 2^scaleFactor, the result may be rounded.
+     * 
+     * @param d
+     *            the base number
+     * @param scaleFactor
+     *            the power number
+     * @return d 2^scaleFactor
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static double scalb(double d, int scaleFactor) {
+        if (Double.isNaN(d) || Double.isInfinite(d) || d == 0) {
+            return d;
+        }
+        // change double to long for calculation
+        long bits = Double.doubleToLongBits(d);
+        // the sign of the results must be the same of given d
+        long sign = bits & DOUBLE_SIGN_MASK;
+        // calculates the factor of the result
+        long factor = (int) ((bits & DOUBLE_EXPONENT_MASK) >> DOUBLE_MANTISSA_BITS)
+                - DOUBLE_EXPONENT_BIAS + scaleFactor;
+
+        // calculates the factor of sub-normal values
+        int subNormalFactor = Long.numberOfLeadingZeros(bits
+                & ~DOUBLE_SIGN_MASK)
+                - DOUBLE_EXPONENT_BITS;
+        if (subNormalFactor < 0) {
+            // not sub-normal values
+            subNormalFactor = 0;
+        }
+        if (Math.abs(d) < Double.MIN_NORMAL) {
+            factor = factor - subNormalFactor;
+        }
+        if (factor > Double.MAX_EXPONENT) {
+            return (d > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY);
+        }
+
+        long result;
+        // if result is a sub-normal
+        if (factor < -DOUBLE_EXPONENT_BIAS) {
+            // the number of digits that shifts
+            long digits = factor + DOUBLE_EXPONENT_BIAS + subNormalFactor;
+            if (Math.abs(d) < Double.MIN_NORMAL) {
+                // origin d is already sub-normal
+                result = shiftLongBits(bits & DOUBLE_MANTISSA_MASK, digits);
+            } else {
+                // origin d is not sub-normal, change mantissa to sub-normal
+                result = shiftLongBits(bits & DOUBLE_MANTISSA_MASK
+                        | 0x0010000000000000L, digits - 1);
+            }
+        } else {
+            if (Math.abs(d) >= Double.MIN_NORMAL) {
+                // common situation
+                result = ((factor + DOUBLE_EXPONENT_BIAS) << DOUBLE_MANTISSA_BITS)
+                        | (bits & DOUBLE_MANTISSA_MASK);
+            } else {
+                // origin d is sub-normal, change mantissa to normal style
+                result = ((factor + DOUBLE_EXPONENT_BIAS) << DOUBLE_MANTISSA_BITS)
+                        | ((bits << (subNormalFactor + 1)) & DOUBLE_MANTISSA_MASK);
+            }
+        }
+        return Double.longBitsToDouble(result | sign);
+    }
+
+    /**
+     * Answers a float value of d 2^scaleFactor, the result may be rounded.
+     * 
+     * @param d
+     *            the base number
+     * @param scaleFactor
+     *            the power number
+     * @return d 2^scaleFactor
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static float scalb(float d, int scaleFactor) {
+        if (Float.isNaN(d) || Float.isInfinite(d) || d == 0) {
+            return d;
+        }
+        int bits = Float.floatToIntBits(d);
+        int sign = bits & FLOAT_SIGN_MASK;
+        int factor = ((bits & FLOAT_EXPONENT_MASK) >> FLOAT_MANTISSA_BITS)
+                - FLOAT_EXPONENT_BIAS + scaleFactor;
+        // calculates the factor of sub-normal values
+        int subNormalFactor = Integer.numberOfLeadingZeros(bits
+                & ~FLOAT_SIGN_MASK)
+                - FLOAT_EXPONENT_BITS;
+        if (subNormalFactor < 0) {
+            // not sub-normal values
+            subNormalFactor = 0;
+        }
+        if (Math.abs(d) < Float.MIN_NORMAL) {
+            factor = factor - subNormalFactor;
+        }
+        if (factor > Float.MAX_EXPONENT) {
+            return (d > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY);
+        }
+
+        int result;
+        // if result is a sub-normal
+        if (factor < -FLOAT_EXPONENT_BIAS) {
+            // the number of digits that shifts
+            int digits = factor + FLOAT_EXPONENT_BIAS + subNormalFactor;
+            if (Math.abs(d) < Float.MIN_NORMAL) {
+                // origin d is already sub-normal
+                result = shiftIntBits(bits & FLOAT_MANTISSA_MASK, digits);
+            } else {
+                // origin d is not sub-normal, change mantissa to sub-normal
+                result = shiftIntBits(bits & FLOAT_MANTISSA_MASK | 0x00800000,
+                        digits - 1);
+            }
+        } else {
+            if (Math.abs(d) >= Float.MIN_NORMAL) {
+                // common situation
+                result = ((factor + FLOAT_EXPONENT_BIAS) << FLOAT_MANTISSA_BITS)
+                        | (bits & FLOAT_MANTISSA_MASK);
+            } else {
+                // origin d is sub-normal, change mantissa to normal style
+                result = ((factor + FLOAT_EXPONENT_BIAS) << FLOAT_MANTISSA_BITS)
+                        | ((bits << (subNormalFactor + 1)) & FLOAT_MANTISSA_MASK);
+            }
+        }
+        return Float.intBitsToFloat(result | sign);
+    }
+
+    // Shifts integer bits as float, if the digits is positive, left-shift; if
+    // not, shift to right and calculate its carry.
+    private static int shiftIntBits(int bits, int digits) {
+        if (digits > 0) {
+            return bits << digits;
+        }
+        // change it to positive
+        int absdigits = -digits;
+        if (Integer.numberOfLeadingZeros(bits & ~FLOAT_SIGN_MASK) <= (32 - absdigits)) {
+            // some bits will remain after shifting, calculates its carry
+            if ((((bits >> (absdigits - 1)) & 0x1) == 0)
+                    || Integer.numberOfTrailingZeros(bits) == (absdigits - 1)) {
+                return bits >> absdigits;
+            }
+            return ((bits >> absdigits) + 1);
+        }
+        return 0;
+    }
+
+    // Shifts long bits as double, if the digits is positive, left-shift; if
+    // not, shift to right and calculate its carry.
+    private static long shiftLongBits(long bits, long digits) {
+        if (digits > 0) {
+            return bits << digits;
+        }
+        // change it to positive
+        long absdigits = -digits;
+        if (Long.numberOfLeadingZeros(bits & ~DOUBLE_SIGN_MASK) <= (64 - absdigits)) {
+            // some bits will remain after shifting, calculates its carry
+            if ((((bits >> (absdigits - 1)) & 0x1) == 0)
+                    || Long.numberOfTrailingZeros(bits) == (absdigits - 1)) {
+                return bits >> absdigits;
+            }
+            return ((bits >> absdigits) + 1);
+        }
+        return 0;
+    }
 }
diff --git a/luni/src/main/java/java/lang/String.java b/luni/src/main/java/java/lang/String.java
index d3c953b..c7236d5 100644
--- a/luni/src/main/java/java/lang/String.java
+++ b/luni/src/main/java/java/lang/String.java
@@ -17,25 +17,20 @@
 
 package java.lang;
 
+import com.ibm.icu4jni.regex.NativeRegEx;
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
-import java.util.Comparator;
-import java.util.Formatter;
-import java.util.Locale;
-
-import java.util.regex.Pattern;
-
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException;
 import java.security.AccessController;
+import java.util.Comparator;
+import java.util.Formatter;
+import java.util.Locale;
+import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
-
-// BEGIN android-removed
-// import org.apache.harmony.kernel.vm.VM;
-// END android-removed
 import org.apache.harmony.luni.util.PriviAction;
 
 /**
@@ -49,18 +44,11 @@
  * @see Charset
  * @since 1.0
  */
-public final class String implements Serializable, Comparable<String>,
-        CharSequence {
+public final class String implements Serializable, Comparable<String>, CharSequence {
 
     private static final long serialVersionUID = -6849794470754667710L;
 
-    // BEGIN android-added
     private static final char REPLACEMENT_CHAR = (char) 0xfffd;
-    // END android-added
-
-    // BEGIN android-removed
-    // static class ConsolePrintStream extends java.io.PrintStream ...
-    // END android-removed
 
     /**
      * CaseInsensitiveComparator compares Strings ignoring the case of the
@@ -399,7 +387,7 @@
             } catch (Exception e) {
                 // do nothing. according to spec:
                 // behavior is unspecified for invalid array
-                cb = CharBuffer.wrap("\u003f".toCharArray()); //$NON-NLS-1$
+                cb = CharBuffer.wrap("\u003f".toCharArray());
             }
             if ((result = cb.length()) > 0) {
                 value = cb.array();
@@ -430,6 +418,84 @@
     }
 
     /**
+     * Converts the byte array to a String using the specified encoding.
+     * 
+     * @param data
+     *            the byte array to convert to a String
+     * @param start
+     *            the starting offset in the byte array
+     * @param length
+     *            the number of bytes to convert
+     * @param encoding
+     *            the encoding
+     * 
+     * @throws IndexOutOfBoundsException
+     *             when <code>length &lt; 0, start &lt; 0</code> or
+     *             <code>start + length &gt; data.length</code>
+     * @throws NullPointerException
+     *             when data is null
+     * 
+     * @see #getBytes()
+     * @see #getBytes(int, int, byte[], int)
+     * @see #getBytes(String)
+     * @see #valueOf(boolean)
+     * @see #valueOf(char)
+     * @see #valueOf(char[])
+     * @see #valueOf(char[], int, int)
+     * @see #valueOf(double)
+     * @see #valueOf(float)
+     * @see #valueOf(int)
+     * @see #valueOf(long)
+     * @see #valueOf(Object)
+     * @since 1.6
+     * @hide
+     */
+    public String(byte[] data, int start, int length, final Charset encoding) {
+        if (encoding == null) {
+            throw new NullPointerException();
+        }
+        if (start < 0 || length < 0 || length > data.length - start) {
+            throw new StringIndexOutOfBoundsException();
+        }
+        CharBuffer cb = encoding.decode(ByteBuffer.wrap(data, start, length));
+        this.lastCharset = encoding;
+        this.offset = 0;
+        this.count = cb.length();
+        this.value = new char[count];
+        System.arraycopy(cb.array(), 0, value, 0, count);
+    }
+
+    /**
+     * Converts the byte array to a String using the specified encoding.
+     * 
+     * @param data
+     *            the byte array to convert to a String
+     * @param encoding
+     *            the encoding
+     * 
+     * @throws NullPointerException
+     *             when data is null
+     * 
+     * @see #getBytes()
+     * @see #getBytes(int, int, byte[], int)
+     * @see #getBytes(String)
+     * @see #valueOf(boolean)
+     * @see #valueOf(char)
+     * @see #valueOf(char[])
+     * @see #valueOf(char[], int, int)
+     * @see #valueOf(double)
+     * @see #valueOf(float)
+     * @see #valueOf(int)
+     * @see #valueOf(long)
+     * @see #valueOf(Object)
+     * @since 1.6
+     * @hide
+     */
+    public String(byte[] data, Charset encoding) {
+        this(data, 0, data.length, encoding);
+    }
+    
+    /**
      * Initializes this string to contain the characters in the specified
      * character array. Modifying the character array after creating the string
      * has no effect on the string.
@@ -576,9 +642,8 @@
         if (codePoints == null) {
             throw new NullPointerException();
         }
-        if (offset < 0 || count < 0
-                || (long) offset + (long) count > codePoints.length) {
-            throw new IndexOutOfBoundsException();
+        if (offset < 0 || count < 0 || (long) offset + (long) count > codePoints.length) {
+            throw new StringIndexOutOfBoundsException();
         }
         this.offset = 0;
         this.value = new char[count * 2];
@@ -616,7 +681,7 @@
     @SuppressWarnings("unused")
     private String(String s1, int v1) {
         if (s1 == null) {
-            s1 = "null"; //$NON-NLS-1$
+            s1 = "null";
         }
         String s2 = String.valueOf(v1);
         int len = s1.count + s2.count;
@@ -784,8 +849,7 @@
     private Charset defaultCharset() {
         if (DefaultCharset == null) {
             String encoding = AccessController
-                    .doPrivileged(new PriviAction<String>(
-                            "file.encoding", "ISO8859_1")); //$NON-NLS-1$ //$NON-NLS-2$
+                    .doPrivileged(new PriviAction<String>("file.encoding", "ISO8859_1"));
             // calling System.getProperty() may cause DefaultCharset to be
             // initialized
             try {
@@ -797,7 +861,7 @@
             }
 
             if (DefaultCharset == null) {
-                DefaultCharset = Charset.forName("ISO-8859-1"); //$NON-NLS-1$
+                DefaultCharset = Charset.forName("ISO-8859-1");
             }
         }
         return DefaultCharset;
@@ -900,11 +964,7 @@
      * @return the byte array encoding of this string.
      */
     public byte[] getBytes() {
-        ByteBuffer buffer = defaultCharset().encode(
-                CharBuffer.wrap(this.value, this.offset, this.count));
-        byte[] bytes = new byte[buffer.limit()];
-        buffer.get(bytes);
-        return bytes;
+        return getBytes(defaultCharset());
     }
 
     /**
@@ -952,11 +1012,7 @@
      *             if the encoding is not supported.
      */
     public byte[] getBytes(String encoding) throws UnsupportedEncodingException {
-        ByteBuffer buffer = getCharset(encoding).encode(
-                CharBuffer.wrap(this.value, this.offset, this.count));
-        byte[] bytes = new byte[buffer.limit()];
-        buffer.get(bytes);
-        return bytes;
+        return getBytes(getCharset(encoding));
     }
 
     private Charset getCharset(final String encoding)
@@ -978,6 +1034,23 @@
     }
 
     /**
+     * Returns a new byte array containing the characters of this string encoded in the
+     * given charset.
+     * 
+     * @param encoding the encoding
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public byte[] getBytes(Charset encoding) {
+        CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
+        ByteBuffer buffer = encoding.encode(chars.asReadOnlyBuffer());
+        byte[] bytes = new byte[buffer.limit()];
+        buffer.get(bytes);
+        return bytes;
+    }
+
+    /**
      * Copies the specified characters in this string to the character array
      * starting at the specified offset in the character array.
      * 
@@ -1049,20 +1122,11 @@
      *         character isn't found.
      */
     public int indexOf(int c) {
-        // BEGIN android-changed
-        int _count = count;
-        if (0 < _count) {
-            int _offset = offset;
-            int last = _offset + _count;
-            char[] _value = value;
-            for (int i = _offset; i < last; i++) {
-                if (_value[i] == c) {
-                    return i - _offset;
-                }
-            }
+        // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep.
+        if (c > 0xffff) {
+            return indexOfSupplementary(c, 0);
         }
-        return -1;
-        // END android-changed
+        return fastIndexOf(c, 0);
     }
 
     /**
@@ -1078,6 +1142,13 @@
      *         character isn't found.
      */
     public int indexOf(int c, int start) {
+        if (c > 0xffff) {
+            return indexOfSupplementary(c, start);
+        }
+        return fastIndexOf(c, start);
+    }
+
+    private int fastIndexOf(int c, int start) {
         // BEGIN android-changed
         int _count = count;
         if (start < _count) {
@@ -1097,6 +1168,15 @@
         // END android-changed
     }
 
+    private int indexOfSupplementary(int c, int start) {
+        if (!Character.isSupplementaryCodePoint(c)) {
+            return -1;
+        }
+        char[] chars = Character.toChars(c);
+        String needle = new String(0, chars.length, chars);
+        return indexOf(needle, start);
+    }
+
     /**
      * Searches in this string for the first index of the specified string. The
      * search for the string starts at the beginning and moves towards the end
@@ -1202,6 +1282,16 @@
     native public String intern();
 
     /**
+     * Returns true if the length of this string is 0.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public boolean isEmpty() {
+        return count == 0;
+    }
+
+    /**
      * Searches in this string for the last index of the specified character.
      * The search for the character starts at the end and moves towards the
      * beginning of this string.
@@ -1212,6 +1302,9 @@
      *         character isn't found.
      */
     public int lastIndexOf(int c) {
+        if (c > 0xffff) {
+            return lastIndexOfSupplementary(c, Integer.MAX_VALUE);
+        }
         // BEGIN android-changed
         int _count = count;
         int _offset = offset;
@@ -1238,6 +1331,9 @@
      *         character isn't found.
      */
     public int lastIndexOf(int c, int start) {
+        if (c > 0xffff) {
+            return lastIndexOfSupplementary(c, start);
+        }
         // BEGIN android-changed
         int _count = count;
         int _offset = offset;
@@ -1256,6 +1352,15 @@
         // END android-changed
     }
 
+    private int lastIndexOfSupplementary(int c, int start) {
+        if (!Character.isSupplementaryCodePoint(c)) {
+            return -1;
+        }
+        char[] chars = Character.toChars(c);
+        String needle = new String(0, chars.length, chars);
+        return lastIndexOf(needle, start);
+    }
+
     /**
      * Searches in this string for the last index of the specified string. The
      * search for the string starts at the end and moves towards the beginning
@@ -1591,8 +1696,9 @@
     }
 
     /**
-     * Converts this string to lowercase, using the rules of the default locale.
-     * 
+     * Converts this string to lowercase, using the rules of the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     *
      * @return a new lowercase string, or {@code this} if it's already all-lowercase.
      */
     public String toLowerCase() {
@@ -1600,18 +1706,16 @@
     }
 
     /**
-     * Converts this string to lowercase, using the rules of the specified locale.
-     * <p>
-     * Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
+     * Converts this string to lowercase, using the rules of {@code locale}.
+     *
+     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
      * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
-     * Lithuanian locales. On the other hand, it isn't necessary to provide, a Greek locale to get
+     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
      * correct case mapping of Greek characters: any locale will do.
-     * <p>
-     * See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
+     *
+     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
      * for full details of context- and language-specific special cases.
-     * 
-     * @param locale
-     *            the Locale to use.
+     *
      * @return a new lowercase string, or {@code this} if it's already all-lowercase.
      */
     public String toLowerCase(Locale locale) {
@@ -1629,145 +1733,30 @@
     }
 
     /**
-     * Converts the characters in this string to uppercase, using the default
-     * Locale.
-     * 
-     * @return a new string containing the uppercase characters equivalent to
-     *         the characters in this string.
+     * Converts this this string to uppercase, using the rules of the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     *
+     * @return a new uppercase string, or {@code this} if it's already all-uppercase.
      */
     public String toUpperCase() {
-        return toUpperCase(Locale.getDefault());
-    }
-
-    // BEGIN android-note
-    // put this in a helper class so that it's only initialized on demand?
-    // END android-note
-    private static final char[] upperValues = "SS\u0000\u02bcN\u0000J\u030c\u0000\u0399\u0308\u0301\u03a5\u0308\u0301\u0535\u0552\u0000H\u0331\u0000T\u0308\u0000W\u030a\u0000Y\u030a\u0000A\u02be\u0000\u03a5\u0313\u0000\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5\u0313\u0342\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1fba\u0399\u0000\u0391\u0399\u0000\u0386\u0399\u0000\u0391\u0342\u0000\u0391\u0342\u0399\u0391\u0399\u0000\u1fca\u0399\u0000\u0397\u0399\u0000\u0389\u0399\u0000\u0397\u0342\u0000\u0397\u0342\u0399\u0397\u0399\u0000\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0000\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313\u0000\u03a5\u0342\u0000\u03a5\u0308\u0342\u1ffa\u0399\u0000\u03a9\u0399\u0000\u038f\u0399\u0000\u03a9\u0342\u0000\u03a9\u0342\u0399\u03a9\u0399\u0000FF\u0000FI\u0000FL\u0000FFIFFLST\u0000ST\u0000\u0544\u0546\u0000\u0544\u0535\u0000\u0544\u053b\u0000\u054e\u0546\u0000\u0544\u053d\u0000".value; //$NON-NLS-1$
-
-    /**
-     * Return the index of the specified character into the upperValues table.
-     * The upperValues table contains three entries at each position. These
-     * three characters are the upper case conversion. If only two characters
-     * are used, the third character in the table is \u0000.
-     *
-     * @param ch
-     *            the char being converted to upper case
-     *
-     * @return the index into the upperValues table, or -1
-     */
-    private int upperIndex(int ch) {
-        int index = -1;
-        if (ch >= 0xdf) {
-            if (ch <= 0x587) {
-                if (ch == 0xdf) {
-                    index = 0;
-                } else if (ch <= 0x149) {
-                    if (ch == 0x149) {
-                        index = 1;
-                    }
-                } else if (ch <= 0x1f0) {
-                    if (ch == 0x1f0) {
-                        index = 2;
-                    }
-                } else if (ch <= 0x390) {
-                    if (ch == 0x390) {
-                        index = 3;
-                    }
-                } else if (ch <= 0x3b0) {
-                    if (ch == 0x3b0) {
-                        index = 4;
-                    }
-                } else if (ch <= 0x587) {
-                    if (ch == 0x587) {
-                        index = 5;
-                    }
-                }
-            } else if (ch >= 0x1e96) {
-                if (ch <= 0x1e9a) {
-                    index = 6 + ch - 0x1e96;
-                } else if (ch >= 0x1f50 && ch <= 0x1ffc) {
-                    index = "\u000b\u0000\f\u0000\r\u0000\u000e\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>\u0000\u0000?@A\u0000BC\u0000\u0000\u0000\u0000D\u0000\u0000\u0000\u0000\u0000EFG\u0000HI\u0000\u0000\u0000\u0000J\u0000\u0000\u0000\u0000\u0000KL\u0000\u0000MN\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000OPQ\u0000RS\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000TUV\u0000WX\u0000\u0000\u0000\u0000Y".value[ch - 0x1f50]; //$NON-NLS-1$
-                    if (index == 0) {
-                        index = -1;
-                    }
-                } else if (ch >= 0xfb00) {
-                    if (ch <= 0xfb06) {
-                        index = 90 + ch - 0xfb00;
-                    } else if (ch >= 0xfb13 && ch <= 0xfb17) {
-                        index = 97 + ch - 0xfb13;
-                    }
-                }
-            }
-        }
-        return index;
+        return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count);
     }
 
     /**
-     * Converts the characters in this string to uppercase, using the specified
-     * Locale.
-     * 
-     * @param locale
-     *            the Locale to use.
-     * @return a new string containing the uppercase characters equivalent to
-     *         the characters in this string.
+     * Converts this this string to uppercase, using the rules of {@code locale}.
+     *
+     * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include
+     * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in
+     * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get
+     * correct case mapping of Greek characters: any locale will do.
+     *
+     * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a>
+     * for full details of context- and language-specific special cases.
+     *
+     * @return a new uppercase string, or {@code this} if it's already all-uppercase.
      */
     public String toUpperCase(Locale locale) {
-        // BEGIN android-changed: support Azeri.
-        String languageCode = locale.getLanguage();
-        boolean turkishOrAzeri = languageCode.equals("tr") || languageCode.equals("az");
-
-        char[] output = null;
-        int i = 0;
-        for (int o = offset, end = offset + count; o < end; o++) {
-            char ch = value[o];
-            int index = upperIndex(ch);
-            if (index == -1) {
-                if (output != null && i >= output.length) {
-                    char[] newoutput = new char[output.length + (count / 6) + 2];
-                    System.arraycopy(output, 0, newoutput, 0, output.length);
-                    output = newoutput;
-                }
-                char upch = !turkishOrAzeri ? Character.toUpperCase(ch)
-                        : (ch != 0x69 ? Character.toUpperCase(ch)
-                                : (char) 0x130);
-                if (ch != upch) {
-                    if (output == null) {
-                        output = new char[count];
-                        i = o - offset;
-                        System.arraycopy(value, offset, output, 0, i);
-                    }
-                    output[i++] = upch;
-                } else if (output != null) {
-                    output[i++] = ch;
-                }
-            } else {
-                int target = index * 3;
-                char val3 = upperValues[target + 2];
-                if (output == null) {
-                    output = new char[count + (count / 6) + 2];
-                    i = o - offset;
-                    System.arraycopy(value, offset, output, 0, i);
-                } else if (i + (val3 == 0 ? 1 : 2) >= output.length) {
-                    char[] newoutput = new char[output.length + (count / 6) + 3];
-                    System.arraycopy(output, 0, newoutput, 0, output.length);
-                    output = newoutput;
-                }
-
-                char val = upperValues[target];
-                output[i++] = val;
-                val = upperValues[target + 1];
-                output[i++] = val;
-                if (val3 != 0) {
-                    output[i++] = val3;
-                }
-            }
-        }
-        if (output == null) {
-            return this;
-        }
-        return output.length == i || output.length - i < 8 ? new String(0, i,
-                output) : new String(output, 0, i);
-        // END android-changed
+        return CaseMapper.toUpperCase(locale, this, value, offset, count);
     }
 
     /**
@@ -1901,7 +1890,7 @@
      * @return the object converted to a string, or the string {@code "null"}.
      */
     public static String valueOf(Object value) {
-        return value != null ? value.toString() : "null"; //$NON-NLS-1$
+        return value != null ? value.toString() : "null";
     }
 
     /**
@@ -1914,7 +1903,7 @@
      * @return the boolean converted to a string.
      */
     public static String valueOf(boolean value) {
-        return value ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
+        return value ? "true" : "false";
     }
 
     /**
@@ -2026,7 +2015,8 @@
     }
 
     /**
-     * Splits this string using the supplied regular expression {@code expr}.
+     * Splits this string using the supplied regular expression {@code expr},
+     * as if by {@code split(expr, 0)}.
      * 
      * @param expr
      *            the regular expression used to divide the string.
@@ -2041,13 +2031,14 @@
      * @since 1.4
      */
     public String[] split(String expr) {
-        return Pattern.compile(expr).split(this);
+        return split(expr, 0);
     }
 
     /**
      * Splits this string using the supplied regular expression {@code expr}.
      * The parameter {@code max} controls the behavior how many times the
-     * pattern is applied to the string.
+     * pattern is applied to the string; see {@link Pattern#split(CharSequence, int)}
+     * for details.
      * 
      * @param expr
      *            the regular expression used to divide the string.
@@ -2064,7 +2055,8 @@
      * @since 1.4
      */
     public String[] split(String expr, int max) {
-        return Pattern.compile(expr).split(this, max);
+        String[] result = java.util.regex.Splitter.fastSplit(expr, this, max);
+        return result != null ? result : Pattern.compile(expr).split(this, max);
     }
 
     /**
@@ -2087,45 +2079,31 @@
     }
 
     /**
-     * Retrieves the Unicode code point (character) value at the specified
-     * {@code index}.
+     * Returns the Unicode code point at the given {@code index}.
      * 
-     * @param index
-     *            the index to the {@code char} code unit within this string.
-     * @return the Unicode code point value.
-     * @throws IndexOutOfBoundsException
-     *             if {@code index} is negative or greater than or equal to
-     *             {@code length()}.
+     * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()}
      * @see Character#codePointAt(char[], int, int)
      * @since 1.5
      */
     public int codePointAt(int index) {
         if (index < 0 || index >= count) {
-            throw new IndexOutOfBoundsException();
+            throw new StringIndexOutOfBoundsException();
         }
-        int s = index + offset;
-        return Character.codePointAt(value, s, offset + count);
+        return Character.codePointAt(value, offset + index, offset + count);
     }
 
     /**
-     * Retrieves the Unicode code point value that precedes the specified
-     * {@code index}.
+     * Returns the Unicode code point that precedes the given {@code index}.
      * 
-     * @param index
-     *            the index to the {@code char} code unit within this string.
-     * @return the Unicode code point value.
-     * @throws IndexOutOfBoundsException
-     *             if {@code index} is less than 1 or greater than
-     *             {@code length()}.
+     * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()}
      * @see Character#codePointBefore(char[], int, int)
      * @since 1.5
      */
     public int codePointBefore(int index) {
         if (index < 1 || index > count) {
-            throw new IndexOutOfBoundsException();
+            throw new StringIndexOutOfBoundsException();
         }
-        int s = index + offset;
-        return Character.codePointBefore(value, s);
+        return Character.codePointBefore(value, offset + index, offset);
     }
 
     /**
@@ -2138,18 +2116,15 @@
      *            the exclusive end index of the subsequence.
      * @return the number of Unicode code points in the subsequence.
      * @throws IndexOutOfBoundsException
-     *             if {@code beginIndex} is negative or greater than {@code
-     *             endIndex} or {@code endIndex} is greater than {@code
-     *             length()}.
+     *         if {@code beginIndex < 0 || endIndex > length() || beginIndex > endIndex}
      * @see Character#codePointCount(CharSequence, int, int)
      * @since 1.5
      */
     public int codePointCount(int beginIndex, int endIndex) {
         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
-            throw new IndexOutOfBoundsException();
+            throw new StringIndexOutOfBoundsException();
         }
-        int s = beginIndex + offset;
-        return Character.codePointCount(value, s, endIndex - beginIndex);
+        return Character.codePointCount(value, offset + beginIndex, endIndex - beginIndex);
     }
 
     /**
@@ -2186,8 +2161,7 @@
      */
     public int offsetByCodePoints(int index, int codePointOffset) {
         int s = index + offset;
-        int r = Character.offsetByCodePoints(value, offset, count, s,
-                codePointOffset);
+        int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset);
         return r - offset;
     }
 
@@ -2195,24 +2169,20 @@
      * Returns a localized formatted string, using the supplied format and arguments,
      * using the user's default locale.
      * 
-     * <p>Note that this method can be dangerous: the user's default locale may
-     * not be the locale you tested in, and this may have unexpected effects on
-     * the output. In particular, floating point numbers may be output with
-     * ',' instead of '.' as the decimal separator if that's what the user's
-     * locale dictates. If you're formatting a string other than for human
+     * <p>If you're formatting a string other than for human
      * consumption, you should use the {@code format(Locale, String, Object...)}
-     * overload and supply {@code Locale.US}.
+     * overload and supply {@code Locale.US}. See
+     * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
-     * @param format
-     *            a format string.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
-     *            arguments to replace format specifiers (may be none).
+     *            the list of arguments passed to the formatter. If there are
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return the formatted string.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      * @throws java.util.IllegalFormatException
      *             if the format is invalid.
-     * @see java.util.Formatter
      * @since 1.5
      */
     public static String format(String format, Object... args) {
@@ -2222,35 +2192,26 @@
     /**
      * Returns a formatted string, using the supplied format and arguments,
      * localized to the given locale.
-     * <p>
-     * Note that this is a convenience method. Using it involves creating an
-     * internal {@link java.util.Formatter} instance on-the-fly, which is
-     * somewhat costly in terms of memory and time. This is probably acceptable
-     * if you use the method only rarely, but if you rely on it for formatting a
-     * large number of strings, consider creating and reusing your own
-     * {@link java.util.Formatter} instance instead.
-     *
-     * @param loc
+     * 
+     * @param locale
      *            the locale to apply; {@code null} value means no localization.
-     * @param format
-     *            a format string.
+     * @param format the format string (see {@link java.util.Formatter#format})
      * @param args
-     *            arguments to replace format specifiers (may be none).
+     *            the list of arguments passed to the formatter. If there are
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return the formatted string.
-     * @throws NullPointerException
-     *             if {@code format} is {@code null}.
+     * @throws NullPointerException if {@code format == null}
      * @throws java.util.IllegalFormatException
      *             if the format is invalid.
-     * @see java.util.Formatter
      * @since 1.5
      */
-    public static String format(Locale loc, String format, Object... args) {
+    public static String format(Locale locale, String format, Object... args) {
         if (format == null) {
             throw new NullPointerException("null format argument");
         }
-        int bufferSize = format.length()
-                + (args == null ? 0 : args.length * 10);
-        Formatter f = new Formatter(new StringBuilder(bufferSize), loc);
+        int bufferSize = format.length() + (args == null ? 0 : args.length * 10);
+        Formatter f = new Formatter(new StringBuilder(bufferSize), locale);
         return f.format(format, args).toString();
     }
 
diff --git a/luni/src/main/java/java/lang/package.html b/luni/src/main/java/java/lang/package.html
index e61346f..8075edb 100644
--- a/luni/src/main/java/java/lang/package.html
+++ b/luni/src/main/java/java/lang/package.html
@@ -6,6 +6,5 @@
       as well as several other classes which represent important data types or
       central aspects of the environment hosting the application.
     </p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/luni/src/main/java/java/lang/ref/package.html b/luni/src/main/java/java/lang/ref/package.html
index a4b2c65..e4cd3b4 100644
--- a/luni/src/main/java/java/lang/ref/package.html
+++ b/luni/src/main/java/java/lang/ref/package.html
@@ -94,7 +94,5 @@
         </tr>
       </table>
     </p>
-    
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/luni/src/main/java/java/lang/reflect/package.html b/luni/src/main/java/java/lang/reflect/package.html
index 5ad5f99..ec457e2 100644
--- a/luni/src/main/java/java/lang/reflect/package.html
+++ b/luni/src/main/java/java/lang/reflect/package.html
@@ -11,7 +11,5 @@
       reflection. The classes in this package represent the various language
       elements.  
     </p>
-    
-  @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/luni/src/main/java/java/net/IDN.java b/luni/src/main/java/java/net/IDN.java
new file mode 100644
index 0000000..51cebeb
--- /dev/null
+++ b/luni/src/main/java/java/net/IDN.java
@@ -0,0 +1,105 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import com.ibm.icu4jni.text.NativeIDN;
+
+/**
+ * Converts internationalized domain names between Unicode and the ASCII Compatible Encoding
+ * (ACE) representation.
+ *
+ * <p>See <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a> for full details.
+ *
+ * @since 1.6
+ * @hide
+ */
+public final class IDN {
+    /**
+     * When set, allows IDN to process unassigned unicode points.
+     */
+    public static final int ALLOW_UNASSIGNED = 1;
+
+    /**
+     * When set, ASCII strings are checked against RFC 1122 & RFC 1123.
+     */
+    public static final int USE_STD3_ASCII_RULES = 2;
+
+    private IDN() {
+    }
+
+    /**
+     * Transform a Unicode String to ASCII Compatible Encoding String according
+     * to the algorithm defined in RFC 3490.
+     * 
+     * <p>If the transformation fails (because the input is not a valid IDN), an
+     * exception will be thrown.
+     * 
+     * <p>This method can handle either an individual label or an entire domain name.
+     * In the latter case, the separators are: U+002E (full stop), U+3002 (ideographic full stop),
+     * U+FF0E (fullwidth full stop), and U+FF61 (halfwidth ideographic full stop).
+     * All of these will become U+002E (full stop) in the result.
+     * 
+     * @param input the Unicode name
+     * @param flags 0, {@code ALLOW_UNASSIGNED}, {@code USE_STD3_ASCII_RULES},
+     *         or {@code ALLOW_UNASSIGNED | USE_STD3_ASCII_RULES}
+     * @return the ACE name
+     * @throws IllegalArgumentException if {@code input} does not conform to RFC 3490
+     */
+    public static String toASCII(String input, int flags) {
+        return NativeIDN.toASCII(input, flags);
+    }
+
+    /**
+     * Equivalent to {@code toASCII(input, 0)}.
+     * 
+     * @param input the Unicode name
+     * @return the ACE name
+     * @throws IllegalArgumentException if {@code input} does not conform to RFC 3490
+     */
+    public static String toASCII(String input) {
+        return toASCII(input, 0);
+    }
+
+    /**
+     * Translates a string from ASCII Compatible Encoding (ACE) to Unicode
+     * according to the algorithm defined in RFC 3490.
+     * 
+     * <p>Unlike {@code toASCII}, this transformation cannot fail.
+     * 
+     * <p>This method can handle either an individual label or an entire domain name.
+     * In the latter case, the separators are: U+002E (full stop), U+3002 (ideographic full stop),
+     * U+FF0E (fullwidth full stop), and U+FF61 (halfwidth ideographic full stop).
+     * 
+     * @param input the ACE name
+     * @return the Unicode name
+     * @param flags 0, {@code ALLOW_UNASSIGNED}, {@code USE_STD3_ASCII_RULES},
+     *         or {@code ALLOW_UNASSIGNED | USE_STD3_ASCII_RULES}
+     */
+    public static String toUnicode(String input, int flags) {
+        return NativeIDN.toUnicode(input, flags);
+    }
+
+    /**
+     * Equivalent to {@code toUnicode(input, 0)}.
+     * 
+     * @param input the ACE name
+     * @return the Unicode name
+     */
+    public static String toUnicode(String input) {
+        return NativeIDN.toUnicode(input, 0);
+    }
+}
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index 41d49b2..e2e715c 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -24,19 +24,14 @@
 import java.io.ObjectStreamException;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-import java.security.AccessController;
 import java.util.Arrays;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.Enumeration;
-import java.util.StringTokenizer;
-
+import java.util.List;
 import org.apache.harmony.luni.net.NetUtil;
 import org.apache.harmony.luni.platform.INetworkSystem;
 import org.apache.harmony.luni.platform.Platform;
-import org.apache.harmony.luni.util.Inet6Util;
-import org.apache.harmony.luni.util.Msg;
-import org.apache.harmony.luni.util.PriviAction;
 
 /**
  * An Internet Protocol (IP) address. This can be either an IPv4 address or an IPv6 address, and
@@ -61,14 +56,12 @@
  * @see Inet6Address
  */
 public class InetAddress implements Serializable {
-    // BEGIN android-added: better DNS caching.
-    // Our Java-side DNS cache.
+    /** Our Java-side DNS cache. */
     private static final AddressCache addressCache = new AddressCache();
-    // END android-added
 
     private final static INetworkSystem NETIMPL = Platform.getNetworkSystem();
 
-    private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; //$NON-NLS-1$
+    private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused";
 
     private static final long serialVersionUID = 3286316764910316507L;
 
@@ -89,15 +82,6 @@
 
     byte[] ipaddress;
 
-    // BEGIN android-removed
-    // // Fill in the JNI id caches
-    // private static native void oneTimeInitialization(boolean supportsIPv6);
-    //
-    // static {
-    //     oneTimeInitialization(true);
-    // }
-    // END android-removed
-
     /**
      * Constructs an {@code InetAddress}.
      *
@@ -110,45 +94,7 @@
      * InetAddresses (e.g., getByAddress). That is why the API does not have
      * public constructors for any of these classes.
      */
-    InetAddress() {
-        super();
-    }
-
-    // BEGIN android-removed
-    /**
-     * Constructs an {@code InetAddress}, representing the {@code address} and
-     * {@code hostName}.
-     *
-     * @param address
-     *            the network address.
-     */
-    // InetAddress(byte[] address) {
-    //     super();
-    //     this.ipaddress = address;
-    // }
-    // END android-removed
-
-    // BEGIN android-removed
-    /**
-     * Constructs an {@code InetAddress}, representing the {@code address} and
-     * {@code hostName}.
-     *
-     * @param address
-     *            the network address.
-     *
-     */
-    // InetAddress(byte[] address, String hostName) {
-    //     super();
-    //     this.ipaddress = address;
-    //     this.hostName = hostName;
-    // }
-    // END android-removed
-
-    // BEGIN android-removed
-    // CacheElement cacheElement() {
-    //     return new CacheElement();
-    // }
-    // END android-removed
+    InetAddress() {}
 
     /**
      * Compares this {@code InetAddress} instance against the specified address
@@ -161,12 +107,10 @@
      */
     @Override
     public boolean equals(Object obj) {
-        // BEGIN android-changed
         if (!(obj instanceof InetAddress)) {
             return false;
         }
         return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress);
-        // END android-changed
     }
 
     /**
@@ -180,7 +124,6 @@
         return ipaddress.clone();
     }
 
-    // BEGIN android-added
     static final Comparator<byte[]> SHORTEST_FIRST = new Comparator<byte[]>() {
         public int compare(byte[] a1, byte[] a2) {
             return a1.length - a2.length;
@@ -222,7 +165,6 @@
         }
         return returnedAddresses;
     }
-    // END android-added
 
     /**
      * Gets all IP addresses associated with the given {@code host} identified
@@ -236,25 +178,16 @@
      * @return the array of addresses associated with the specified host.
      * @throws UnknownHostException if the address lookup fails.
      */
-    public static InetAddress[] getAllByName(String host)
-            throws UnknownHostException {
-        // BEGIN android-changed
-        return getAllByNameImpl(host, true);
-        // END android-changed
+    public static InetAddress[] getAllByName(String host) throws UnknownHostException {
+        return getAllByNameImpl(host).clone();
     }
 
-    // BEGIN android-added
     /**
-     * Implementation of getAllByName.
-     *
-     * @param host the hostname or literal IP string to be resolved.
-     * @param returnUnshared requests a result that is modifiable by the caller.
-     * @return the array of addresses associated with the specified host.
-     * @throws UnknownHostException if the address lookup fails.
+     * Returns the InetAddresses for {@code host}. The returned array is shared
+     * and must be cloned before it is returned to application code.
      */
-    static InetAddress[] getAllByNameImpl(String host, boolean returnUnshared)
-            throws UnknownHostException {
-        if (host == null || 0 == host.length()) {
+    static InetAddress[] getAllByNameImpl(String host) throws UnknownHostException {
+        if (host == null || host.isEmpty()) {
             if (NetUtil.preferIPv6Addresses()) {
                 return new InetAddress[] { Inet6Address.LOOPBACK,
                                            Inet4Address.LOOPBACK };
@@ -265,33 +198,33 @@
         }
 
         // Special-case "0" for legacy IPv4 applications.
-        if (host.equals("0")) { //$NON-NLS-1$
+        if (host.equals("0")) {
             return new InetAddress[] { Inet4Address.ANY };
         }
 
-        if (isHostName(host)) {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkConnect(host, -1);
-            }
-            if (returnUnshared) {
-                return lookupHostByName(host).clone();
+        try {
+            byte[] hBytes = NETIMPL.ipStringToByteArray(host);
+            if (hBytes.length == 4) {
+                return (new InetAddress[] { new Inet4Address(hBytes) });
+            } else if (hBytes.length == 16) {
+                return (new InetAddress[] { new Inet6Address(hBytes) });
             } else {
-                return lookupHostByName(host);
+                throw new UnknownHostException(wrongAddressLength());
             }
+        } catch (UnknownHostException e) {
         }
 
-        byte[] hBytes = NETIMPL.ipStringToByteArray(host);
-        if (hBytes.length == 4) {
-            return (new InetAddress[] { new Inet4Address(hBytes) });
-        } else if (hBytes.length == 16) {
-            return (new InetAddress[] { new Inet6Address(hBytes) });
-        } else {
-            throw new UnknownHostException(
-                    Msg.getString("K0339")); //$NON-NLS-1$
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkConnect(host, -1);
         }
+
+        return lookupHostByName(host);
     }
-    // END android-added
+
+    private static String wrongAddressLength() {
+        return "Invalid IP Address is neither 4 or 16 bytes";
+    }
 
     /**
      * Returns the address of a host according to the given host string name
@@ -307,10 +240,9 @@
      *             if the address lookup fails.
      */
     public static InetAddress getByName(String host) throws UnknownHostException {
-        return getAllByNameImpl(host, false)[0];
+        return getAllByNameImpl(host)[0];
     }
 
-    // BEGIN android-added
     /**
      * Returns the numeric string form of the given IP address.
      *
@@ -326,7 +258,6 @@
             throw new IllegalArgumentException("byte[] neither 4 nor 16 bytes", ex);
         }
     }
-    // END android-added
 
     /**
      * Gets the textual representation of this IP address.
@@ -355,7 +286,7 @@
                     }
                 }
                 hostName = getHostByAddrImpl(ipaddress).hostName;
-                if (hostName.equals("localhost") && ipaddress.length == 4 //$NON-NLS-1$
+                if (hostName.equals("localhost") && ipaddress.length == 4
                         && address != 0x7f000001) {
                     return hostName = ipAddressToString(ipaddress);
                 }
@@ -467,12 +398,9 @@
      */
     @Override
     public int hashCode() {
-        // BEGIN android-changed
         return Arrays.hashCode(ipaddress);
-        // END android-changed
     }
 
-    // BEGIN android-changed
     /*
      * Returns whether this address is an IP multicast address or not. This
      * implementation returns always {@code false}.
@@ -483,7 +411,6 @@
     public boolean isMulticastAddress() {
         return false;
     }
-    // END android-changed
 
     /**
      * Resolves a hostname to its IP addresses using a cache.
@@ -491,7 +418,6 @@
      * @param host the hostname to resolve.
      * @return the IP addresses of the host.
      */
-    // BEGIN android-changed
     private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
         // Do we have a result cached?
         InetAddress[] cachedResult = addressCache.get(host);
@@ -514,12 +440,6 @@
         }
     }
     private static native byte[][] getaddrinfo(String name) throws UnknownHostException;
-    // END android-changed
-
-    // BEGIN android-deleted
-    // static native InetAddress[] getAliasesByNameImpl(String name)
-    //     throws UnknownHostException;
-    // END android-deleted
 
     /**
      * Query the IP stack for the host address. The host is in address form.
@@ -529,9 +449,6 @@
      * @throws UnknownHostException
      *             if an error occurs during lookup.
      */
-    // BEGIN android-changed
-    // static native InetAddress getHostByAddrImpl(byte[] addr)
-    //    throws UnknownHostException;
     static InetAddress getHostByAddrImpl(byte[] addr)
             throws UnknownHostException {
         if (addr.length == 4) {
@@ -539,8 +456,7 @@
         } else if (addr.length == 16) {
             return new Inet6Address(addr, getnameinfo(addr));
         } else {
-            throw new UnknownHostException(Msg.getString(
-                    "K0339")); //$NON-NLS-1$
+            throw new UnknownHostException(wrongAddressLength());
         }
     }
 
@@ -548,23 +464,6 @@
      * Resolves an IP address to a hostname. Thread safe.
      */
     private static native String getnameinfo(byte[] addr);
-    // END android-changed
-
-    // BEGIN android-removed
-    // static int inetAddr(String host) throws UnknownHostException
-    // END android-removed
-
-    // BEGIN android-removed
-    // static native int inetAddrImpl(String host) throws UnknownHostException;
-    // END android-removed
-
-    // BEGIN android-removed
-    // static native String inetNtoaImpl(int hipAddr);
-    // END android-removed
-
-    // BEGIN android-removed
-    // static native InetAddress getHostByNameImpl(String name) throws UnknownHostException;
-    // END android-removed
 
     static String getHostNameInternal(String host, boolean isCheck) throws UnknownHostException {
         if (host == null || 0 == host.length()) {
@@ -590,7 +489,7 @@
      */
     @Override
     public String toString() {
-        return (hostName == null ? "" : hostName) + "/" + getHostAddress(); //$NON-NLS-1$ //$NON-NLS-2$
+        return (hostName == null ? "" : hostName) + "/" + getHostAddress();
     }
 
     /**
@@ -772,7 +671,7 @@
      * ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
      * on port 7 (Echo) of the remote host is established.
      *
-     * @param netif
+     * @param networkInterface
      *            the network interface on which to connection should be
      *            established.
      * @param ttl
@@ -787,57 +686,33 @@
      * @throws IllegalArgumentException
      *             if ttl or timeout is less than zero.
      */
-    public boolean isReachable(NetworkInterface netif, final int ttl,
+    public boolean isReachable(NetworkInterface networkInterface, final int ttl,
             final int timeout) throws IOException {
-        if (0 > ttl || 0 > timeout) {
-            throw new IllegalArgumentException(Msg.getString("K0051")); //$NON-NLS-1$
+        if (ttl < 0 || timeout < 0) {
+            throw new IllegalArgumentException("ttl < 0 || timeout < 0");
         }
-        boolean reachable = false;
-        if (null == netif) {
-            // network interface is null, binds to no address
-            // BEGIN android-changed
-            // reachable = NETIMPL.isReachableByICMP(this, null, ttl, timeout);
-            // if (!reachable) {
-                reachable = isReachableByTCP(this, null, timeout);
-            // }
-            // END android-changed
+        if (networkInterface == null) {
+            return isReachableByTCP(this, null, timeout);
         } else {
-            // Not Bind to any address
-            if (null == netif.addresses) {
-                return false;
-            }
-            // binds to all address on this NetworkInterface, tries ICMP ping
-            // first
-            // BEGIN android-changed
-            // reachable = isReachableByICMPUseMultiThread(netif, ttl, timeout);
-            // if (!reachable) {
-                // tries TCP echo if ICMP ping fails
-                reachable = isReachableByMultiThread(netif, ttl, timeout);
-            // }
-            // END adnroid-changed
+            return isReachableByMultiThread(networkInterface, ttl, timeout);
         }
-        return reachable;
     }
 
     /*
      * Uses multi-Thread to try if isReachable, returns true if any of threads
      * returns in time
      */
-    // BEGIN android-changed
     private boolean isReachableByMultiThread(NetworkInterface netif,
             final int ttl, final int timeout)
-    // END android-changed
             throws IOException {
-        if (null == netif.addresses) {
+        List<InetAddress> addresses = Collections.list(netif.getInetAddresses());
+        if (addresses.isEmpty()) {
             return false;
         }
-        Enumeration<InetAddress> addresses = netif.getInetAddresses();
         reached = false;
-        addrCount = netif.addresses.length;
+        addrCount = addresses.size();
         boolean needWait = false;
-        while (addresses.hasMoreElements()) {
-            final InetAddress addr = addresses.nextElement();
-
+        for (final InetAddress addr : addresses) {
             // loopback interface can only reach to local addresses
             if (addr.isLoopbackAddress()) {
                 Enumeration<NetworkInterface> NetworkInterfaces = NetworkInterface
@@ -869,23 +744,16 @@
 
             needWait = true;
             new Thread() {
-                @Override
-                public void run() {
+                @Override public void run() {
+                    /*
+                     * Spec violation! This implementation doesn't attempt an
+                     * ICMP; it skips right to TCP echo.
+                     */
                     boolean threadReached = false;
-                    // BEGIN android-changed
-                    // if isICMP, tries ICMP ping, else TCP echo
-                    // if (isICMP) {
-                    //     threadReached = NETIMPL.isReachableByICMP(
-                    //             InetAddress.this, addr, ttl, timeout);
-                    // } else {
-                        try {
-                            threadReached = isReachableByTCP(addr,
-                                    InetAddress.this, timeout);
-                        } catch (IOException e) {
-                            // do nothing
-                        }
-                    // }
-                    // END android-changed
+                    try {
+                        threadReached = isReachableByTCP(addr, InetAddress.this, timeout);
+                    } catch (IOException e) {
+                    }
 
                     synchronized (waitReachable) {
                         if (threadReached) {
@@ -923,18 +791,6 @@
         return false;
     }
 
-    // BEGIN android-removed
-    // private boolean isReachableByICMPUseMultiThread(NetworkInterface netif,
-    //         int ttl, int timeout) throws IOException {
-    //     return isReachableByMultiThread(netif, ttl, timeout, true);
-    // }
-    //
-    // private boolean isReachableByTCPUseMultiThread(NetworkInterface netif,
-    //         int ttl, int timeout) throws IOException {
-    //     return isReachableByMultiThread(netif, ttl, timeout, false);
-    // }
-    // END android-removed
-
     private boolean isReachableByTCP(InetAddress dest, InetAddress source,
             int timeout) throws IOException {
         FileDescriptor fd = new FileDescriptor();
@@ -1080,11 +936,7 @@
     static InetAddress getByAddressInternal(String hostName, byte[] ipAddress,
             int scope_id) throws UnknownHostException {
         if (ipAddress == null) {
-            // We don't throw NullPointerException here for RI compatibility,
-            // but we do say "address is null" (K0331), instead of "addr is of
-            // illegal length".
-            throw new UnknownHostException(
-                Msg.getString("K0331", hostName)); //$NON-NLS-1$
+            throw new UnknownHostException("ipAddress == null");
         }
         switch (ipAddress.length) {
             case 4:
@@ -1099,15 +951,8 @@
                     return new Inet6Address(ipAddress.clone(), scope_id);
                 }
             default:
-                if (hostName != null) {
-                    // "Invalid IP Address is neither 4 or 16 bytes: <hostName>"
-                    throw new UnknownHostException(
-                            Msg.getString("K0332", hostName)); //$NON-NLS-1$
-                } else {
-                    // "Invalid IP Address is neither 4 or 16 bytes"
-                    throw new UnknownHostException(
-                            Msg.getString("K0339")); //$NON-NLS-1$
-                }
+                throw new UnknownHostException(
+                        "Invalid IP Address is neither 4 or 16 bytes: " + hostName);
         }
     }
 
@@ -1145,19 +990,19 @@
     }
 
     private static final ObjectStreamField[] serialPersistentFields = {
-            new ObjectStreamField("address", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("family", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("hostName", String.class) }; //$NON-NLS-1$
+            new ObjectStreamField("address", Integer.TYPE),
+            new ObjectStreamField("family", Integer.TYPE),
+            new ObjectStreamField("hostName", String.class) };
 
     private void writeObject(ObjectOutputStream stream) throws IOException {
         ObjectOutputStream.PutField fields = stream.putFields();
         if (ipaddress == null) {
-            fields.put("address", 0); //$NON-NLS-1$
+            fields.put("address", 0);
         } else {
-            fields.put("address", bytesToInt(ipaddress, 0)); //$NON-NLS-1$
+            fields.put("address", bytesToInt(ipaddress, 0));
         }
-        fields.put("family", family); //$NON-NLS-1$
-        fields.put("hostName", hostName); //$NON-NLS-1$
+        fields.put("family", family);
+        fields.put("hostName", hostName);
 
         stream.writeFields();
     }
@@ -1165,11 +1010,11 @@
     private void readObject(ObjectInputStream stream) throws IOException,
             ClassNotFoundException {
         ObjectInputStream.GetField fields = stream.readFields();
-        int addr = fields.get("address", 0); //$NON-NLS-1$
+        int addr = fields.get("address", 0);
         ipaddress = new byte[4];
         intToBytes(addr, ipaddress, 0);
-        hostName = (String) fields.get("hostName", null); //$NON-NLS-1$
-        family = fields.get("family", 2); //$NON-NLS-1$
+        hostName = (String) fields.get("hostName", null);
+        family = fields.get("family", 2);
     }
 
     /*
diff --git a/luni/src/main/java/java/net/InterfaceAddress.java b/luni/src/main/java/java/net/InterfaceAddress.java
index 7bc3936..2fa99f7 100644
--- a/luni/src/main/java/java/net/InterfaceAddress.java
+++ b/luni/src/main/java/java/net/InterfaceAddress.java
@@ -20,22 +20,131 @@
  * Identifies one of a network interface's addresses.
  * These are passed back from the JNI behind NetworkInterface.getNetworkInterfaces.
  * Multiple addresses for the same interface are collected together on the Java side.
+ *
+ * @hide
+ * @since 1.6
  */
-class InterfaceAddress {
-    // An IPv4 or IPv6 address.
-    final InetAddress address;
-
-    // The kernel's interface index for the network interface this address
-    // is currently assigned to. Values start at 1, because 0 means "unknown"
-    // or "any", depending on context.
+public class InterfaceAddress {
+    /**
+     * The kernel's interface index for the network interface this address
+     * is currently assigned to. Values start at 1, because 0 means "unknown"
+     * or "any", depending on context.
+     */
     final int index;
 
-    // The network interface's name. "lo" or "eth0", for example.
+    /**
+     * The network interface's name. "lo" or "eth0", for example.
+     */
     final String name;
 
-    InterfaceAddress(int index, String name, InetAddress address) {
+    /**
+     * An IPv4 or IPv6 address.
+     */
+    final InetAddress address;
+
+    /**
+     * The IPv4 broadcast address, or null for IPv6.
+     */
+    private final InetAddress broadcastAddress;
+
+    private final short prefixLength;
+
+    InterfaceAddress(int index, String name, InetAddress address, InetAddress mask) {
+        assert ((address instanceof Inet4Address) == (mask instanceof Inet4Address));
         this.index = index;
         this.name = name;
         this.address = address;
+        this.broadcastAddress = makeBroadcastAddress(address, mask);
+        this.prefixLength = countPrefixLength(mask);
+    }
+
+    private static InetAddress makeBroadcastAddress(InetAddress address, InetAddress mask) {
+        if (!(address instanceof Inet4Address)) {
+            return null;
+        }
+        byte[] broadcast = new byte[4];
+        byte[] maskBytes = mask.ipaddress;
+        byte[] addrBytes = address.ipaddress;
+        if (maskBytes[0] != 0) {
+            for (int i = 0; i < broadcast.length; ++i) {
+                broadcast[i] = (byte) (addrBytes[i] | ~maskBytes[i]);
+            }
+        }
+        return new Inet4Address(broadcast);
+    }
+
+    private static short countPrefixLength(InetAddress mask) {
+        short count = 0;
+        for (byte b : mask.ipaddress) {
+            for (int i = 0; i < 8; ++i) {
+                if ((b & (1 << i)) != 0) {
+                    ++count;
+                }
+            }
+        }
+        return count;
+    }
+
+    /**
+     * Tests whether this object is equal to another one. Returns true if
+     * the address, broadcast address and prefix length are all equal.
+     *
+     * @param obj the object to be compared.
+     * @return true if 'obj' is equal to this InterfaceAddress, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this){
+            return true;
+        }
+        if (!(obj instanceof InterfaceAddress)) {
+            return false;
+        }
+        InterfaceAddress rhs = (InterfaceAddress) obj;
+        return ((address == null) ? rhs.address == null : address.equals(rhs.address)) &&
+                (rhs.prefixLength == prefixLength) &&
+                ((broadcastAddress == null) ? rhs.broadcastAddress == null : broadcastAddress.equals(rhs.broadcastAddress));
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = address == null ? 0 : -address.hashCode();
+        hashCode += broadcastAddress == null ? 0 : broadcastAddress.hashCode();
+        hashCode += prefixLength;
+        return hashCode;
+    }
+
+    /**
+     * Returns a string representation for this interface address.
+     * The string is of the form: InetAddress / prefix length [ broadcast address ].
+     *
+     * @return a string representation of this interface address.
+     */
+    @Override
+    public String toString() {
+        return address + "/" + prefixLength + " [" + broadcastAddress + "]";
+    }
+
+    /**
+     * Returns the InetAddress for this address.
+     */
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    /**
+     * Returns the subnet-directed broadcast address if this is an IPv4 interface, null otherwise.
+     */
+    public InetAddress getBroadcast() {
+        return broadcastAddress;
+    }
+
+    /**
+     * Returns the network prefix length in bits.
+     * (In IPv4 parlance, this is known as the subnet mask,
+     * but this method applies to IPv6 addresses too.)
+     */
+    public short getNetworkPrefixLength() {
+        return prefixLength;
     }
 }
diff --git a/luni/src/main/java/java/net/NetworkInterface.java b/luni/src/main/java/java/net/NetworkInterface.java
index 93a30cb..b3e242e 100644
--- a/luni/src/main/java/java/net/NetworkInterface.java
+++ b/luni/src/main/java/java/net/NetworkInterface.java
@@ -17,9 +17,12 @@
 
 package java.net;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Vector;
@@ -37,49 +40,45 @@
     private static final int CHECK_CONNECT_NO_PORT = -1;
 
     static final int NO_INTERFACE_INDEX = 0;
-
     static final int UNSET_INTERFACE_INDEX = -1;
 
-    private String name;
+    private final String name;
+    private final String displayName;
+    private final List<InterfaceAddress> interfaceAddresses = new LinkedList<InterfaceAddress>();
 
-    private String displayName;
-
-    InetAddress addresses[];
+    private final List<InetAddress> addresses = new LinkedList<InetAddress>();
 
     // The interface index is a positive integer which is non-negative. Where
     // value is zero then we do not have an index for the interface (which
     // occurs in systems which only support IPV4)
     private int interfaceIndex;
 
-    private int hashCode;
+    private NetworkInterface parent = null;
+
+    private final List<NetworkInterface> children = new LinkedList<NetworkInterface>();
 
     // BEGIN android-changed: we pay this extra complexity on the Java side
     // in return for vastly simpler native code.
-    private static native InterfaceAddress[] getInterfaceAddresses() throws SocketException;
+    private static native InterfaceAddress[] getAllInterfaceAddressesImpl() throws SocketException;
 
     private static NetworkInterface[] getNetworkInterfacesImpl() throws SocketException {
         Map<String, NetworkInterface> networkInterfaces = new LinkedHashMap<String, NetworkInterface>();
-        for (InterfaceAddress ia : getInterfaceAddresses()) {
+        for (InterfaceAddress ia : getAllInterfaceAddressesImpl()) {
             if (ia != null) { // The array may contain harmless null elements.
                 String name = ia.name;
                 NetworkInterface ni = networkInterfaces.get(name);
                 if (ni == null) {
                     ni = new NetworkInterface(name, name, new InetAddress[] { ia.address }, ia.index);
+                    ni.interfaceAddresses.add(ia);
                     networkInterfaces.put(name, ni);
                 } else {
-                    ni.addInterfaceAddress(ia.address);
+                    ni.addresses.add(ia.address);
+                    ni.interfaceAddresses.add(ia);
                 }
             }
         }
         return networkInterfaces.values().toArray(new NetworkInterface[networkInterfaces.size()]);
     }
-
-    private void addInterfaceAddress(InetAddress address) {
-        InetAddress[] newAddresses = new InetAddress[addresses.length + 1];
-        System.arraycopy(addresses, 0, newAddresses, 0, addresses.length);
-        newAddresses[addresses.length] = address;
-        addresses = newAddresses;
-    }
     // END android-changed
 
     /**
@@ -96,12 +95,16 @@
      *            an index for the interface. Only set for platforms that
      *            support IPV6.
      */
-    NetworkInterface(String name, String displayName, InetAddress addresses[],
+    NetworkInterface(String name, String displayName, InetAddress[] addresses,
             int interfaceIndex) {
         this.name = name;
         this.displayName = displayName;
-        this.addresses = addresses;
         this.interfaceIndex = interfaceIndex;
+        if (addresses != null) {
+            for (InetAddress address : addresses) {
+                this.addresses.add(address);
+            }
+        }
     }
 
     /**
@@ -122,8 +125,8 @@
      * @return the first address if one exists, otherwise null.
      */
     InetAddress getFirstAddress() {
-        if ((addresses != null) && (addresses.length >= 1)) {
-            return addresses[0];
+        if (addresses.size() >= 1) {
+            return addresses.get(0);
         }
         return null;
     }
@@ -143,63 +146,21 @@
      * @return the address list of the represented network interface.
      */
     public Enumeration<InetAddress> getInetAddresses() {
-        /*
-         * create new vector from which Enumeration to be returned can be
-         * generated set the initial capacity to be the number of addresses for
-         * the network interface which is the maximum required size
-         */
-
-        /*
-         * return an empty enumeration if there are no addresses associated with
-         * the interface
-         */
-        if (addresses == null) {
-            return new Vector<InetAddress>(0).elements();
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null || addresses.isEmpty()) {
+            return Collections.enumeration(addresses);
         }
-
-        /*
-         * for those configuration that support the security manager we only
-         * return addresses for which checkConnect returns true
-         */
-        Vector<InetAddress> accessibleAddresses = new Vector<InetAddress>(
-                addresses.length);
-
-        /*
-         * get the security manager. If one does not exist just return the full
-         * list
-         */
-        SecurityManager security = System.getSecurityManager();
-        if (security == null) {
-            return (new Vector<InetAddress>(Arrays.asList(addresses)))
-                    .elements();
-        }
-
-        /*
-         * ok security manager exists so check each address and return those
-         * that pass
-         */
-        for (InetAddress element : addresses) {
-            if (security != null) {
-                try {
-                    /*
-                     * since we don't have a port in this case we pass in
-                     * NO_PORT
-                     */
-                    security.checkConnect(element.getHostName(),
-                            CHECK_CONNECT_NO_PORT);
-                    accessibleAddresses.add(element);
-                } catch (SecurityException e) {
-                }
+        // TODO: Android should ditch SecurityManager and the associated pollution.
+        List<InetAddress> result = new ArrayList<InetAddress>(addresses.size());
+        for (InetAddress address : addresses) {
+            try {
+                sm.checkConnect(address.getHostName(), CHECK_CONNECT_NO_PORT);
+            } catch (SecurityException e) {
+                continue;
             }
+            result.add(address);
         }
-
-        Enumeration<InetAddress> theAccessibleElements = accessibleAddresses
-                .elements();
-        if (theAccessibleElements.hasMoreElements()) {
-            return accessibleAddresses.elements();
-        }
-
-        return new Vector<InetAddress>(0).elements();
+        return Collections.enumeration(result);
     }
 
     /**
@@ -232,24 +193,13 @@
      * @throws NullPointerException
      *             if the given interface's name is {@code null}.
      */
-    public static NetworkInterface getByName(String interfaceName)
-            throws SocketException {
-
+    public static NetworkInterface getByName(String interfaceName) throws SocketException {
         if (interfaceName == null) {
             throw new NullPointerException(Msg.getString("K0330")); //$NON-NLS-1$
         }
-
-        /*
-         * get the list of interfaces, and then loop through the list to look
-         * for one with a matching name
-         */
-        Enumeration<NetworkInterface> interfaces = getNetworkInterfaces();
-        if (interfaces != null) {
-            while (interfaces.hasMoreElements()) {
-                NetworkInterface netif = interfaces.nextElement();
-                if (netif.getName().equals(interfaceName)) {
-                    return netif;
-                }
+        for (NetworkInterface networkInterface : getNetworkInterfacesList()) {
+            if (networkInterface.name.equals(interfaceName)) {
+                return networkInterface;
             }
         }
         return null;
@@ -268,38 +218,13 @@
      * @throws NullPointerException
      *             if the given interface address is invalid.
      */
-    public static NetworkInterface getByInetAddress(InetAddress address)
-            throws SocketException {
-
+    public static NetworkInterface getByInetAddress(InetAddress address) throws SocketException {
         if (address == null) {
             throw new NullPointerException(Msg.getString("K0331")); //$NON-NLS-1$
         }
-
-        /*
-         * get the list of interfaces, and then loop through the list. For each
-         * interface loop through the associated set of internet addresses and
-         * see if one matches. If so return that network interface
-         */
-        Enumeration<NetworkInterface> interfaces = getNetworkInterfaces();
-        if (interfaces != null) {
-            while (interfaces.hasMoreElements()) {
-                NetworkInterface netif = interfaces.nextElement();
-                /*
-                 * to be compatible use the raw addresses without any security
-                 * filtering
-                 */
-                // Enumeration netifAddresses = netif.getInetAddresses();
-                if ((netif.addresses != null) && (netif.addresses.length != 0)) {
-                    Enumeration<InetAddress> netifAddresses = (new Vector<InetAddress>(
-                            Arrays.asList(netif.addresses))).elements();
-                    if (netifAddresses != null) {
-                        while (netifAddresses.hasMoreElements()) {
-                            if (address.equals(netifAddresses.nextElement())) {
-                                return netif;
-                            }
-                        }
-                    }
-                }
+        for (NetworkInterface networkInterface : getNetworkInterfacesList()) {
+            if (networkInterface.addresses.contains(address)) {
+                return networkInterface;
             }
         }
         return null;
@@ -315,32 +240,53 @@
      *             if an error occurs while getting the network interface
      *             information.
      */
-    public static Enumeration<NetworkInterface> getNetworkInterfaces()
-            throws SocketException {
+    public static Enumeration<NetworkInterface> getNetworkInterfaces() throws SocketException {
+        return Collections.enumeration(getNetworkInterfacesList());
+    }
+
+    private static List<NetworkInterface> getNetworkInterfacesList() throws SocketException {
         NetworkInterface[] interfaces = getNetworkInterfacesImpl();
-        if (interfaces == null) {
-            return null;
-        }
 
         for (NetworkInterface netif : interfaces) {
             // Ensure that current NetworkInterface is bound to at least
             // one InetAddress before processing
-            if (netif.addresses != null) {
-                for (InetAddress addr : netif.addresses) {
-                    if (16 == addr.ipaddress.length) {
-                        if (addr.isLinkLocalAddress()
-                                || addr.isSiteLocalAddress()) {
-                            ((Inet6Address) addr).scopedIf = netif;
-                            ((Inet6Address) addr).ifname = netif.name;
-                            ((Inet6Address) addr).scope_ifname_set = true;
-                        }
+            for (InetAddress addr : netif.addresses) {
+                if (addr.ipaddress.length == 16) {
+                    if (addr.isLinkLocalAddress() || addr.isSiteLocalAddress()) {
+                        ((Inet6Address) addr).scopedIf = netif;
+                        ((Inet6Address) addr).ifname = netif.name;
+                        ((Inet6Address) addr).scope_ifname_set = true;
                     }
                 }
             }
         }
 
-        return (new Vector<NetworkInterface>(Arrays.asList(interfaces)))
-                .elements();
+        List<NetworkInterface> result = new ArrayList<NetworkInterface>();
+        boolean[] peeked = new boolean[interfaces.length];
+        for (int counter = 0; counter < interfaces.length; counter++) {
+            // If this interface has been touched, continue.
+            if (peeked[counter]) {
+                continue;
+            }
+            int counter2 = counter;
+            // Checks whether the following interfaces are children.
+            for (; counter2 < interfaces.length; counter2++) {
+                if (peeked[counter2]) {
+                    continue;
+                }
+                if (interfaces[counter2].name.startsWith(interfaces[counter].name + ":")) {
+                    // Tagged as peeked
+                    peeked[counter2] = true;
+                    interfaces[counter].children.add(interfaces[counter2]);
+                    interfaces[counter2].parent = interfaces[counter];
+                    interfaces[counter].addresses.addAll(interfaces[counter2].addresses);
+                }
+            }
+            // Tagged as peeked
+            result.add(interfaces[counter]);
+            peeked[counter] = true;
+        }
+        return result;
     }
 
     /**
@@ -357,77 +303,27 @@
      */
     @Override
     public boolean equals(Object obj) {
-        // Return true if it is the exact same object.
         if (obj == this) {
             return true;
         }
-
-        // Ensure it is the right type.
         if (!(obj instanceof NetworkInterface)) {
             return false;
         }
-
-        /*
-         * Make sure that some simple checks pass. If the name is not the same
-         * then we are sure it is not the same one. We don't check the hashcode
-         * as it is generated from the name which we check
-         */
-        NetworkInterface netif = (NetworkInterface) obj;
-
-        if (netif.getIndex() != interfaceIndex) {
-            return false;
-        }
-
-        if (!(name.equals("")) && (!netif.getName().equals(name))) { //$NON-NLS-1$
-            return false;
-        }
-
-        if ((name.equals("")) && (!netif.getName().equals(displayName))) { //$NON-NLS-1$
-            return false;
-        }
-
-        // Now check that the collection of internet addresses are equal.
-        Enumeration<InetAddress> netifAddresses = netif.getInetAddresses();
-        Enumeration<InetAddress> localifAddresses = getInetAddresses();
-
-        // Check for both null (same), or one null (not same).
-        if (netifAddresses == null) {
-            return localifAddresses == null;
-        }
-        if (localifAddresses == null) {
-            return false;
-        }
-
-        // Both are not null, check InetAddress elements.
-        while (netifAddresses.hasMoreElements()
-                && localifAddresses.hasMoreElements()) {
-            if (!(localifAddresses.nextElement()).equals(
-                    netifAddresses.nextElement())) {
-                return false;
-            }
-        }
-
-        /*
-         * Now make sure that they had the same number of addresses, if not they
-         * are not the same interface.
-         */
-        return !netifAddresses.hasMoreElements()
-                && !localifAddresses.hasMoreElements();
+        NetworkInterface rhs = (NetworkInterface) obj;
+        // TODO: should the order of the addresses matter (we use List.equals)?
+        return interfaceIndex == rhs.interfaceIndex &&
+                name.equals(rhs.name) && displayName.equals(rhs.displayName) &&
+                addresses.equals(rhs.addresses);
     }
 
     /**
-     * Gets the hashcode for this {@code NetworkInterface} instance. Since the
-     * name should be unique for each network interface the hashcode is
+     * Returns the hash code for this {@code NetworkInterface}. Since the
+     * name should be unique for each network interface the hash code is
      * generated using this name.
-     * 
-     * @return the hashcode value for this {@code NetworkInterface} instance.
      */
     @Override
     public int hashCode() {
-        if (hashCode == 0) {
-            hashCode = name.hashCode();
-        }
-        return hashCode;
+        return name.hashCode();
     }
 
     /**
@@ -464,4 +360,174 @@
         }
         return string.toString();
     }
+
+    /**
+     * Returns a List the InterfaceAddresses for this network interface.
+     * <p>
+     * If there is a security manager, its checkConnect method is called with
+     * the InetAddress for each InterfaceAddress. Only InterfaceAddresses where
+     * the checkConnect doesn't throw a SecurityException will be returned.
+     * 
+     * @return a List of the InterfaceAddresses for this network interface.
+     * @since 1.6
+     * @hide
+     */
+    public List<InterfaceAddress> getInterfaceAddresses() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            return Collections.unmodifiableList(interfaceAddresses);
+        }
+        // TODO: Android should ditch SecurityManager and the associated pollution.
+        List<InterfaceAddress> result = new ArrayList<InterfaceAddress>(interfaceAddresses.size());
+        for (InterfaceAddress ia : interfaceAddresses) {
+            try {
+                sm.checkConnect(ia.getAddress().getHostName(), CHECK_CONNECT_NO_PORT);
+            } catch (SecurityException e) {
+                continue;
+            }
+            result.add(ia);
+        }
+        return result;
+    }
+
+    /**
+     * Returns an {@code Enumeration} of all the sub-interfaces of this network interface.
+     * Sub-interfaces are also known as virtual interfaces.
+     * <p>
+     * For example, {@code eth0:1} would be a sub-interface of {@code eth0}.
+     * 
+     * @return an Enumeration of all the sub-interfaces of this network interface
+     * @since 1.6
+     * @hide
+     */
+    public Enumeration<NetworkInterface> getSubInterfaces() {
+        return Collections.enumeration(children);
+    }
+
+    /**
+     * Returns the parent NetworkInterface of this interface if this is a
+     * sub-interface, or null if it's a physical (non virtual) interface.
+     * 
+     * @return the NetworkInterface this interface is attached to.
+     * @since 1.6
+     * @hide
+     */
+    public NetworkInterface getParent() {
+        return parent;
+    }
+
+    /**
+     * Returns true if this network interface is up.
+     * 
+     * @return true if the interface is up.
+     * @throws SocketException if an I/O error occurs.
+     * @since 1.6
+     * @hide
+     */
+    public boolean isUp() throws SocketException {
+        if (addresses.isEmpty()) {
+            return false;
+        }
+        return isUpImpl(name, interfaceIndex);
+    }
+    private static native boolean isUpImpl(String n, int index) throws SocketException;
+
+    /**
+     * Returns true if this network interface is a loopback interface.
+     * 
+     * @return true if the interface is a loopback interface.
+     * @throws SocketException if an I/O error occurs.
+     * @since 1.6
+     * @hide
+     */
+    public boolean isLoopback() throws SocketException {
+        if (addresses.isEmpty()) {
+            return false;
+        }
+        return isLoopbackImpl(name, interfaceIndex);
+    }
+    private static native boolean isLoopbackImpl(String n, int index) throws SocketException;
+
+    /**
+     * Returns true if this network interface is a point-to-point interface.
+     * (For example, a PPP connection using a modem.)
+     * 
+     * @return true if the interface is point-to-point.
+     * @throws SocketException if an I/O error occurs.
+     * @since 1.6
+     * @hide
+     */
+    public boolean isPointToPoint() throws SocketException {
+        if (addresses.isEmpty()) {
+            return false;
+        }
+        return isPointToPointImpl(name, interfaceIndex);
+    }
+    private static native boolean isPointToPointImpl(String n, int index) throws SocketException;
+
+    /**
+     * Returns true if this network interface supports multicast.
+     * 
+     * @throws SocketException if an I/O error occurs.
+     * @since 1.6
+     * @hide
+     */
+    public boolean supportsMulticast() throws SocketException {
+        if (addresses.isEmpty()) {
+            return false;
+        }
+        return supportsMulticastImpl(name, interfaceIndex);
+    }
+    private static native boolean supportsMulticastImpl(String n, int index) throws SocketException;
+
+    /**
+     * Returns the hardware address of the interface, if it has one, and the
+     * user has the necessary privileges to access the address.
+     * 
+     * @return a byte array containing the address or null if the address
+     *         doesn't exist or is not accessible.
+     * @throws SocketException if an I/O error occurs.
+     * @since 1.6
+     * @hide
+     */
+    public byte[] getHardwareAddress() throws SocketException {
+        if (addresses.isEmpty()) {
+            return new byte[0];
+        }
+        return getHardwareAddressImpl(name, interfaceIndex);
+    }
+    private static native byte[] getHardwareAddressImpl(String n, int index) throws SocketException;
+
+    /**
+     * Returns the Maximum Transmission Unit (MTU) of this interface.
+     * 
+     * @return the value of the MTU for the interface.
+     * @throws SocketException if an I/O error occurs.
+     * @since 1.6
+     * @hide
+     */
+    public int getMTU() throws SocketException {
+        if (addresses.isEmpty()) {
+            return 0;
+        }
+        return getMTUImpl(name, interfaceIndex);
+    }
+    private static native int getMTUImpl(String n, int index) throws SocketException;
+
+    /**
+     * Returns true if this interface is a virtual interface (also called
+     * a sub-interface). Virtual interfaces are, on some systems, interfaces
+     * created as a child of a physical interface and given different settings
+     * (like address or MTU). Usually the name of the interface will the name of
+     * the parent followed by a colon (:) and a number identifying the child,
+     * since there can be several virtual interfaces attached to a single
+     * physical interface.
+     * 
+     * @return true if this interface is a virtual interface.
+     * @since 1.6
+     * @hide
+     */
+    public boolean isVirtual() {
+        return parent != null;
+    }
 }
diff --git a/luni/src/main/java/java/net/ProxySelectorImpl.java b/luni/src/main/java/java/net/ProxySelectorImpl.java
index fa8d049..8230f99 100644
--- a/luni/src/main/java/java/net/ProxySelectorImpl.java
+++ b/luni/src/main/java/java/net/ProxySelectorImpl.java
@@ -56,9 +56,7 @@
                 if (f.exists()) {
                     try {
                         FileInputStream fis = new FileInputStream(f);
-                        // BEGIN android-modified
-                        InputStream is = new BufferedInputStream(fis, 8192);
-                        // END android-modified
+                        InputStream is = new BufferedInputStream(fis);
                         netProps = new Properties();
                         netProps.load(is);
                         is.close();
diff --git a/luni/src/main/java/java/net/ServerSocket.java b/luni/src/main/java/java/net/ServerSocket.java
index 2fe6b5c..ce7b84f 100644
--- a/luni/src/main/java/java/net/ServerSocket.java
+++ b/luni/src/main/java/java/net/ServerSocket.java
@@ -61,13 +61,7 @@
     }
 
     /**
-     * Unspecified constructor.
-     *
-     * Warning: this function is technically part of API#1.
-     * Hiding it for API#2 broke source compatibility.
-     * Removing it entirely would theoretically break binary compatibility,
-     *     and would be better done with some visibility over the extent
-     *     of the compatibility breakage (expected to be non-existent).
+     * Unspecified constructor needed by ServerSocketChannelImpl.ServerSocketAdapter.
      *
      * @hide
      */
diff --git a/luni/src/main/java/java/net/Socket.java b/luni/src/main/java/java/net/Socket.java
index 2962b62..208bc09 100644
--- a/luni/src/main/java/java/net/Socket.java
+++ b/luni/src/main/java/java/net/Socket.java
@@ -61,14 +61,8 @@
 
     private Proxy proxy;
 
-    static final int MULTICAST_IF = 1;
-
-    static final int MULTICAST_TTL = 2;
-
     static final int TCP_NODELAY = 4;
 
-    static final int FLAG_SHUTDOWN = 8;
-
     static private Logger logger;
 
     static private Logger getLogger() {
diff --git a/luni/src/main/java/java/net/URI.java b/luni/src/main/java/java/net/URI.java
index 85c16eb..926ec3c 100644
--- a/luni/src/main/java/java/net/URI.java
+++ b/luni/src/main/java/java/net/URI.java
@@ -23,56 +23,41 @@
 import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.util.StringTokenizer;
-
-import org.apache.harmony.luni.util.Msg;
+import org.apache.harmony.luni.platform.INetworkSystem;
+import org.apache.harmony.luni.platform.Platform;
 
 /**
  * This class represents an instance of a URI as defined by RFC 2396.
  */
 public final class URI implements Comparable<URI>, Serializable {
 
+    private final static INetworkSystem NETWORK_SYSTEM = Platform.getNetworkSystem();
+
     private static final long serialVersionUID = -6052424284110960213l;
 
-    static final String unreserved = "_-!.~\'()*"; //$NON-NLS-1$
-
-    static final String punct = ",;:$&+="; //$NON-NLS-1$
-
-    static final String reserved = punct + "?/[]@"; //$NON-NLS-1$
-
-    static final String someLegal = unreserved + punct;
-
-    static final String allLegal = unreserved + reserved;
+    static final String UNRESERVED = "_-!.~\'()*";
+    static final String PUNCTUATION = ",;:$&+=";
+    static final String RESERVED = PUNCTUATION + "?/[]@";
+    static final String SOME_LEGAL = UNRESERVED + PUNCTUATION;
+    static final String ALL_LEGAL = UNRESERVED + RESERVED;
 
     private String string;
-
     private transient String scheme;
-
-    private transient String schemespecificpart;
-
+    private transient String schemeSpecificPart;
     private transient String authority;
-
-    private transient String userinfo;
-
+    private transient String userInfo;
     private transient String host;
-
     private transient int port = -1;
-
     private transient String path;
-
     private transient String query;
-
     private transient String fragment;
-
     private transient boolean opaque;
-
     private transient boolean absolute;
-
     private transient boolean serverAuthority = false;
 
     private transient int hash = -1;
 
-    private URI() {
-    }
+    private URI() {}
 
     /**
      * Creates a new URI instance according to the given string {@code uri}.
@@ -84,7 +69,7 @@
      *             specification RFC2396 or could not be parsed correctly.
      */
     public URI(String uri) throws URISyntaxException {
-        new Helper().parseURI(uri, false);
+        parseURI(uri, false);
     }
 
     /**
@@ -113,15 +98,15 @@
         }
         if (ssp != null) {
             // QUOTE ILLEGAL CHARACTERS
-            uri.append(quoteComponent(ssp, allLegal));
+            uri.append(quoteComponent(ssp, ALL_LEGAL));
         }
         if (frag != null) {
             uri.append('#');
             // QUOTE ILLEGAL CHARACTERS
-            uri.append(quoteComponent(frag, allLegal));
+            uri.append(quoteComponent(frag, ALL_LEGAL));
         }
 
-        new Helper().parseURI(uri.toString(), false);
+        parseURI(uri.toString(), false);
     }
 
     /**
@@ -133,7 +118,7 @@
      *
      * @param scheme
      *            the scheme part of the URI.
-     * @param userinfo
+     * @param userInfo
      *            the user information of the URI for authentication and
      *            authorization.
      * @param host
@@ -151,19 +136,19 @@
      *             if the temporary created string doesn't fit to the
      *             specification RFC2396 or could not be parsed correctly.
      */
-    public URI(String scheme, String userinfo, String host, int port,
+    public URI(String scheme, String userInfo, String host, int port,
             String path, String query, String fragment)
             throws URISyntaxException {
 
-        if (scheme == null && userinfo == null && host == null && path == null
+        if (scheme == null && userInfo == null && host == null && path == null
                 && query == null && fragment == null) {
-            this.path = ""; //$NON-NLS-1$
+            this.path = "";
             return;
         }
 
         if (scheme != null && path != null && path.length() > 0
                 && path.charAt(0) != '/') {
-            throw new URISyntaxException(path, Msg.getString("K0302")); //$NON-NLS-1$
+            throw new URISyntaxException(path, "Relative path");
         }
 
         StringBuilder uri = new StringBuilder();
@@ -172,22 +157,22 @@
             uri.append(':');
         }
 
-        if (userinfo != null || host != null || port != -1) {
-            uri.append("//"); //$NON-NLS-1$
+        if (userInfo != null || host != null || port != -1) {
+            uri.append("//");
         }
 
-        if (userinfo != null) {
-            // QUOTE ILLEGAL CHARACTERS in userinfo
-            uri.append(quoteComponent(userinfo, someLegal));
+        if (userInfo != null) {
+            // QUOTE ILLEGAL CHARACTERS in userInfo
+            uri.append(quoteComponent(userInfo, SOME_LEGAL));
             uri.append('@');
         }
 
         if (host != null) {
-            // check for ipv6 addresses that hasn't been enclosed
+            // check for IPv6 addresses that hasn't been enclosed
             // in square brackets
             if (host.indexOf(':') != -1 && host.indexOf(']') == -1
                     && host.indexOf('[') == -1) {
-                host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+                host = "[" + host + "]";
             }
             uri.append(host);
         }
@@ -199,22 +184,22 @@
 
         if (path != null) {
             // QUOTE ILLEGAL CHARS
-            uri.append(quoteComponent(path, "/@" + someLegal)); //$NON-NLS-1$
+            uri.append(quoteComponent(path, "/@" + SOME_LEGAL));
         }
 
         if (query != null) {
             uri.append('?');
             // QUOTE ILLEGAL CHARS
-            uri.append(quoteComponent(query, allLegal));
+            uri.append(quoteComponent(query, ALL_LEGAL));
         }
 
         if (fragment != null) {
             // QUOTE ILLEGAL CHARS
             uri.append('#');
-            uri.append(quoteComponent(fragment, allLegal));
+            uri.append(quoteComponent(fragment, ALL_LEGAL));
         }
 
-        new Helper().parseURI(uri.toString(), true);
+        parseURI(uri.toString(), true);
     }
 
     /**
@@ -267,7 +252,7 @@
             String fragment) throws URISyntaxException {
         if (scheme != null && path != null && path.length() > 0
                 && path.charAt(0) != '/') {
-            throw new URISyntaxException(path, Msg.getString("K0302")); //$NON-NLS-1$
+            throw new URISyntaxException(path, "Relative path");
         }
 
         StringBuilder uri = new StringBuilder();
@@ -276,552 +261,375 @@
             uri.append(':');
         }
         if (authority != null) {
-            uri.append("//"); //$NON-NLS-1$
+            uri.append("//");
             // QUOTE ILLEGAL CHARS
-            uri.append(quoteComponent(authority, "@[]" + someLegal)); //$NON-NLS-1$
+            uri.append(quoteComponent(authority, "@[]" + SOME_LEGAL));
         }
 
         if (path != null) {
             // QUOTE ILLEGAL CHARS
-            uri.append(quoteComponent(path, "/@" + someLegal)); //$NON-NLS-1$
+            uri.append(quoteComponent(path, "/@" + SOME_LEGAL));
         }
         if (query != null) {
             // QUOTE ILLEGAL CHARS
             uri.append('?');
-            uri.append(quoteComponent(query, allLegal));
+            uri.append(quoteComponent(query, ALL_LEGAL));
         }
         if (fragment != null) {
             // QUOTE ILLEGAL CHARS
             uri.append('#');
-            uri.append(quoteComponent(fragment, allLegal));
+            uri.append(quoteComponent(fragment, ALL_LEGAL));
         }
 
-        new Helper().parseURI(uri.toString(), false);
+        parseURI(uri.toString(), false);
     }
 
-    private class Helper {
+    private void parseURI(String uri, boolean forceServer) throws URISyntaxException {
+        String temp = uri;
+        // assign uri string to the input value per spec
+        string = uri;
+        int index, index1, index2, index3;
+        // parse into Fragment, Scheme, and SchemeSpecificPart
+        // then parse SchemeSpecificPart if necessary
 
-        private void parseURI(String uri, boolean forceServer)
-                throws URISyntaxException {
-            String temp = uri;
-            // assign uri string to the input value per spec
-            string = uri;
-            int index, index1, index2, index3;
-            // parse into Fragment, Scheme, and SchemeSpecificPart
-            // then parse SchemeSpecificPart if necessary
+        // Fragment
+        index = temp.indexOf('#');
+        if (index != -1) {
+            // remove the fragment from the end
+            fragment = temp.substring(index + 1);
+            validateFragment(uri, fragment, index + 1);
+            temp = temp.substring(0, index);
+        }
 
-            // Fragment
-            index = temp.indexOf('#');
+        // Scheme and SchemeSpecificPart
+        index = index1 = temp.indexOf(':');
+        index2 = temp.indexOf('/');
+        index3 = temp.indexOf('?');
+
+        // if a '/' or '?' occurs before the first ':' the uri has no
+        // specified scheme, and is therefore not absolute
+        if (index != -1 && (index2 >= index || index2 == -1)
+                && (index3 >= index || index3 == -1)) {
+            // the characters up to the first ':' comprise the scheme
+            absolute = true;
+            scheme = temp.substring(0, index);
+            if (scheme.length() == 0) {
+                throw new URISyntaxException(uri, "Scheme expected", index);
+            }
+            validateScheme(uri, scheme, 0);
+            schemeSpecificPart = temp.substring(index + 1);
+            if (schemeSpecificPart.length() == 0) {
+                throw new URISyntaxException(uri, "Scheme-specific part expected", index + 1);
+            }
+        } else {
+            absolute = false;
+            schemeSpecificPart = temp;
+        }
+
+        if (scheme == null || schemeSpecificPart.length() > 0
+                && schemeSpecificPart.charAt(0) == '/') {
+            opaque = false;
+            // the URI is hierarchical
+
+            // Query
+            temp = schemeSpecificPart;
+            index = temp.indexOf('?');
             if (index != -1) {
-                // remove the fragment from the end
-                fragment = temp.substring(index + 1);
-                validateFragment(uri, fragment, index + 1);
+                query = temp.substring(index + 1);
                 temp = temp.substring(0, index);
+                validateQuery(uri, query, index2 + 1 + index);
             }
 
-            // Scheme and SchemeSpecificPart
-            index = index1 = temp.indexOf(':');
-            index2 = temp.indexOf('/');
-            index3 = temp.indexOf('?');
-
-            // if a '/' or '?' occurs before the first ':' the uri has no
-            // specified scheme, and is therefore not absolute
-            if (index != -1 && (index2 >= index || index2 == -1)
-                    && (index3 >= index || index3 == -1)) {
-                // the characters up to the first ':' comprise the scheme
-                absolute = true;
-                scheme = temp.substring(0, index);
-                if (scheme.length() == 0) {
-                    throw new URISyntaxException(uri, Msg.getString("K0342"), //$NON-NLS-1$
-                            index);
-                }
-                validateScheme(uri, scheme, 0);
-                schemespecificpart = temp.substring(index + 1);
-                if (schemespecificpart.length() == 0) {
-                    throw new URISyntaxException(uri, Msg.getString("K0303"), //$NON-NLS-1$
-                            index + 1);
-                }
-            } else {
-                absolute = false;
-                schemespecificpart = temp;
-            }
-
-            if (scheme == null || schemespecificpart.length() > 0
-                    && schemespecificpart.charAt(0) == '/') {
-                opaque = false;
-                // the URI is hierarchical
-
-                // Query
-                temp = schemespecificpart;
-                index = temp.indexOf('?');
+            // Authority and Path
+            if (temp.startsWith("//")) {
+                index = temp.indexOf('/', 2);
                 if (index != -1) {
-                    query = temp.substring(index + 1);
-                    temp = temp.substring(0, index);
-                    validateQuery(uri, query, index2 + 1 + index);
-                }
-
-                // Authority and Path
-                if (temp.startsWith("//")) { //$NON-NLS-1$
-                    index = temp.indexOf('/', 2);
-                    if (index != -1) {
-                        authority = temp.substring(2, index);
-                        path = temp.substring(index);
-                    } else {
-                        authority = temp.substring(2);
-                        if (authority.length() == 0 && query == null
-                                && fragment == null) {
-                            throw new URISyntaxException(uri, Msg
-                                    .getString("K0304"), uri.length()); //$NON-NLS-1$
-                        }
-
-                        path = ""; //$NON-NLS-1$
-                        // nothing left, so path is empty (not null, path should
-                        // never be null)
+                    authority = temp.substring(2, index);
+                    path = temp.substring(index);
+                } else {
+                    authority = temp.substring(2);
+                    if (authority.length() == 0 && query == null
+                            && fragment == null) {
+                        throw new URISyntaxException(uri, "Authority expected", uri.length());
                     }
 
-                    if (authority.length() == 0) {
-                        authority = null;
-                    } else {
-                        validateAuthority(uri, authority, index1 + 3);
-                    }
-                } else { // no authority specified
-                    path = temp;
+                    path = "";
+                    // nothing left, so path is empty (not null, path should
+                    // never be null)
                 }
 
-                int pathIndex = 0;
-                if (index2 > -1) {
-                    pathIndex += index2;
+                if (authority.length() == 0) {
+                    authority = null;
+                } else {
+                    validateAuthority(uri, authority, index1 + 3);
                 }
-                if (index > -1) {
-                    pathIndex += index;
-                }
-                validatePath(uri, path, pathIndex);
-            } else { // if not hierarchical, URI is opaque
-                opaque = true;
-                validateSsp(uri, schemespecificpart, index2 + 2 + index);
+            } else { // no authority specified
+                path = temp;
             }
 
-            parseAuthority(forceServer);
+            int pathIndex = 0;
+            if (index2 > -1) {
+                pathIndex += index2;
+            }
+            if (index > -1) {
+                pathIndex += index;
+            }
+            validatePath(uri, path, pathIndex);
+        } else { // if not hierarchical, URI is opaque
+            opaque = true;
+            validateSsp(uri, schemeSpecificPart, index2 + 2 + index);
         }
 
-        private void validateScheme(String uri, String scheme, int index)
-                throws URISyntaxException {
-            // first char needs to be an alpha char
-            char ch = scheme.charAt(0);
-            if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
-                throw new URISyntaxException(uri, Msg.getString("K0305"), 0); //$NON-NLS-1$
-            }
+        parseAuthority(forceServer);
+    }
 
-            try {
-                URIEncoderDecoder.validateSimple(scheme, "+-."); //$NON-NLS-1$
-            } catch (URISyntaxException e) {
-                throw new URISyntaxException(uri, Msg.getString("K0305"), index //$NON-NLS-1$
-                        + e.getIndex());
-            }
+    private void validateScheme(String uri, String scheme, int index)
+            throws URISyntaxException {
+        // first char needs to be an alpha char
+        char ch = scheme.charAt(0);
+        if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) {
+            throw new URISyntaxException(uri, "Illegal character in scheme", 0);
         }
 
-        private void validateSsp(String uri, String ssp, int index)
-                throws URISyntaxException {
-            try {
-                URIEncoderDecoder.validate(ssp, allLegal);
-            } catch (URISyntaxException e) {
-                throw new URISyntaxException(uri, Msg.getString("K0306", e //$NON-NLS-1$
-                        .getReason()), index + e.getIndex());
-            }
+        try {
+            URIEncoderDecoder.validateSimple(scheme, "+-.");
+        } catch (URISyntaxException e) {
+            throw new URISyntaxException(uri, "Illegal character in scheme", index + e.getIndex());
+        }
+    }
+
+    private void validateSsp(String uri, String ssp, int index)
+            throws URISyntaxException {
+        try {
+            URIEncoderDecoder.validate(ssp, ALL_LEGAL);
+        } catch (URISyntaxException e) {
+            throw new URISyntaxException(uri,
+                    e.getReason() + " in schemeSpecificPart", index + e.getIndex());
+        }
+    }
+
+    private void validateAuthority(String uri, String authority, int index)
+            throws URISyntaxException {
+        try {
+            URIEncoderDecoder.validate(authority, "@[]" + SOME_LEGAL);
+        } catch (URISyntaxException e) {
+            throw new URISyntaxException(uri, e.getReason() + " in authority", index + e.getIndex());
+        }
+    }
+
+    private void validatePath(String uri, String path, int index)
+            throws URISyntaxException {
+        try {
+            URIEncoderDecoder.validate(path, "/@" + SOME_LEGAL);
+        } catch (URISyntaxException e) {
+            throw new URISyntaxException(uri, e.getReason() + " in path", index + e.getIndex());
+        }
+    }
+
+    private void validateQuery(String uri, String query, int index)
+            throws URISyntaxException {
+        try {
+            URIEncoderDecoder.validate(query, ALL_LEGAL);
+        } catch (URISyntaxException e) {
+            throw new URISyntaxException(uri, e.getReason() + " in query", index + e.getIndex());
+
+        }
+    }
+
+    private void validateFragment(String uri, String fragment, int index)
+            throws URISyntaxException {
+        try {
+            URIEncoderDecoder.validate(fragment, ALL_LEGAL);
+        } catch (URISyntaxException e) {
+            throw new URISyntaxException(uri, e.getReason() + " in fragment", index + e.getIndex());
+        }
+    }
+
+    /**
+     * Parse the authority string into its component parts: user info,
+     * host, and port. This operation doesn't apply to registry URIs, and
+     * calling it on such <i>may</i> result in a syntax exception.
+     *
+     * @param forceServer true to always throw if the authority cannot be
+     *     parsed. If false, this method may still throw for some kinds of
+     *     errors; this unpredictable behaviour is consistent with the RI.
+     */
+    private void parseAuthority(boolean forceServer) throws URISyntaxException {
+        if (authority == null) {
+            return;
         }
 
-        private void validateAuthority(String uri, String authority, int index)
-                throws URISyntaxException {
-            try {
-                URIEncoderDecoder.validate(authority, "@[]" + someLegal); //$NON-NLS-1$
-            } catch (URISyntaxException e) {
-                throw new URISyntaxException(uri, Msg.getString("K0307", e //$NON-NLS-1$
-                        .getReason()), index + e.getIndex());
-            }
+        String tempUserInfo = null;
+        String temp = authority;
+        int index = temp.indexOf('@');
+        int hostIndex = 0;
+        if (index != -1) {
+            // remove user info
+            tempUserInfo = temp.substring(0, index);
+            validateUserInfo(authority, tempUserInfo, 0);
+            temp = temp.substring(index + 1); // host[:port] is left
+            hostIndex = index + 1;
         }
 
-        private void validatePath(String uri, String path, int index)
-                throws URISyntaxException {
-            try {
-                URIEncoderDecoder.validate(path, "/@" + someLegal); //$NON-NLS-1$
-            } catch (URISyntaxException e) {
-                throw new URISyntaxException(uri, Msg.getString("K0308", e //$NON-NLS-1$
-                        .getReason()), index + e.getIndex());
-            }
-        }
+        index = temp.lastIndexOf(':');
+        int endIndex = temp.indexOf(']');
 
-        private void validateQuery(String uri, String query, int index)
-                throws URISyntaxException {
-            try {
-                URIEncoderDecoder.validate(query, allLegal);
-            } catch (URISyntaxException e) {
-                throw new URISyntaxException(uri, Msg.getString("K0309", e //$NON-NLS-1$
-                        .getReason()), index + e.getIndex());
+        String tempHost;
+        int tempPort = -1;
+        if (index != -1 && endIndex < index) {
+            // determine port and host
+            tempHost = temp.substring(0, index);
 
-            }
-        }
-
-        private void validateFragment(String uri, String fragment, int index)
-                throws URISyntaxException {
-            try {
-                URIEncoderDecoder.validate(fragment, allLegal);
-            } catch (URISyntaxException e) {
-                throw new URISyntaxException(uri, Msg.getString("K030a", e //$NON-NLS-1$
-                        .getReason()), index + e.getIndex());
-            }
-        }
-
-        /**
-         * determine the host, port and userinfo if the authority parses
-         * successfully to a server based authority
-         * 
-         * behavour in error cases: if forceServer is true, throw
-         * URISyntaxException with the proper diagnostic messages. if
-         * forceServer is false assume this is a registry based uri, and just
-         * return leaving the host, port and userinfo fields undefined.
-         * 
-         * and there are some error cases where URISyntaxException is thrown
-         * regardless of the forceServer parameter e.g. malformed ipv6 address
-         */
-        private void parseAuthority(boolean forceServer)
-                throws URISyntaxException {
-            if (authority == null) {
-                return;
-            }
-
-            String temp, tempUserinfo = null, tempHost = null;
-            int index, hostindex = 0;
-            int tempPort = -1;
-
-            temp = authority;
-            index = temp.indexOf('@');
-            if (index != -1) {
-                // remove user info
-                tempUserinfo = temp.substring(0, index);
-                validateUserinfo(authority, tempUserinfo, 0);
-                temp = temp.substring(index + 1); // host[:port] is left
-                hostindex = index + 1;
-            }
-
-            index = temp.lastIndexOf(':');
-            int endindex = temp.indexOf(']');
-
-            if (index != -1 && endindex < index) {
-                // determine port and host
-                tempHost = temp.substring(0, index);
-
-                if (index < (temp.length() - 1)) { // port part is not empty
-                    try {
-                        tempPort = Integer.parseInt(temp.substring(index + 1));
-                        if (tempPort < 0) {
-                            if (forceServer) {
-                                throw new URISyntaxException(
-                                        authority,
-                                        Msg.getString("K00b1"), hostindex + index + 1); //$NON-NLS-1$
-                            }
-                            return;
-                        }
-                    } catch (NumberFormatException e) {
+            if (index < (temp.length() - 1)) { // port part is not empty
+                try {
+                    tempPort = Integer.parseInt(temp.substring(index + 1));
+                    if (tempPort < 0) {
                         if (forceServer) {
-                            throw new URISyntaxException(authority, Msg
-                                    .getString("K00b1"), hostindex + index + 1); //$NON-NLS-1$
+                            throw new URISyntaxException(authority,
+                                    "Invalid port number", hostIndex + index + 1);
                         }
                         return;
                     }
+                } catch (NumberFormatException e) {
+                    if (forceServer) {
+                        throw new URISyntaxException(authority,
+                                "Invalid port number", hostIndex + index + 1);
+                    }
+                    return;
                 }
-            } else {
-                tempHost = temp;
             }
-
-            if (tempHost.equals("")) { //$NON-NLS-1$
-                if (forceServer) {
-                    throw new URISyntaxException(authority, Msg
-                            .getString("K030c"), hostindex); //$NON-NLS-1$
-                }
-                return;
-            }
-
-            if (!isValidHost(forceServer, tempHost)) {
-                return;
-            }
-
-            // this is a server based uri,
-            // fill in the userinfo, host and port fields
-            userinfo = tempUserinfo;
-            host = tempHost;
-            port = tempPort;
-            serverAuthority = true;
+        } else {
+            tempHost = temp;
         }
 
-        private void validateUserinfo(String uri, String userinfo, int index)
-                throws URISyntaxException {
-            for (int i = 0; i < userinfo.length(); i++) {
-                char ch = userinfo.charAt(i);
-                if (ch == ']' || ch == '[') {
-                    throw new URISyntaxException(uri, Msg.getString("K030d"), //$NON-NLS-1$
-                            index + i);
-                }
+        if (tempHost.equals("")) {
+            if (forceServer) {
+                throw new URISyntaxException(authority, "Expected host", hostIndex);
             }
+            return;
         }
 
-        /**
-         * distinguish between IPv4, IPv6, domain name and validate it based on
-         * its type
-         */
-        private boolean isValidHost(boolean forceServer, String host)
-                throws URISyntaxException {
-            if (host.charAt(0) == '[') {
-                // ipv6 address
-                if (host.charAt(host.length() - 1) != ']') {
-                    throw new URISyntaxException(host,
-                            Msg.getString("K030e"), 0); //$NON-NLS-1$
-                }
-                if (!isValidIP6Address(host)) {
-                    throw new URISyntaxException(host, Msg.getString("K030f")); //$NON-NLS-1$
-                }
-                return true;
-            }
+        if (!isValidHost(forceServer, tempHost)) {
+            return;
+        }
 
-            // '[' and ']' can only be the first char and last char
-            // of the host name
-            if (host.indexOf('[') != -1 || host.indexOf(']') != -1) {
-                throw new URISyntaxException(host, Msg.getString("K0310"), 0); //$NON-NLS-1$
-            }
+        // this is a server based uri,
+        // fill in the userInfo, host and port fields
+        userInfo = tempUserInfo;
+        host = tempHost;
+        port = tempPort;
+        serverAuthority = true;
+    }
 
-            int index = host.lastIndexOf('.');
-            if (index < 0 || index == host.length() - 1
-                    || !Character.isDigit(host.charAt(index + 1))) {
-                // domain name
-                if (isValidDomainName(host)) {
+    private void validateUserInfo(String uri, String userInfo, int index)
+            throws URISyntaxException {
+        for (int i = 0; i < userInfo.length(); i++) {
+            char ch = userInfo.charAt(i);
+            if (ch == ']' || ch == '[') {
+                throw new URISyntaxException(uri, "Illegal character in userInfo", index + i);
+            }
+        }
+    }
+
+    /**
+     * Returns true if {@code host} is a well-formed host name or IP address.
+     *
+     * @param forceServer true to always throw if the host cannot be parsed. If
+     *     false, this method may still throw for some kinds of errors; this
+     *     unpredictable behaviour is consistent with the RI.
+     */
+    private boolean isValidHost(boolean forceServer, String host) throws URISyntaxException {
+        if (host.startsWith("[")) {
+            // IPv6 address
+            if (!host.endsWith("]")) {
+                throw new URISyntaxException(host,
+                        "Expected a closing square bracket for IPv6 address", 0);
+            }
+            try {
+                byte[] bytes = NETWORK_SYSTEM.ipStringToByteArray(host);
+                /*
+                 * The native IP parser may return 4 bytes for addresses like
+                 * "[::FFFF:127.0.0.1]". This is allowed, but we must not accept
+                 * IPv4-formatted addresses in square braces like "[127.0.0.1]".
+                 */
+                if (bytes.length == 16 || bytes.length == 4 && host.contains(":")) {
                     return true;
                 }
-                if (forceServer) {
-                    throw new URISyntaxException(host,
-                            Msg.getString("K0310"), 0); //$NON-NLS-1$
-                }
-                return false;
+            } catch (UnknownHostException e) {
             }
+            throw new URISyntaxException(host, "Malformed IPv6 address");
+        }
 
-            // IPv4 address
-            if (isValidIPv4Address(host)) {
+        // '[' and ']' can only be the first char and last char
+        // of the host name
+        if (host.indexOf('[') != -1 || host.indexOf(']') != -1) {
+            throw new URISyntaxException(host, "Illegal character in host name", 0);
+        }
+
+        int index = host.lastIndexOf('.');
+        if (index < 0 || index == host.length() - 1
+                || !Character.isDigit(host.charAt(index + 1))) {
+            // domain name
+            if (isValidDomainName(host)) {
                 return true;
             }
             if (forceServer) {
-                throw new URISyntaxException(host, Msg.getString("K0311"), 0); //$NON-NLS-1$
+                throw new URISyntaxException(host, "Illegal character in host name", 0);
             }
             return false;
         }
 
-        private boolean isValidDomainName(String host) {
-            try {
-                URIEncoderDecoder.validateSimple(host, "-."); //$NON-NLS-1$
-            } catch (URISyntaxException e) {
-                return false;
+        // IPv4 address
+        try {
+            if (NETWORK_SYSTEM.ipStringToByteArray(host).length == 4) {
+                return true;
             }
-
-            String label = null;
-            StringTokenizer st = new StringTokenizer(host, "."); //$NON-NLS-1$
-            while (st.hasMoreTokens()) {
-                label = st.nextToken();
-                if (label.startsWith("-") || label.endsWith("-")) { //$NON-NLS-1$ //$NON-NLS-2$
-                    return false;
-                }
-            }
-
-            if (!label.equals(host)) {
-                char ch = label.charAt(0);
-                if (ch >= '0' && ch <= '9') {
-                    return false;
-                }
-            }
-            return true;
+        } catch (UnknownHostException e) {
         }
 
-        private boolean isValidIPv4Address(String host) {
-            int index;
-            int index2;
-            try {
-                int num;
-                index = host.indexOf('.');
-                num = Integer.parseInt(host.substring(0, index));
-                if (num < 0 || num > 255) {
-                    return false;
-                }
-                index2 = host.indexOf('.', index + 1);
-                num = Integer.parseInt(host.substring(index + 1, index2));
-                if (num < 0 || num > 255) {
-                    return false;
-                }
-                index = host.indexOf('.', index2 + 1);
-                num = Integer.parseInt(host.substring(index2 + 1, index));
-                if (num < 0 || num > 255) {
-                    return false;
-                }
-                num = Integer.parseInt(host.substring(index + 1));
-                if (num < 0 || num > 255) {
-                    return false;
-                }
-            } catch (Exception e) {
-                return false;
-            }
-            return true;
+        if (forceServer) {
+            throw new URISyntaxException(host, "Malformed IPv4 address", 0);
         }
-
-        private boolean isValidIP6Address(String ipAddress) {
-            int length = ipAddress.length();
-            boolean doubleColon = false;
-            int numberOfColons = 0;
-            int numberOfPeriods = 0;
-            String word = ""; //$NON-NLS-1$
-            char c = 0;
-            char prevChar = 0;
-            int offset = 0; // offset for [] ip addresses
-
-            if (length < 2) {
-                return false;
-            }
-
-            for (int i = 0; i < length; i++) {
-                prevChar = c;
-                c = ipAddress.charAt(i);
-                switch (c) {
-
-                    // case for an open bracket [x:x:x:...x]
-                    case '[':
-                        if (i != 0) {
-                            return false; // must be first character
-                        }
-                        if (ipAddress.charAt(length - 1) != ']') {
-                            return false; // must have a close ]
-                        }
-                        if ((ipAddress.charAt(1) == ':')
-                                && (ipAddress.charAt(2) != ':')) {
-                            return false;
-                        }
-                        offset = 1;
-                        if (length < 4) {
-                            return false;
-                        }
-                        break;
-
-                    // case for a closed bracket at end of IP [x:x:x:...x]
-                    case ']':
-                        if (i != length - 1) {
-                            return false; // must be last character
-                        }
-                        if (ipAddress.charAt(0) != '[') {
-                            return false; // must have a open [
-                        }
-                        break;
-
-                    // case for the last 32-bits represented as IPv4
-                    // x:x:x:x:x:x:d.d.d.d
-                    case '.':
-                        numberOfPeriods++;
-                        if (numberOfPeriods > 3) {
-                            return false;
-                        }
-                        if (!isValidIP4Word(word)) {
-                            return false;
-                        }
-                        if (numberOfColons != 6 && !doubleColon) {
-                            return false;
-                        }
-                        // a special case ::1:2:3:4:5:d.d.d.d allows 7 colons
-                        // with
-                        // an IPv4 ending, otherwise 7 :'s is bad
-                        if (numberOfColons == 7
-                                && ipAddress.charAt(0 + offset) != ':'
-                                && ipAddress.charAt(1 + offset) != ':') {
-                            return false;
-                        }
-                        word = ""; //$NON-NLS-1$
-                        break;
-
-                    case ':':
-                        numberOfColons++;
-                        if (numberOfColons > 7) {
-                            return false;
-                        }
-                        if (numberOfPeriods > 0) {
-                            return false;
-                        }
-                        if (prevChar == ':') {
-                            if (doubleColon) {
-                                return false;
-                            }
-                            doubleColon = true;
-                        }
-                        word = ""; //$NON-NLS-1$
-                        break;
-
-                    default:
-                        if (word.length() > 3) {
-                            return false;
-                        }
-                        if (!isValidHexChar(c)) {
-                            return false;
-                        }
-                        word += c;
-                }
-            }
-
-            // Check if we have an IPv4 ending
-            if (numberOfPeriods > 0) {
-                if (numberOfPeriods != 3 || !isValidIP4Word(word)) {
-                    return false;
-                }
-            } else {
-                // If we're at then end and we haven't had 7 colons then there
-                // is a problem unless we encountered a doubleColon
-                if (numberOfColons != 7 && !doubleColon) {
-                    return false;
-                }
-
-                // If we have an empty word at the end, it means we ended in
-                // either a : or a .
-                // If we did not end in :: then this is invalid
-                if (word == "" && ipAddress.charAt(length - 1 - offset) != ':' //$NON-NLS-1$
-                        && ipAddress.charAt(length - 2 - offset) != ':') {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        private boolean isValidIP4Word(String word) {
-            char c;
-            if (word.length() < 1 || word.length() > 3) {
-                return false;
-            }
-            for (int i = 0; i < word.length(); i++) {
-                c = word.charAt(i);
-                if (!(c >= '0' && c <= '9')) {
-                    return false;
-                }
-            }
-            if (Integer.parseInt(word) > 255) {
-                return false;
-            }
-            return true;
-        }
-
-        private boolean isValidHexChar(char c) {
-
-            return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
-                    || (c >= 'a' && c <= 'f');
-        }
+        return false;
     }
 
-    /*
+    private boolean isValidDomainName(String host) {
+        try {
+            URIEncoderDecoder.validateSimple(host, "-.");
+        } catch (URISyntaxException e) {
+            return false;
+        }
+
+        String lastLabel = null;
+        StringTokenizer st = new StringTokenizer(host, ".");
+        while (st.hasMoreTokens()) {
+            lastLabel = st.nextToken();
+            if (lastLabel.startsWith("-") || lastLabel.endsWith("-")) {
+                return false;
+            }
+        }
+
+        if (lastLabel == null) {
+            return false;
+        }
+
+        if (!lastLabel.equals(host)) {
+            char ch = lastLabel.charAt(0);
+            if (ch >= '0' && ch <= '9') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
      * Quote illegal chars for each component, but not the others
      * 
-     * @param component java.lang.String the component to be converted @param
-     * legalset java.lang.String the legal character set allowed in the
-     * component s @return java.lang.String the converted string
+     * @param component java.lang.String the component to be converted
+     * @param legalSet the legal character set allowed in the component
+     * @return java.lang.String the converted string
      */
-    private String quoteComponent(String component, String legalset) {
+    private String quoteComponent(String component, String legalSet) {
         try {
             /*
              * Use a different encoder than URLEncoder since: 1. chars like "/",
@@ -829,7 +637,7 @@
              * UTF-8 char set needs to be used for encoding instead of default
              * platform one
              */
-            return URIEncoderDecoder.quoteIllegal(component, legalset);
+            return URIEncoderDecoder.quoteIllegal(component, legalSet);
         } catch (UnsupportedEncodingException e) {
             throw new RuntimeException(e.toString());
         }
@@ -841,7 +649,7 @@
      * argument and a positive value if this URI instance is greater than the
      * given argument. The return value {@code 0} indicates that the two
      * instances represent the same URI. To define the order the single parts of
-     * the URI are compared with each other. String components will be orderer
+     * the URI are compared with each other. String components will be ordered
      * in the natural case-sensitive way. A hierarchical URI is less than an
      * opaque URI and if one part is {@code null} the URI with the undefined
      * part is less than the other one.
@@ -851,7 +659,7 @@
      * @return the value representing the order of the two instances.
      */
     public int compareTo(URI uri) {
-        int ret = 0;
+        int ret;
 
         // compare schemes
         if (scheme == null && uri.scheme != null) {
@@ -871,7 +679,7 @@
         } else if (opaque && !uri.opaque) {
             return 1;
         } else if (opaque && uri.opaque) {
-            ret = schemespecificpart.compareTo(uri.schemespecificpart);
+            ret = schemeSpecificPart.compareTo(uri.schemeSpecificPart);
             if (ret != 0) {
                 return ret;
             }
@@ -886,19 +694,19 @@
                 return -1;
             } else if (authority != null && uri.authority != null) {
                 if (host != null && uri.host != null) {
-                    // both are server based, so compare userinfo, host, port
-                    if (userinfo != null && uri.userinfo == null) {
+                    // both are server based, so compare userInfo, host, port
+                    if (userInfo != null && uri.userInfo == null) {
                         return 1;
-                    } else if (userinfo == null && uri.userinfo != null) {
+                    } else if (userInfo == null && uri.userInfo != null) {
                         return -1;
-                    } else if (userinfo != null && uri.userinfo != null) {
-                        ret = userinfo.compareTo(uri.userinfo);
+                    } else if (userInfo != null && uri.userInfo != null) {
+                        ret = userInfo.compareTo(uri.userInfo);
                         if (ret != 0) {
                             return ret;
                         }
                     }
 
-                    // userinfo's are the same, compare hostname
+                    // userInfo's are the same, compare hostname
                     ret = host.compareToIgnoreCase(uri.host);
                     if (ret != 0) {
                         return ret;
@@ -955,21 +763,18 @@
     }
 
     /**
-     * Parses the given argument {@code uri} and creates an appropriate URI
-     * instance.
-     *
-     * @param uri
-     *            the string which has to be parsed to create the URI instance.
-     * @return the created instance representing the given URI.
+     * Returns the URI formed by parsing {@code uri}. This method behaves
+     * identically to the string constructor but throws a different exception
+     * on failure. The constructor fails with a checked {@link
+     * URISyntaxException}; this method fails with an unchecked {@link
+     * IllegalArgumentException}.
      */
     public static URI create(String uri) {
-        URI result = null;
         try {
-            result = new URI(uri);
+            return new URI(uri);
         } catch (URISyntaxException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
-        return result;
     }
 
     private URI duplicate() {
@@ -983,8 +788,8 @@
         clone.port = port;
         clone.query = query;
         clone.scheme = scheme;
-        clone.schemespecificpart = schemespecificpart;
-        clone.userinfo = userinfo;
+        clone.schemeSpecificPart = schemeSpecificPart;
+        clone.userInfo = userInfo;
         clone.serverAuthority = serverAuthority;
         return clone;
     }
@@ -994,36 +799,35 @@
      * converts the hex values following the '%' to lowercase
      */
     private String convertHexToLowerCase(String s) {
-        StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
+        StringBuilder result = new StringBuilder("");
         if (s.indexOf('%') == -1) {
             return s;
         }
 
-        int index = 0, previndex = 0;
-        while ((index = s.indexOf('%', previndex)) != -1) {
-            result.append(s.substring(previndex, index + 1));
+        int index, prevIndex = 0;
+        while ((index = s.indexOf('%', prevIndex)) != -1) {
+            result.append(s.substring(prevIndex, index + 1));
             result.append(s.substring(index + 1, index + 3).toLowerCase());
             index += 3;
-            previndex = index;
+            prevIndex = index;
         }
         return result.toString();
     }
 
-    /*
-     * Takes two strings that may contain hex sequences like %F1 or %2b and
-     * compares them, ignoring case for the hex values hex values must always
-     * occur in pairs like above
+    /**
+     * Returns true if {@code first} and {@code second} are equal after
+     * unescaping hex sequences like %F1 and %2b.
      */
-    private boolean equalsHexCaseInsensitive(String first, String second) {
+    private boolean escapedEquals(String first, String second) {
         if (first.indexOf('%') != second.indexOf('%')) {
             return first.equals(second);
         }
 
-        int index = 0, previndex = 0;
-        while ((index = first.indexOf('%', previndex)) != -1
-                && second.indexOf('%', previndex) == index) {
-            boolean match = first.substring(previndex, index).equals(
-                    second.substring(previndex, index));
+        int index, prevIndex = 0;
+        while ((index = first.indexOf('%', prevIndex)) != -1
+                && second.indexOf('%', prevIndex) == index) {
+            boolean match = first.substring(prevIndex, index).equals(
+                    second.substring(prevIndex, index));
             if (!match) {
                 return false;
             }
@@ -1035,9 +839,9 @@
             }
 
             index += 3;
-            previndex = index;
+            prevIndex = index;
         }
-        return first.substring(previndex).equals(second.substring(previndex));
+        return first.substring(prevIndex).equals(second.substring(prevIndex));
     }
 
     /**
@@ -1061,7 +865,7 @@
                 && fragment == null) {
             return false;
         } else if (uri.fragment != null && fragment != null) {
-            if (!equalsHexCaseInsensitive(uri.fragment, fragment)) {
+            if (!escapedEquals(uri.fragment, fragment)) {
                 return false;
             }
         }
@@ -1076,10 +880,10 @@
         }
 
         if (uri.opaque && opaque) {
-            return equalsHexCaseInsensitive(uri.schemespecificpart,
-                    schemespecificpart);
+            return escapedEquals(uri.schemeSpecificPart,
+                    schemeSpecificPart);
         } else if (!uri.opaque && !opaque) {
-            if (!equalsHexCaseInsensitive(path, uri.path)) {
+            if (!escapedEquals(path, uri.path)) {
                 return false;
             }
 
@@ -1087,7 +891,7 @@
                     && query != null) {
                 return false;
             } else if (uri.query != null && query != null) {
-                if (!equalsHexCaseInsensitive(uri.query, query)) {
+                if (!escapedEquals(uri.query, query)) {
                     return false;
                 }
             }
@@ -1101,7 +905,7 @@
                     return false;
                 } else if (uri.host == null && host == null) {
                     // both are registry based, so compare the whole authority
-                    return equalsHexCaseInsensitive(uri.authority, authority);
+                    return escapedEquals(uri.authority, authority);
                 } else { // uri.host != null && host != null, so server-based
                     if (!host.equalsIgnoreCase(uri.host)) {
                         return false;
@@ -1111,11 +915,11 @@
                         return false;
                     }
 
-                    if (uri.userinfo != null && userinfo == null
-                            || uri.userinfo == null && userinfo != null) {
+                    if (uri.userInfo != null && userInfo == null
+                            || uri.userInfo == null && userInfo != null) {
                         return false;
-                    } else if (uri.userinfo != null && userinfo != null) {
-                        return equalsHexCaseInsensitive(userinfo, uri.userinfo);
+                    } else if (uri.userInfo != null && userInfo != null) {
+                        return escapedEquals(userInfo, uri.userInfo);
                     } else {
                         return true;
                     }
@@ -1227,7 +1031,7 @@
      * @return the encoded scheme-specific part or {@code null} if undefined.
      */
     public String getRawSchemeSpecificPart() {
-        return schemespecificpart;
+        return schemeSpecificPart;
     }
 
     /**
@@ -1236,7 +1040,7 @@
      * @return the encoded user-info part or {@code null} if undefined.
      */
     public String getRawUserInfo() {
-        return userinfo;
+        return userInfo;
     }
 
     /**
@@ -1254,7 +1058,7 @@
      * @return the decoded scheme-specific part or {@code null} if undefined.
      */
     public String getSchemeSpecificPart() {
-        return decode(schemespecificpart);
+        return decode(schemeSpecificPart);
     }
 
     /**
@@ -1263,7 +1067,7 @@
      * @return the decoded user-info part or {@code null} if undefined.
      */
     public String getUserInfo() {
-        return decode(userinfo);
+        return decode(userInfo);
     }
 
     /**
@@ -1307,39 +1111,39 @@
     private String normalize(String path) {
         // count the number of '/'s, to determine number of segments
         int index = -1;
-        int pathlen = path.length();
+        int pathLength = path.length();
         int size = 0;
-        if (pathlen > 0 && path.charAt(0) != '/') {
+        if (pathLength > 0 && path.charAt(0) != '/') {
             size++;
         }
         while ((index = path.indexOf('/', index + 1)) != -1) {
-            if (index + 1 < pathlen && path.charAt(index + 1) != '/') {
+            if (index + 1 < pathLength && path.charAt(index + 1) != '/') {
                 size++;
             }
         }
 
-        String[] seglist = new String[size];
+        String[] segList = new String[size];
         boolean[] include = new boolean[size];
 
         // break the path into segments and store in the list
         int current = 0;
-        int index2 = 0;
-        index = (pathlen > 0 && path.charAt(0) == '/') ? 1 : 0;
+        int index2;
+        index = (pathLength > 0 && path.charAt(0) == '/') ? 1 : 0;
         while ((index2 = path.indexOf('/', index + 1)) != -1) {
-            seglist[current++] = path.substring(index, index2);
+            segList[current++] = path.substring(index, index2);
             index = index2 + 1;
         }
 
         // if current==size, then the last character was a slash
         // and there are no more segments
         if (current < size) {
-            seglist[current] = path.substring(index);
+            segList[current] = path.substring(index);
         }
 
         // determine which segments get included in the normalized path
         for (int i = 0; i < size; i++) {
             include[i] = true;
-            if (seglist[i].equals("..")) { //$NON-NLS-1$
+            if (segList[i].equals("..")) {
                 int remove = i - 1;
                 // search back to find a segment to remove, if possible
                 while (remove > -1 && !include[remove]) {
@@ -1347,45 +1151,45 @@
                 }
                 // if we find a segment to remove, remove it and the ".."
                 // segment
-                if (remove > -1 && !seglist[remove].equals("..")) { //$NON-NLS-1$
+                if (remove > -1 && !segList[remove].equals("..")) {
                     include[remove] = false;
                     include[i] = false;
                 }
-            } else if (seglist[i].equals(".")) { //$NON-NLS-1$
+            } else if (segList[i].equals(".")) {
                 include[i] = false;
             }
         }
 
         // put the path back together
-        StringBuilder newpath = new StringBuilder();
-        if (path.startsWith("/")) { //$NON-NLS-1$
-            newpath.append('/');
+        StringBuilder newPath = new StringBuilder();
+        if (path.startsWith("/")) {
+            newPath.append('/');
         }
 
-        for (int i = 0; i < seglist.length; i++) {
+        for (int i = 0; i < segList.length; i++) {
             if (include[i]) {
-                newpath.append(seglist[i]);
-                newpath.append('/');
+                newPath.append(segList[i]);
+                newPath.append('/');
             }
         }
 
         // if we used at least one segment and the path previously ended with
         // a slash and the last segment is still used, then delete the extra
         // trailing '/'
-        if (!path.endsWith("/") && seglist.length > 0 //$NON-NLS-1$
-                && include[seglist.length - 1]) {
-            newpath.deleteCharAt(newpath.length() - 1);
+        if (!path.endsWith("/") && segList.length > 0
+                && include[segList.length - 1]) {
+            newPath.deleteCharAt(newPath.length() - 1);
         }
 
-        String result = newpath.toString();
+        String result = newPath.toString();
 
         // check for a ':' in the first segment if one exists,
         // prepend "./" to normalize
         index = result.indexOf(':');
         index2 = result.indexOf('/');
         if (index != -1 && (index < index2 || index2 == -1)) {
-            newpath.insert(0, "./"); //$NON-NLS-1$
-            result = newpath.toString();
+            newPath.insert(0, "./");
+            result = newPath.toString();
         }
         return result;
     }
@@ -1425,7 +1229,7 @@
      */
     public URI parseServerAuthority() throws URISyntaxException {
         if (!serverAuthority) {
-            new Helper().parseAuthority(true);
+            parseAuthority(true);
         }
         return this;
     }
@@ -1463,7 +1267,7 @@
          */
         if (!thisPath.equals(relativePath)) {
             // if this URI's path doesn't end in a '/', add one
-            if (!thisPath.endsWith("/")) { //$NON-NLS-1$
+            if (!thisPath.endsWith("/")) {
                 thisPath = thisPath + '/';
             }
             /*
@@ -1499,12 +1303,12 @@
         }
 
         URI result;
-        if (relative.path.equals("") && relative.scheme == null //$NON-NLS-1$
+        if (relative.path.equals("") && relative.scheme == null
                 && relative.authority == null && relative.query == null
                 && relative.fragment != null) {
             // if the relative URI only consists of fragment,
             // the resolved URI is very similar to this URI,
-            // except that it has the fragement from the relative URI.
+            // except that it has the fragment from the relative URI.
             result = duplicate();
             result.fragment = relative.fragment;
             // no need to re-calculate the scheme specific part,
@@ -1527,12 +1331,12 @@
             result = duplicate();
             result.fragment = relative.fragment;
             result.query = relative.query;
-            if (relative.path.startsWith("/")) { //$NON-NLS-1$
+            if (relative.path.startsWith("/")) {
                 result.path = relative.path;
             } else {
                 // resolve a relative reference
-                int endindex = path.lastIndexOf('/') + 1;
-                result.path = normalize(path.substring(0, endindex)
+                int endIndex = path.lastIndexOf('/') + 1;
+                result.path = normalize(path.substring(0, endIndex)
                         + relative.path);
             }
             // re-calculate the scheme specific part since
@@ -1550,15 +1354,15 @@
         // ssp = [//authority][path][?query]
         StringBuilder ssp = new StringBuilder();
         if (authority != null) {
-            ssp.append("//" + authority); //$NON-NLS-1$
+            ssp.append("//" + authority);
         }
         if (path != null) {
             ssp.append(path);
         }
         if (query != null) {
-            ssp.append("?" + query); //$NON-NLS-1$
+            ssp.append("?" + query);
         }
-        schemespecificpart = ssp.toString();
+        schemeSpecificPart = ssp.toString();
         // reset string, so that it can be re-calculated correctly when asked.
         string = null;
     }
@@ -1577,17 +1381,13 @@
         return resolve(create(relative));
     }
 
-    /*
+    /**
      * Encode unicode chars that are not part of US-ASCII char set into the
      * escaped form
      * 
      * i.e. The Euro currency symbol is encoded as "%E2%82%AC".
-     * 
-     * @param component java.lang.String the component to be converted @param
-     * legalset java.lang.String the legal character set allowed in the
-     * component s @return java.lang.String the converted string
      */
-    private String encodeOthers(String s) {
+    private String encodeNonAscii(String s) {
         try {
             /*
              * Use a different encoder than URLEncoder since: 1. chars like "/",
@@ -1620,7 +1420,7 @@
      * @return the US-ASCII string representation of this URI.
      */
     public String toASCIIString() {
-        return encodeOthers(toString());
+        return encodeNonAscii(toString());
     }
 
     /**
@@ -1637,10 +1437,10 @@
                 result.append(':');
             }
             if (opaque) {
-                result.append(schemespecificpart);
+                result.append(schemeSpecificPart);
             } else {
                 if (authority != null) {
-                    result.append("//"); //$NON-NLS-1$
+                    result.append("//");
                     result.append(authority);
                 }
 
@@ -1676,19 +1476,19 @@
             result.append(':');
         }
         if (opaque) {
-            result.append(schemespecificpart);
+            result.append(schemeSpecificPart);
         } else {
             if (authority != null) {
-                result.append("//"); //$NON-NLS-1$
+                result.append("//");
                 if (host == null) {
                     result.append(authority);
                 } else {
-                    if (userinfo != null) {
-                        result.append(userinfo + "@"); //$NON-NLS-1$
+                    if (userInfo != null) {
+                        result.append(userInfo + "@");
                     }
                     result.append(host.toLowerCase());
                     if (port != -1) {
-                        result.append(":" + port); //$NON-NLS-1$
+                        result.append(":" + port);
                     }
                 }
             }
@@ -1721,8 +1521,7 @@
      */
     public URL toURL() throws MalformedURLException {
         if (!absolute) {
-            throw new IllegalArgumentException(Msg.getString("K0312") + ": " //$NON-NLS-1$//$NON-NLS-2$
-                    + toString());
+            throw new IllegalArgumentException("URI is not absolute: " + toString());
         }
         return new URL(toString());
     }
@@ -1731,7 +1530,7 @@
             ClassNotFoundException {
         in.defaultReadObject();
         try {
-            new Helper().parseURI(string, false);
+            parseURI(string, false);
         } catch (URISyntaxException e) {
             throw new IOException(e.toString());
         }
diff --git a/luni/src/main/java/java/net/URLClassLoader.java b/luni/src/main/java/java/net/URLClassLoader.java
index 61841e6..1d8ee85 100644
--- a/luni/src/main/java/java/net/URLClassLoader.java
+++ b/luni/src/main/java/java/net/URLClassLoader.java
@@ -291,7 +291,7 @@
         URL targetURL(URL base, String name) {
             try {
                 String file = base.getFile() + URIEncoderDecoder.quoteIllegal(name,
-                        "/@" + URI.someLegal);
+                        "/@" + URI.SOME_LEGAL);
 
                 return new URL(base.getProtocol(), base.getHost(), base.getPort(),
                         file, null);
diff --git a/luni/src/main/java/java/net/package.html b/luni/src/main/java/java/net/package.html
index b4e8b8d..dff1ccd 100644
--- a/luni/src/main/java/java/net/package.html
+++ b/luni/src/main/java/java/net/package.html
@@ -4,6 +4,5 @@
       Provides networking-related functionality, such as streaming and datagram
       sockets, handling of Internet addresses, and dealing with HTTP requests. 
     </p>
-    @since Android 1.0 
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/luni/src/main/java/java/util/AbstractMap.java b/luni/src/main/java/java/util/AbstractMap.java
index c98a25f..4789b14 100644
--- a/luni/src/main/java/java/util/AbstractMap.java
+++ b/luni/src/main/java/java/util/AbstractMap.java
@@ -17,10 +17,18 @@
 
 package java.util;
 
+import java.io.Serializable;
+
 /**
- * This class is an abstract implementation of the {@code Map} interface. This
- * implementation does not support adding. A subclass must implement the
- * abstract method entrySet().
+ * A base class for {@code Map} implementations.
+ *
+ * <p>Subclasses that permit new mappings to be added must override {@link
+ * #put}.
+ *
+ * <p>The default implementations of many methods are inefficient for large
+ * maps. For example in the default implementation, each call to {@link #get}
+ * performs a linear iteration of the entry set. Subclasses should override such
+ * methods to improve their performance.
  *
  * @since 1.2
  */
@@ -32,31 +40,152 @@
     Collection<V> valuesCollection;
 
     /**
-     * Constructs a new instance of this {@code AbstractMap}.
+     * An immutable key-value mapping. Despite the name, this class is non-final
+     * and its subclasses may be mutable.
+     *
+     * @since 1.6
      */
+    public static class SimpleImmutableEntry<K, V>
+            implements Map.Entry<K, V>, Serializable {
+        private static final long serialVersionUID = 7138329143949025153L;
+
+        private final K key;
+        private final V value;
+
+        public SimpleImmutableEntry(K theKey, V theValue) {
+            key = theKey;
+            value = theValue;
+        }
+
+        /**
+         * Constructs an instance with the key and value of {@code copyFrom}.
+         */
+        public SimpleImmutableEntry(Map.Entry<? extends K, ? extends V> copyFrom) {
+            key = copyFrom.getKey();
+            value = copyFrom.getValue();
+        }
+
+        public K getKey() {
+            return key;
+        }
+
+        public V getValue() {
+            return value;
+        }
+
+        /**
+         * This base implementation throws {@code UnsupportedOperationException}
+         * always.
+         */
+        public V setValue(V object) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override public boolean equals(Object object) {
+            if (this == object) {
+                return true;
+            }
+            if (object instanceof Map.Entry) {
+                Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+                return (key == null ? entry.getKey() == null : key.equals(entry
+                        .getKey()))
+                        && (value == null ? entry.getValue() == null : value
+                                .equals(entry.getValue()));
+            }
+            return false;
+        }
+
+        @Override public int hashCode() {
+            return (key == null ? 0 : key.hashCode())
+                    ^ (value == null ? 0 : value.hashCode());
+        }
+
+        @Override public String toString() {
+            return key + "=" + value;
+        }
+    }
+
+    /**
+     * A key-value mapping with mutable values.
+     *
+     * @since 1.6
+     */
+    public static class SimpleEntry<K, V>
+            implements Map.Entry<K, V>, Serializable {
+        private static final long serialVersionUID = -8499721149061103585L;
+
+        private final K key;
+        private V value;
+
+        public SimpleEntry(K theKey, V theValue) {
+            key = theKey;
+            value = theValue;
+        }
+
+        /**
+         * Constructs an instance with the key and value of {@code copyFrom}.
+         */
+        public SimpleEntry(Map.Entry<? extends K, ? extends V> copyFrom) {
+            key = copyFrom.getKey();
+            value = copyFrom.getValue();
+        }
+
+        public K getKey() {
+            return key;
+        }
+
+        public V getValue() {
+            return value;
+        }
+
+        public V setValue(V object) {
+            V result = value;
+            value = object;
+            return result;
+        }
+
+        @Override public boolean equals(Object object) {
+            if (this == object) {
+                return true;
+            }
+            if (object instanceof Map.Entry) {
+                Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+                return (key == null ? entry.getKey() == null : key.equals(entry
+                        .getKey()))
+                        && (value == null ? entry.getValue() == null : value
+                                .equals(entry.getValue()));
+            }
+            return false;
+        }
+
+        @Override public int hashCode() {
+            return (key == null ? 0 : key.hashCode())
+                    ^ (value == null ? 0 : value.hashCode());
+        }
+
+        @Override public String toString() {
+            return key + "=" + value;
+        }
+    }
+
     protected AbstractMap() {
         super();
     }
 
     /**
-     * Removes all elements from this map, leaving it empty.
+     * {@inheritDoc}
      *
-     * @throws UnsupportedOperationException
-     *                if removing from this map is not supported.
-     * @see #isEmpty()
-     * @see #size()
+     * <p>This implementation calls {@code entrySet().clear()}.
      */
     public void clear() {
         entrySet().clear();
     }
 
     /**
-     * Returns whether this map contains the specified key.
+     * {@inheritDoc}
      *
-     * @param key
-     *            the key to search for.
-     * @return {@code true} if this map contains the specified key,
-     *         {@code false} otherwise.
+     * <p>This implementation iterates its key set, looking for a key that
+     * {@code key} equals.
      */
     public boolean containsKey(Object key) {
         Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -77,12 +206,10 @@
     }
 
     /**
-     * Returns whether this map contains the specified value.
+     * {@inheritDoc}
      *
-     * @param value
-     *            the value to search for.
-     * @return {@code true} if this map contains the specified value,
-     *         {@code false} otherwise.
+     * <p>This implementation iterates its entry set, looking for an entry with
+     * a value that {@code value} equals.
      */
     public boolean containsValue(Object value) {
         Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -102,28 +229,18 @@
         return false;
     }
 
-    /**
-     * Returns a set containing all of the mappings in this map. Each mapping is
-     * an instance of {@link Map.Entry}. As the set is backed by this map,
-     * changes in one will be reflected in the other.
-     *
-     * @return a set of the mappings.
-     */
     public abstract Set<Map.Entry<K, V>> entrySet();
 
     /**
-     * Compares the specified object to this instance, and returns {@code true}
-     * if the specified object is a map and both maps contain the same mappings.
+     * {@inheritDoc}
      *
-     * @param object
-     *            the object to compare with this object.
-     * @return boolean {@code true} if the object is the same as this object,
-     *         and {@code false} if it is different from this object.
-     * @see #hashCode()
-     * @see #entrySet()
+     * <p>This implementation first checks the structure of {@code object}. If
+     * it is not a map or of a different size, this returns false. Otherwise it
+     * iterates its own entry set, looking up each entry's key in {@code
+     * object}. If any value does not equal the other map's value for the same
+     * key, this returns false. Otherwise it returns true.
      */
-    @Override
-    public boolean equals(Object object) {
+    @Override public boolean equals(Object object) {
         if (this == object) {
             return true;
         }
@@ -157,12 +274,10 @@
     }
 
     /**
-     * Returns the value of the mapping with the specified key.
+     * {@inheritDoc}
      *
-     * @param key
-     *            the key.
-     * @return the value of the mapping with the specified key, or {@code null}
-     *         if no mapping for the specified key is found.
+     * <p>This implementation iterates its entry set, looking for an entry with
+     * a key that {@code key} equals.
      */
     public V get(Object key) {
         Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -185,14 +300,12 @@
     }
 
     /**
-     * Returns the hash code for this object. Objects which are equal must
-     * return the same value for this method.
+     * {@inheritDoc}
      *
-     * @return the hash code of this object.
-     * @see #equals(Object)
+     * <p>This implementation iterates its entry set, summing the hashcodes of
+     * its entries.
      */
-    @Override
-    public int hashCode() {
+    @Override public int hashCode() {
         int result = 0;
         Iterator<Map.Entry<K, V>> it = entrySet().iterator();
         while (it.hasNext()) {
@@ -202,41 +315,34 @@
     }
 
     /**
-     * Returns whether this map is empty.
+     * {@inheritDoc}
      *
-     * @return {@code true} if this map has no elements, {@code false}
-     *         otherwise.
-     * @see #size()
+     * <p>This implementation compares {@code size()} to 0.
      */
     public boolean isEmpty() {
         return size() == 0;
     }
 
     /**
-     * Returns a set of the keys contained in this map. The set is backed by
-     * this map so changes to one are reflected by the other. The returned set
-     * does not support adding.
+     * {@inheritDoc}
      *
-     * @return a set of the keys.
+     * <p>This implementation returns a view that calls through this to map. Its
+     * iterator transforms this map's entry set iterator to return keys.
      */
     public Set<K> keySet() {
         if (keySet == null) {
             keySet = new AbstractSet<K>() {
-                @Override
-                public boolean contains(Object object) {
+                @Override public boolean contains(Object object) {
                     return containsKey(object);
                 }
 
-                @Override
-                public int size() {
+                @Override public int size() {
                     return AbstractMap.this.size();
                 }
 
-                @Override
-                public Iterator<K> iterator() {
+                @Override public Iterator<K> iterator() {
                     return new Iterator<K>() {
-                        Iterator<Map.Entry<K, V>> setIterator = entrySet()
-                                .iterator();
+                        Iterator<Map.Entry<K, V>> setIterator = entrySet().iterator();
 
                         public boolean hasNext() {
                             return setIterator.hasNext();
@@ -257,44 +363,19 @@
     }
 
     /**
-     * Maps the specified key to the specified value.
+     * {@inheritDoc}
      *
-     * @param key
-     *            the key.
-     * @param value
-     *            the value.
-     * @return the value of any previous mapping with the specified key or
-     *         {@code null} if there was no mapping.
-     * @throws UnsupportedOperationException
-     *                if adding to this map is not supported.
-     * @throws ClassCastException
-     *                if the class of the key or value is inappropriate for this
-     *                map.
-     * @throws IllegalArgumentException
-     *                if the key or value cannot be added to this map.
-     * @throws NullPointerException
-     *                if the key or value is {@code null} and this Map does not
-     *                support {@code null} keys or values.
+     * <p>This base implementation throws {@code UnsupportedOperationException}.
      */
     public V put(K key, V value) {
         throw new UnsupportedOperationException();
     }
 
     /**
-     * Copies every mapping in the specified map to this map.
+     * {@inheritDoc}
      *
-     * @param map
-     *            the map to copy mappings from.
-     * @throws UnsupportedOperationException
-     *                if adding to this map is not supported.
-     * @throws ClassCastException
-     *                if the class of a key or value is inappropriate for this
-     *                map.
-     * @throws IllegalArgumentException
-     *                if a key or value cannot be added to this map.
-     * @throws NullPointerException
-     *                if a key or value is {@code null} and this map does not
-     *                support {@code null} keys or values.
+     * <p>This implementation iterates through {@code map}'s entry set, calling
+     * {@code put()} for each.
      */
     public void putAll(Map<? extends K, ? extends V> map) {
         for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
@@ -303,14 +384,10 @@
     }
 
     /**
-     * Removes a mapping with the specified key from this Map.
+     * {@inheritDoc}
      *
-     * @param key
-     *            the key of the mapping to remove.
-     * @return the value of the removed mapping or {@code null} if no mapping
-     *         for the specified key was found.
-     * @throws UnsupportedOperationException
-     *                if removing from this map is not supported.
+     * <p>This implementation iterates its entry set, removing the entry with
+     * a key that {@code key} equals.
      */
     public V remove(Object key) {
         Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -335,23 +412,24 @@
     }
 
     /**
-     * Returns the number of elements in this map.
+     * {@inheritDoc}
      *
-     * @return the number of elements in this map.
+     * <p>This implementation returns its entry set's size.
      */
     public int size() {
         return entrySet().size();
     }
 
     /**
-     * Returns the string representation of this map.
+     * {@inheritDoc}
      *
-     * @return the string representation of this map.
+     * <p>This implementation composes a string by iterating its entry set. If
+     * this map contains itself as a key or a value, the string "(this Map)"
+     * will appear in its place.
      */
-    @Override
-    public String toString() {
+    @Override public String toString() {
         if (isEmpty()) {
-            return "{}"; //$NON-NLS-1$
+            return "{}";
         }
 
         StringBuilder buffer = new StringBuilder(size() * 28);
@@ -363,17 +441,17 @@
             if (key != this) {
                 buffer.append(key);
             } else {
-                buffer.append("(this Map)"); //$NON-NLS-1$
+                buffer.append("(this Map)");
             }
             buffer.append('=');
             Object value = entry.getValue();
             if (value != this) {
                 buffer.append(value);
             } else {
-                buffer.append("(this Map)"); //$NON-NLS-1$
+                buffer.append("(this Map)");
             }
             if (it.hasNext()) {
-                buffer.append(", "); //$NON-NLS-1$
+                buffer.append(", ");
             }
         }
         buffer.append('}');
@@ -381,42 +459,25 @@
     }
 
     /**
-     * Returns a collection of the values contained in this map. The collection
-     * is backed by this map so changes to one are reflected by the other. The
-     * collection supports remove, removeAll, retainAll and clear operations,
-     * and it does not support add or addAll operations.
-     * <p>
-     * This method returns a collection which is the subclass of
-     * AbstractCollection. The iterator method of this subclass returns a
-     * "wrapper object" over the iterator of map's entrySet(). The {@code size}
-     * method wraps the map's size method and the {@code contains} method wraps
-     * the map's containsValue method.
-     * <p>
-     * The collection is created when this method is called for the first time
-     * and returned in response to all subsequent calls. This method may return
-     * different collections when multiple concurrent calls occur to this
-     * method, since no synchronization is performed.
+     * {@inheritDoc}
      *
-     * @return a collection of the values contained in this map.
+     * <p>This implementation returns a view that calls through this to map. Its
+     * iterator transforms this map's entry set iterator to return values.
      */
     public Collection<V> values() {
         if (valuesCollection == null) {
             valuesCollection = new AbstractCollection<V>() {
-                @Override
-                public int size() {
+                @Override public int size() {
                     return AbstractMap.this.size();
                 }
 
-                @Override
-                public boolean contains(Object object) {
+                @Override public boolean contains(Object object) {
                     return containsValue(object);
                 }
 
-                @Override
-                public Iterator<V> iterator() {
+                @Override public Iterator<V> iterator() {
                     return new Iterator<V>() {
-                        Iterator<Map.Entry<K, V>> setIterator = entrySet()
-                                .iterator();
+                        Iterator<Map.Entry<K, V>> setIterator = entrySet().iterator();
 
                         public boolean hasNext() {
                             return setIterator.hasNext();
@@ -436,21 +497,11 @@
         return valuesCollection;
     }
 
-    /**
-     * Returns a new instance of the same class as this instance, whose slots
-     * have been filled in with the values of the slots of this instance.
-     *
-     * @return a shallow copy of this object.
-     * @throws CloneNotSupportedException
-     *                if the receiver's class does not implement the interface
-     *                {@code Cloneable}.
-     */
-    @Override
     @SuppressWarnings("unchecked")
-    protected Object clone() throws CloneNotSupportedException {
+    @Override protected Object clone() throws CloneNotSupportedException {
         AbstractMap<K, V> result = (AbstractMap<K, V>) super.clone();
         result.keySet = null;
         result.valuesCollection = null;
         return result;
     }
-}
+}
\ No newline at end of file
diff --git a/luni/src/main/java/java/util/ArrayDeque.java b/luni/src/main/java/java/util/ArrayDeque.java
new file mode 100644
index 0000000..2e2fe3a
--- /dev/null
+++ b/luni/src/main/java/java/util/ArrayDeque.java
@@ -0,0 +1,885 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+
+/**
+ * An implementation of Deque, backed by an array.
+ *
+ * ArrayDeques have no size limit, can not contain null element, and they are
+ * not thread-safe.
+ *
+ * All optional operations are supported, and the elements can be any objects.
+ *
+ * @param <E>
+ *            the type of elements in this collection
+ *
+ * @since 1.6
+ */
+public class ArrayDeque<E> extends AbstractCollection<E> implements Deque<E>,
+        Cloneable, Serializable {
+
+    private static final long serialVersionUID = 2340985798034038923L;
+
+    private static final int DEFAULT_SIZE = 16;
+
+    private enum DequeStatus {
+        Empty, Normal, Full;
+    }
+
+    private transient DequeStatus status;
+
+    private transient int modCount;
+
+    // the pointer of the head element
+    private transient int front;
+
+    // the pointer of the "next" position of the tail element
+    private transient int rear;
+
+    private transient E[] elements;
+
+    @SuppressWarnings("hiding")
+    private class ArrayDequeIterator<E> implements Iterator<E> {
+        private int pos;
+
+        private final int expectedModCount;
+
+        private boolean canRemove;
+
+        @SuppressWarnings("synthetic-access")
+        ArrayDequeIterator() {
+            super();
+            pos = front;
+            expectedModCount = modCount;
+            canRemove = false;
+        }
+
+        @SuppressWarnings("synthetic-access")
+        public boolean hasNext() {
+            if (expectedModCount != modCount) {
+                return false;
+            }
+            return hasNextInternal();
+        }
+
+        private boolean hasNextInternal() {
+            // canRemove means "next" method is called, and the Full
+            // status can ensure that this method is not called just
+            // after "remove" method is call.(so, canRemove can keep
+            // true after "next" method called)
+            return (pos != rear)
+                    || ((status == DequeStatus.Full) && !canRemove);
+        }
+
+        @SuppressWarnings( { "synthetic-access", "unchecked" })
+        public E next() {
+            if (hasNextInternal()) {
+                E result = (E) elements[pos];
+                if (expectedModCount == modCount && null != result) {
+                    canRemove = true;
+                    pos = circularBiggerPos(pos);
+                    return result;
+                }
+                throw new ConcurrentModificationException();
+            }
+            throw new NoSuchElementException();
+        }
+
+        @SuppressWarnings("synthetic-access")
+        public void remove() {
+            if (canRemove) {
+                int removedPos = circularSmallerPos(pos);
+                if (expectedModCount == modCount
+                        && null != elements[removedPos]) {
+                    removeInternal(removedPos, true);
+                    canRemove = false;
+                    return;
+                }
+                throw new ConcurrentModificationException();
+            }
+            throw new IllegalStateException();
+        }
+    }
+
+    /*
+     * NOTES:descendingIterator is not fail-fast, according to the documentation
+     * and test case.
+     */
+    @SuppressWarnings("hiding")
+    private class ReverseArrayDequeIterator<E> implements Iterator<E> {
+        private int pos;
+
+        private final int expectedModCount;
+
+        private boolean canRemove;
+
+        @SuppressWarnings("synthetic-access")
+        ReverseArrayDequeIterator() {
+            super();
+            expectedModCount = modCount;
+            pos = circularSmallerPos(rear);
+            canRemove = false;
+        }
+
+        @SuppressWarnings("synthetic-access")
+        public boolean hasNext() {
+            if (expectedModCount != modCount) {
+                return false;
+            }
+            return hasNextInternal();
+        }
+
+        private boolean hasNextInternal() {
+            // canRemove means "next" method is called, and the Full
+            // status can ensure that this method is not called just
+            // after "remove" method is call.(so, canRemove can keep
+            // true after "next" method called)
+            return (circularBiggerPos(pos) != front)
+                    || ((status == DequeStatus.Full) && !canRemove);
+        }
+
+        @SuppressWarnings( { "synthetic-access", "unchecked" })
+        public E next() {
+            if (hasNextInternal()) {
+                E result = (E) elements[pos];
+                canRemove = true;
+                pos = circularSmallerPos(pos);
+                return result;
+            }
+            throw new NoSuchElementException();
+        }
+
+        @SuppressWarnings("synthetic-access")
+        public void remove() {
+            if (canRemove) {
+                removeInternal(circularBiggerPos(pos), false);
+                canRemove = false;
+                return;
+            }
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Constructs a new empty instance of ArrayDeque big enough for 16 elements.
+     */
+    public ArrayDeque() {
+        this(DEFAULT_SIZE);
+    }
+
+    /**
+     * Constructs a new empty instance of ArrayDeque big enough for specified
+     * number of elements.
+     *
+     * @param minSize
+     *            the smallest size of the ArrayDeque
+     */
+    @SuppressWarnings("unchecked")
+    public ArrayDeque(final int minSize) {
+        int size = countInitSize(minSize);
+        elements = (E[]) new Object[size];
+        front = rear = 0;
+        status = DequeStatus.Empty;
+        modCount = 0;
+    }
+
+    /*
+     * count out the size for a new deque, and ensure that size >= minSize
+     */
+    private int countInitSize(final int minSize) {
+        int size = Math.max(minSize, DEFAULT_SIZE);
+        // get the smallest number that not smaller than size,
+        // and is a power of 2.
+        size = Integer.highestOneBit(size - 1) << 1;
+        if (0 >= size) {
+            size = minSize;
+        }
+        return size;
+    }
+
+    /**
+     * Constructs a new instance of ArrayDeque containing the elements of the
+     * specified collection, with the order returned by the collection's
+     * iterator.
+     *
+     * @param c
+     *            the source of the elements
+     * @throws NullPointerException
+     *             if the collection is null
+     */
+    @SuppressWarnings("unchecked")
+    public ArrayDeque(Collection<? extends E> c) {
+        elements = (E[]) new Object[countInitSize(c.size())];
+        front = rear = 0;
+        status = DequeStatus.Empty;
+        modCount = 0;
+        Iterator<? extends E> it = c.iterator();
+        while (it.hasNext()) {
+            addLastImpl(it.next());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param e
+     *            the element
+     * @throws NullPointerException
+     *             if the element is null
+     * @see java.util.Deque#addFirst(java.lang.Object)
+     */
+    public void addFirst(E e) {
+        offerFirst(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param e
+     *            the element
+     * @throws NullPointerException
+     *             if the element is null
+     * @see java.util.Deque#addLast(java.lang.Object)
+     */
+    public void addLast(E e) {
+        addLastImpl(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param e
+     *            the element
+     * @return true
+     * @throws NullPointerException
+     *             if the element is null
+     * @see java.util.Deque#offerFirst(java.lang.Object)
+     */
+    public  boolean offerFirst(E e) {
+        checkNull(e);
+        checkAndExpand();
+        front = circularSmallerPos(front);
+        elements[front] = e;
+        resetStatus(true);
+        modCount++;
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param e
+     *            the element
+     * @return true if the operation succeeds or false if it fails
+     * @throws NullPointerException
+     *             if the element is null
+     * @see java.util.Deque#offerLast(java.lang.Object)
+     */
+    public boolean offerLast(E e) {
+        return addLastImpl(e);
+    }
+
+    /**
+     * Inserts the element at the tail of the deque.
+     *
+     * @param e
+     *            the element
+     * @return true if the operation succeeds or false if it fails.
+     * @throws NullPointerException
+     *             if the element is null
+     * @see java.util.Queue#offer(java.lang.Object)
+     */
+    public boolean offer(E e) {
+        return addLastImpl(e);
+    }
+
+    /**
+     * Inserts the element to the tail of the deque.
+     *
+     * @param e
+     *            the element
+     * @return true
+     * @see java.util.AbstractCollection#add(java.lang.Object)
+     */
+    @Override
+    public boolean add(E e) {
+        return addLastImpl(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param e
+     *            the element to push
+     * @throws NullPointerException
+     *             if the element is null
+     * @see java.util.Deque#push(java.lang.Object)
+     */
+    public void push(E e) {
+        offerFirst(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Deque#removeFirst()
+     */
+    public  E removeFirst() {
+        checkEmpty();
+        return removePollFirstImpl();
+    }
+
+    /**
+     * Gets and removes the head element of this deque. This method throws an
+     * exception if the deque is empty.
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Queue#remove()
+     */
+    public E remove() {
+        return removeFirst();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Deque#pop()
+     */
+    public E pop() {
+        return removeFirst();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the tail element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Deque#removeLast()
+     */
+    public  E removeLast() {
+        checkEmpty();
+        return removeLastImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the head element or null if the deque is empty
+     * @see java.util.Deque#pollFirst()
+     */
+    public  E pollFirst() {
+        return (status == DequeStatus.Empty) ? null : removePollFirstImpl();
+    }
+
+    /**
+     * Gets and removes the head element of this deque. This method returns null
+     * if the deque is empty.
+     *
+     * @return the head element or null if the deque is empty
+     * @see java.util.Queue#poll()
+     */
+    public E poll() {
+        return pollFirst();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the tail element or null if the deque is empty
+     * @see java.util.Deque#pollLast()
+     */
+    public  E pollLast() {
+        return (status == DequeStatus.Empty) ? null : removeLastImpl();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Deque#getFirst()
+     */
+    public  E getFirst() {
+        checkEmpty();
+        return elements[front];
+    }
+
+    /**
+     * Gets but does not remove the head element of this deque. It throws an
+     * exception if the deque is empty.
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Queue#element()
+     */
+    public E element() {
+        return getFirst();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the tail element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     * @see java.util.Deque#getLast()
+     */
+    public  E getLast() {
+        checkEmpty();
+        return elements[circularSmallerPos(rear)];
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the head element or null if the deque is empty
+     * @see java.util.Deque#peekFirst()
+     */
+    public  E peekFirst() {
+        return (status == DequeStatus.Empty) ? null : elements[front];
+    }
+
+    /**
+     * Gets but not removes the head element of this deque. This method returns
+     * null if the deque is empty.
+     *
+     * @return the head element or null if the deque is empty
+     * @see java.util.Queue#peek()
+     */
+    public  E peek() {
+        return (status == DequeStatus.Empty) ? null : elements[front];
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the tail element or null if the deque is empty
+     * @see java.util.Deque#peekLast()
+     */
+    public  E peekLast() {
+        return (status == DequeStatus.Empty) ? null
+                : elements[circularSmallerPos(rear)];
+    }
+
+    private void checkNull(E e) {
+        if (null == e) {
+            throw new NullPointerException();
+        }
+    }
+
+    private void checkEmpty() {
+        if (status == DequeStatus.Empty) {
+            throw new NoSuchElementException();
+        }
+    }
+
+    private int circularSmallerPos(int current) {
+        return (current - 1 < 0) ? (elements.length - 1) : current - 1;
+    }
+
+    private int circularBiggerPos(int current) {
+        return (current + 1 >= elements.length) ? 0 : current + 1;
+    }
+
+    @SuppressWarnings("unchecked")
+    /*
+     * If array of elements is full, there will be a new bigger array to store
+     * the elements.
+     */
+    private void checkAndExpand() {
+        if (status != DequeStatus.Full) {
+            return;
+        }
+        if (Integer.MAX_VALUE == elements.length) {
+            throw new IllegalStateException();
+        }
+        int length = elements.length;
+        int newLength = length << 1;
+        // bigger than Integer.MAX_VALUE
+        if (newLength < 0) {
+            newLength = Integer.MAX_VALUE;
+        }
+        E[] newElements = (E[]) new Object[newLength];
+        System.arraycopy(elements, front, newElements, 0, length - front);
+        System.arraycopy(elements, 0, newElements, length - front, front);
+        front = 0;
+        rear = length;
+        status = DequeStatus.Normal;
+        elements = newElements;
+    }
+
+    /**
+     * Resets the status after adding or removing operation.
+     *
+     * @param adding
+     *            if the method is called after an "adding" operation
+     */
+    private void resetStatus(boolean adding) {
+        if (front == rear) {
+            status = adding ? DequeStatus.Full : DequeStatus.Empty;
+        } else {
+            status = DequeStatus.Normal;
+        }
+    }
+
+    private  boolean addLastImpl(E e) {
+        checkNull(e);
+        checkAndExpand();
+        elements[rear] = e;
+        rear = circularBiggerPos(rear);
+        resetStatus(true);
+        modCount++;
+        return true;
+    }
+
+    private E removePollFirstImpl() {
+        E element = elements[front];
+        elements[front] = null;
+        front = circularBiggerPos(front);
+        resetStatus(false);
+        modCount++;
+        return element;
+    }
+
+    private E removeLastImpl() {
+        int last = circularSmallerPos(rear);
+        E element = elements[last];
+        elements[last] = null;
+        rear = last;
+        resetStatus(false);
+        modCount++;
+        return element;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param obj
+     *            the element to be removed
+     * @return true if the operation succeeds or false if the deque does not
+     *         contain the element
+     * @see java.util.Deque#removeFirstOccurrence(java.lang.Object)
+     */
+    public boolean removeFirstOccurrence(Object obj) {
+        return removeFirstOccurrenceImpl(obj);
+    }
+
+    /**
+     * Removes the first equivalent element of the specified object. If the
+     * deque does not contain the element, it is unchanged and returns false.
+     *
+     * @param obj
+     *            the element to be removed
+     * @return true if the operation succeeds or false if the deque does not
+     *         contain the element
+     * @see java.util.AbstractCollection#remove(java.lang.Object)
+     */
+    @Override
+    public boolean remove(Object obj) {
+        return removeFirstOccurrenceImpl(obj);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param obj
+     *            the element to be removed
+     * @return true if the operation succeeds or false if the deque does not
+     *         contain the element.
+     * @see java.util.Deque#removeLastOccurrence(java.lang.Object)
+     */
+    public  boolean removeLastOccurrence(final Object obj) {
+        if (null != obj) {
+            Iterator<E> iter = descendingIterator();
+            while (iter.hasNext()) {
+                if (iter.next().equals(obj)) {
+                    iter.remove();
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private  boolean removeFirstOccurrenceImpl(final Object obj) {
+        if (null != obj) {
+            Iterator<E> iter = iterator();
+            while (iter.hasNext()) {
+                if (iter.next().equals(obj)) {
+                    iter.remove();
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /*
+     * Removes the element in the cursor position and shifts front elements to
+     * fill the gap if frontShift is true, shifts rear elements otherwise.
+     *
+     */
+    private void removeInternal(final int current, final boolean frontShift) {
+        int cursor = current;
+        if (frontShift) {
+            while (cursor != front) {
+                int next = circularSmallerPos(cursor);
+                elements[cursor] = elements[next];
+                cursor = next;
+            }
+            front = circularBiggerPos(front);
+        } else {
+            while (cursor != rear) {
+                int next = circularBiggerPos(cursor);
+                elements[cursor] = elements[next];
+                cursor = next;
+            }
+            rear = circularSmallerPos(rear);
+        }
+        elements[cursor] = null;
+        resetStatus(false);
+    }
+
+    /**
+     * Returns the size of the deque.
+     *
+     * @return the size of the deque
+     * @see java.util.AbstractCollection#size()
+     */
+    @Override
+    public  int size() {
+        if (status == DequeStatus.Full) {
+            return elements.length;
+        }
+        return (front <= rear) ? (rear - front)
+                : (rear + elements.length - front);
+    }
+
+    /**
+     * Returns true if the deque has no elements.
+     *
+     * @return true if the deque has no elements, false otherwise
+     * @see java.util.AbstractCollection#isEmpty()
+     */
+    @Override
+    public  boolean isEmpty() {
+        return 0 == size();
+    }
+
+    /**
+     * Returns true if the specified element is in the deque.
+     *
+     * @param obj
+     *            the element
+     * @return true if the element is in the deque, false otherwise
+     * @see java.util.AbstractCollection#contains(java.lang.Object)
+     */
+    @SuppressWarnings("cast")
+    @Override
+    public  boolean contains(final Object obj) {
+        if (null != obj) {
+            Iterator<E> it = new ArrayDequeIterator<E>();
+            while (it.hasNext()) {
+                if (obj.equals((E) it.next())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Empty the deque.
+     *
+     * @see java.util.AbstractCollection#clear()
+     */
+    @SuppressWarnings("cast")
+    @Override
+    public  void clear() {
+        if (status != DequeStatus.Empty) {
+            int cursor = front;
+            do {
+                elements[cursor] = null;
+                cursor = circularBiggerPos(cursor);
+            } while (cursor != rear);
+            status = DequeStatus.Empty;
+        }
+        front = rear = 0;
+        modCount = 0;
+    }
+
+    /**
+     * Returns a clone of the deque.
+     *
+     * @return the clone of the deque
+     * @see java.lang.Object#clone()
+     * @see java.lang.Cloneable
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public  ArrayDeque<E> clone() {
+        try {
+            ArrayDeque<E> newDeque = (ArrayDeque<E>) super.clone();
+            newDeque.elements = elements.clone();
+            return newDeque;
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns all the elements in an array from head to tail. The result is a
+     * copy of all the elements.
+     *
+     * @return the Array of all the elements
+     * @see java.util.AbstractCollection#toArray()
+     */
+    @Override
+    public Object[] toArray() {
+        return newArray(new Object[size()]);
+    }
+
+    /**
+     * Returns all the elements in an array from head to tail, and the type of
+     * the result array is the type of the argument array. If the argument array
+     * is big enough, the elements from the deque will be stored in it(elements
+     * following the tail of the deque is set to null, if any); otherwise, it
+     * will return a new array with the size of the argument array and size of
+     * the deque.
+     *
+     * @param <T>
+     *            the type of elements in the array
+     * @param array
+     *            the array stores all the elements from the deque, if it has
+     *            enough space; otherwise, a new array of the same type and the
+     *            size of the deque will be used
+     * @return the Array of all the elements
+     * @throws ArrayStoreException
+     *             if the type of the argument array is not compatible with
+     *             every element in the deque
+     * @throws NullPointerException
+     *             if the argument array is null
+     * @see java.util.AbstractCollection#toArray
+     */
+    @Override
+    public <T> T[] toArray(T[] array) {
+        return newArray(array);
+    }
+
+    @SuppressWarnings("unchecked")
+    private  <T> T[] newArray(T[] array) {
+        int size = size();
+        if (size > array.length) {
+            Class<?> clazz = array.getClass().getComponentType();
+            array = (T[]) Array.newInstance(clazz, size);
+        }
+        if (front < rear) {
+            System.arraycopy(elements, front, array, 0, size);
+        } else if (size != 0) {
+            int length = elements.length;
+            System.arraycopy(elements, front, array, 0, length - front);
+            System.arraycopy(elements, 0, array, length - front, rear);
+        }
+        if (size < array.length) {
+            array[size] = null;
+        }
+        return array;
+    }
+
+    /**
+     * Returns the iterator of the deque. The elements will be ordered from head
+     * to tail.
+     *
+     * @return the iterator
+     * @see java.util.AbstractCollection#iterator()
+     */
+    @SuppressWarnings("synthetic-access")
+    @Override
+    public Iterator<E> iterator() {
+        return new ArrayDequeIterator<E>();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the reverse order Iterator
+     * @see java.util.Deque#descendingIterator()
+     */
+    public Iterator<E> descendingIterator() {
+        return new ReverseArrayDequeIterator<E>();
+    }
+
+    /**
+     * Deserialization method.
+     *
+     * @param stream
+     *            the ObjectInputStream
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    @SuppressWarnings("unchecked")
+    private void readObject(ObjectInputStream stream) throws IOException,
+            ClassNotFoundException {
+        stream.defaultReadObject();
+        int size = stream.readInt();
+        elements = (E[]) new Object[countInitSize(size)];
+        front = rear = 0;
+        status = DequeStatus.Empty;
+        modCount = 0;
+        for (int i = 0; i < size; i++) {
+            addLastImpl((E) stream.readObject());
+        }
+    }
+
+    /**
+     * Serialization method.
+     *
+     * @param stream
+     *            the ObjectOutputStream
+     * @serialData The current size of the deque, followed by all the elements
+     *             from head to tail.
+     * @throws IOException
+     *
+     */
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        stream.defaultWriteObject();
+        stream.writeInt(size());
+        Iterator<?> it = new ArrayDequeIterator<E>();
+        while (it.hasNext()) {
+            stream.writeObject(it.next());
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/luni/src/main/java/java/util/Arrays.java b/luni/src/main/java/java/util/Arrays.java
index c49a298..44f7616 100644
--- a/luni/src/main/java/java/util/Arrays.java
+++ b/luni/src/main/java/java/util/Arrays.java
@@ -172,83 +172,142 @@
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code byte} array to search.
-     * @param value
-     *            the {@code byte} element to find.
+     * @param array the sorted array to search.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
      */
     public static int binarySearch(byte[] array, byte value) {
-         int lo = 0;
-         int hi = array.length - 1;
-
-         while (lo <= hi) {
-             int mid = (lo + hi) >>> 1;
-             byte midVal = array[mid];
-
-             if (midVal < value)
-                 lo = mid + 1;
-             else if (midVal > value)
-                 hi = mid - 1;
-             else
-                 return mid;  // value found
-         }
-         return ~lo;  // value not present
+        return binarySearch(array, 0, array.length, value);
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code char} array to search.
-     * @param value
-     *            the {@code char} element to find.
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(byte[] array, int startIndex, int endIndex, byte value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            byte midVal = array[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
      */
     public static int binarySearch(char[] array, char value) {
-         int lo = 0;
-         int hi = array.length - 1;
-
-         while (lo <= hi) {
-             int mid = (lo + hi) >>> 1;
-             char midVal = array[mid];
-
-             if (midVal < value)
-                 lo = mid + 1;
-             else if (midVal > value)
-                 hi = mid - 1;
-             else
-                 return mid;  // value found
-         }
-         return ~lo;  // value not present
+        return binarySearch(array, 0, array.length, value);
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code double} array to search.
-     * @param value
-     *            the {@code double} element to find.
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(char[] array, int startIndex, int endIndex, char value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            char midVal = array[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
      */
     public static int binarySearch(double[] array, double value) {
-        int lo = 0;
-        int hi = array.length - 1;
+        return binarySearch(array, 0, array.length, value);
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(double[] array, int startIndex, int endIndex, double value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
 
         while (lo <= hi) {
             int mid = (lo + hi) >>> 1;
@@ -264,33 +323,53 @@
                 long midValBits = Double.doubleToLongBits(midVal);
                 long valueBits  = Double.doubleToLongBits(value);
 
-                if (midValBits < valueBits)
+                if (midValBits < valueBits) {
                     lo = mid + 1; // (-0.0, 0.0) or (not NaN, NaN); midVal < val
-                else if (midValBits > valueBits)
+                } else if (midValBits > valueBits) {
                     hi = mid - 1; // (0.0, -0.0) or (NaN, not NaN); midVal > val
-                else
+                } else {
                     return mid; // bit patterns are equal; value found
+                }
             }
         }
         return ~lo;  // value not present
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code float} array to search.
-     * @param value
-     *            the {@code float} element to find.
+     * @param array the sorted array to search.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
      */
     public static int binarySearch(float[] array, float value) {
-        int lo = 0;
-        int hi = array.length - 1;
+        return binarySearch(array, 0, array.length, value);
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(float[] array, int startIndex, int endIndex, float value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
 
         while (lo <= hi) {
             int mid = (lo + hi) >>> 1;
@@ -306,184 +385,302 @@
                 int midValBits = Float.floatToIntBits(midVal);
                 int valueBits  = Float.floatToIntBits(value);
 
-                if (midValBits < valueBits)
+                if (midValBits < valueBits) {
                     lo = mid + 1; // (-0.0, 0.0) or (not NaN, NaN); midVal < val
-                else if (midValBits > valueBits)
+                } else if (midValBits > valueBits) {
                     hi = mid - 1; // (0.0, -0.0) or (NaN, not NaN); midVal > val
-                else
+                } else {
                     return mid; // bit patterns are equal; value found
+                }
             }
         }
         return ~lo;  // value not present
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code int} array to search.
-     * @param value
-     *            the {@code int} element to find.
+     * @param array the sorted array to search.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
      */
- public static int binarySearch(int[] array, int value) {
-         int lo = 0;
-         int hi = array.length - 1;
-
-         while (lo <= hi) {
-             int mid = (lo + hi) >>> 1;
-             int midVal = array[mid];
-
-             if (midVal < value)
-                 lo = mid + 1;
-             else if (midVal > value)
-                 hi = mid - 1;
-             else
-                 return mid;  // value found
-         }
-         return ~lo;  // value not present
-     }
-
-    /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
-     *
-     * @param array
-     *            the sorted {@code long} array to search.
-     * @param value
-     *            the {@code long} element to find.
-     * @return the non-negative index of the element, or a negative index which
-     *         is {@code -index - 1} where the element would be inserted.
-     */
-    public static int binarySearch(long[] array, long value) {
-         int lo = 0;
-         int hi = array.length - 1;
-
-         while (lo <= hi) {
-             int mid = (lo + hi) >>> 1;
-             long midVal = array[mid];
-
-             if (midVal < value)
-                 lo = mid + 1;
-             else if (midVal > value)
-                 hi = mid - 1;
-             else
-                 return mid;  // value found
-         }
-         return ~lo;  // value not present
+    public static int binarySearch(int[] array, int value) {
+        return binarySearch(array, 0, array.length, value);
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code Object} array to search.
-     * @param value
-     *            the {@code Object} element to find.
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
-     * @throws ClassCastException
-     *                if an element in the array or the search element does not
-     *                implement {@code Comparable}, or cannot be compared to each other.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
      */
-    public static int binarySearch(Object[] array, Object value) {
-         int lo = 0;
-         int hi = array.length - 1;
-
-         while (lo <= hi) {
-             int mid = (lo + hi) >>> 1;
-             @SuppressWarnings("unchecked")
-             int midValCmp = ((Comparable) array[mid]).compareTo(value);
-
-             if (midValCmp < 0)
-                 lo = mid + 1;
-             else if (midValCmp > 0)
-                 hi = mid - 1;
-             else
-                 return mid;  // value found
-         }
-         return ~lo;  // value not present
-    }
-
-    /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array using the {@code Comparator} to compare elements.
-     * Searching in an unsorted array has an undefined result. It's also
-     * undefined which element is found if there are multiple occurrences of the
-     * same element.
-     *
-     * @param array
-     *            the sorted array to search
-     * @param value
-     *            the element to find
-     * @param comparator
-     *            the {@code Comparator} sued to compare the elements.
-     * @return the non-negative index of the element, or a negative index which
-     *         is {@code -index - 1} where the element would be inserted.
-     * @throws ClassCastException
-     *                if an element in the array cannot be compared to the search element
-     *                using the {@code Comparator}.
-     */
-    public static <T> int binarySearch(T[] array, T value,
-            Comparator<? super T> comparator) {
-        if (comparator == null)
-            return binarySearch(array, value);
-
-        int lo = 0;
-        int hi = array.length - 1;
+    public static int binarySearch(int[] array, int startIndex, int endIndex, int value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
 
         while (lo <= hi) {
             int mid = (lo + hi) >>> 1;
-            int midValCmp = comparator.compare(array[mid], value);
+            int midVal = array[mid];
 
-            if (midValCmp < 0)
+            if (midVal < value) {
                 lo = mid + 1;
-            else if (midValCmp > 0)
+            } else if (midVal > value) {
                 hi = mid - 1;
-            else
+            } else {
                 return mid;  // value found
+            }
         }
         return ~lo;  // value not present
     }
 
     /**
-     * Performs a binary search for the specified element in the specified
-     * ascending sorted array. Searching in an unsorted array has an undefined
-     * result. It's also undefined which element is found if there are multiple
-     * occurrences of the same element.
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
      *
-     * @param array
-     *            the sorted {@code short} array to search.
-     * @param value
-     *            the {@code short} element to find.
+     * @param array the sorted array to search.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     */
+    public static int binarySearch(long[] array, long value) {
+        return binarySearch(array, 0, array.length, value);
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(long[] array, int startIndex, int endIndex, long value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            long midVal = array[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+         }
+         return ~lo;  // value not present
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws ClassCastException
+     *         if an element in the array or the search element does not
+     *         implement {@code Comparable}, or cannot be compared to each other.
+     */
+    public static int binarySearch(Object[] array, Object value) {
+        return binarySearch(array, 0, array.length, value);
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws ClassCastException
+     *         if an element in the array or the search element does not
+     *         implement {@code Comparable}, or cannot be compared to each other.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(Object[] array, int startIndex, int endIndex, Object value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            @SuppressWarnings("unchecked")
+            int midValCmp = ((Comparable) array[mid]).compareTo(value);
+
+            if (midValCmp < 0) {
+                lo = mid + 1;
+            } else if (midValCmp > 0) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * using {@comparator} to compare elements.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param value the element to find.
+     * @param comparator the {@code Comparator} used to compare the elements.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws ClassCastException
+     *         if an element in the array or the search element does not
+     *         implement {@code Comparable}, or cannot be compared to each other.
+     */
+    public static <T> int binarySearch(T[] array, T value, Comparator<? super T> comparator) {
+        return binarySearch(array, 0, array.length, value, comparator);
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive),
+     * using {@comparator} to compare elements.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @param comparator the {@code Comparator} used to compare the elements.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws ClassCastException
+     *         if an element in the array or the search element does not
+     *         implement {@code Comparable}, or cannot be compared to each other.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static <T> int binarySearch(T[] array, int startIndex, int endIndex, T value,
+            Comparator<? super T> comparator) {
+        if (comparator == null) {
+            return binarySearch(array, startIndex, endIndex, value);
+        }
+
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            int midValCmp = comparator.compare(array[mid], value);
+
+            if (midValCmp < 0) {
+                lo = mid + 1;
+            } else if (midValCmp > 0) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array}.
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param value the element to find.
      * @return the non-negative index of the element, or a negative index which
      *         is {@code -index - 1} where the element would be inserted.
      */
     public static int binarySearch(short[] array, short value) {
-         int lo = 0;
-         int hi = array.length - 1;
+        return binarySearch(array, 0, array.length, value);
+    }
 
-         while (lo <= hi) {
-             int mid = (lo + hi) >>> 1;
-             short midVal = array[mid];
+    /**
+     * Performs a binary search for {@code value} in the ascending sorted array {@code array},
+     * in the range specified by fromIndex (inclusive) and toIndex (exclusive).
+     * Searching in an unsorted array has an undefined result. It's also undefined which element
+     * is found if there are multiple occurrences of the same element.
+     *
+     * @param array the sorted array to search.
+     * @param startIndex the inclusive start index.
+     * @param endIndex the exclusive start index.
+     * @param value the element to find.
+     * @return the non-negative index of the element, or a negative index which
+     *         is {@code -index - 1} where the element would be inserted.
+     * @throws IllegalArgumentException if {@code startIndex > endIndex}
+     * @throws ArrayIndexOutOfBoundsException if {@code startIndex < 0 || endIndex > array.length}
+     * @since 1.6
+     * @hide
+     */
+    public static int binarySearch(short[] array, int startIndex, int endIndex, short value) {
+        checkBinarySearchBounds(startIndex, endIndex, array.length);
+        int lo = startIndex;
+        int hi = endIndex - 1;
 
-             if (midVal < value)
-                 lo = mid + 1;
-             else if (midVal > value)
-                 hi = mid - 1;
-             else
-                 return mid;  // value found
-         }
-         return ~lo;  // value not present
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            short midVal = array[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    private static void checkBinarySearchBounds(int startIndex, int endIndex, int length) {
+        if (startIndex > endIndex) {
+            throw new IllegalArgumentException();
+        }
+        if (startIndex < 0 || endIndex > length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
     }
 
     /**
@@ -517,7 +714,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(byte[] array, int start, int end, byte value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -554,7 +751,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(short[] array, int start, int end, short value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -591,7 +788,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(char[] array, int start, int end, char value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -628,7 +825,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(int[] array, int start, int end, int value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -665,7 +862,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(long[] array, int start, int end, long value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -702,7 +899,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(float[] array, int start, int end, float value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -739,7 +936,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(double[] array, int start, int end, double value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -776,7 +973,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(boolean[] array, int start, int end, boolean value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -813,7 +1010,7 @@
      *                if {@code start < 0} or {@code end > array.length}.
      */
     public static void fill(Object[] array, int start, int end, Object value) {
-        checkBounds(array.length, start, end);
+        checkFillBounds(array.length, start, end);
         for (int i = start; i < end; i++) {
             array[i] = value;
         }
@@ -1549,7 +1746,7 @@
         DualPivotQuicksort.sort(array, start, end);
     }
 
-    private static void checkBounds(int arrLength, int start, int end) {
+    private static void checkFillBounds(int arrLength, int start, int end) {
         if (start > end) {
             // K0033=Start index ({0}) is greater than end index ({1})
             throw new IllegalArgumentException(Msg.getString("K0033", //$NON-NLS-1$
@@ -2314,4 +2511,529 @@
         }
         return false;
     }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code false}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static boolean[] copyOf(boolean[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code (byte) 0}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static byte[] copyOf(byte[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code '\\u0000'}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static char[] copyOf(char[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0.0d}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static double[] copyOf(double[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0.0f}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static float[] copyOf(float[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static int[] copyOf(int[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0L}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static long[] copyOf(long[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code (short) 0}.
+     *
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static short[] copyOf(short[] original, int newLength) {
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code null}.
+     *
+     * @param <T> array element type
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static <T> T[] copyOf(T[] original, int newLength) {
+        if (original == null) {
+            throw new NullPointerException();
+        }
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength);
+    }
+
+    /**
+     * Copies {@code newLength} elements from {@code original} into a new array.
+     * If {@code newLength} is greater than {@code original.length}, the result is padded
+     * with the value {@code null}.
+     *
+     * @param <T> result array element type
+     * @param <U> original array element type
+     * @param original the original array
+     * @param newLength the length of the new array
+     * @param newType the class of the new array
+     * @return the new array
+     * @throws NegativeArraySizeException if {@code newLength < 0}
+     * @throws NullPointerException if {@code original == null}
+     * @throws ArrayStoreException if a value in {@code original} is incompatible with T
+     * @since 1.6
+     * @hide
+     */
+    public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
+        // We use the null pointer check in copyOfRange for exception priority compatibility.
+        if (newLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+        return copyOfRange(original, 0, newLength, newType);
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code false}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static boolean[] copyOfRange(boolean[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        boolean[] result = new boolean[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code (byte) 0}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static byte[] copyOfRange(byte[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        byte[] result = new byte[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code '\\u0000'}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static char[] copyOfRange(char[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        char[] result = new char[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0.0d}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static double[] copyOfRange(double[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        double[] result = new double[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0.0f}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static float[] copyOfRange(float[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        float[] result = new float[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static int[] copyOfRange(int[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        int[] result = new int[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code 0L}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static long[] copyOfRange(long[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        long[] result = new long[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code (short) 0}.
+     *
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    public static short[] copyOfRange(short[] original, int start, int end) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        short[] result = new short[resultLength];
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code null}.
+     *
+     * @param <T> the element type
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @since 1.6
+     * @hide
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] copyOfRange(T[] original, int start, int end) {
+        int originalLength = original.length; // For exception priority compatibility.
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        T[] result = (T[]) Array.newInstance(original.getClass().getComponentType(), resultLength);
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
+
+    /**
+     * Copies elements from {@code original} into a new array, from indexes start (inclusive) to
+     * end (exclusive). The original order of elements is preserved.
+     * If {@code end} is greater than {@code original.length}, the result is padded
+     * with the value {@code null}.
+     *
+     * @param <T> result array element type
+     * @param <U> original array element type
+     * @param original the original array
+     * @param start the start index, inclusive
+     * @param end the end index, exclusive
+     * @return the new array
+     * @throws ArrayIndexOutOfBoundsException if {@code start < 0 || start > original.length}
+     * @throws IllegalArgumentException if {@code start > end}
+     * @throws NullPointerException if {@code original == null}
+     * @throws ArrayStoreException if a value in {@code original} is incompatible with T
+     * @since 1.6
+     * @hide
+     */
+    @SuppressWarnings("unchecked")
+    public static <T, U> T[] copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType) {
+        if (start > end) {
+            throw new IllegalArgumentException();
+        }
+        int originalLength = original.length;
+        if (start < 0 || start > originalLength) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        int resultLength = end - start;
+        int copyLength = Math.min(resultLength, originalLength - start);
+        T[] result = (T[]) Array.newInstance(newType.getComponentType(), resultLength);
+        System.arraycopy(original, start, result, 0, copyLength);
+        return result;
+    }
 }
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java
index 7f2e92d..3e5e43d 100644
--- a/luni/src/main/java/java/util/Calendar.java
+++ b/luni/src/main/java/java/util/Calendar.java
@@ -17,13 +17,14 @@
 
 package java.util;
 
+import com.ibm.icu4jni.util.LocaleData;
+import com.ibm.icu4jni.util.ICU;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
-
-import com.ibm.icu4jni.util.LocaleData;
+import java.text.DateFormatSymbols;
 
 /**
  * {@code Calendar} is an abstract base class for converting between a
@@ -285,36 +286,48 @@
  * @see GregorianCalendar
  * @see TimeZone
  */
-public abstract class Calendar implements Serializable, Cloneable,
-        Comparable<Calendar> {
+public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
 
     private static final long serialVersionUID = -1807547505821590642L;
 
     /**
-     * Set to {@code true} when the calendar fields have been set from the time, set to
-     * {@code false} when a field is changed and the fields must be recomputed.
+     * True iff the values in {@code fields[]} correspond to {@code time}. Despite the name, this
+     * is effectively "are the values in fields[] up-to-date?" --- {@code fields[]} may contain
+     * non-zero values and {@code isSet[]} may contain {@code true} values even when
+     * {@code areFieldsSet} is false.
+     * Accessing the fields via {@code get} will ensure the fields are up-to-date.
      */
     protected boolean areFieldsSet;
 
     /**
-     * An integer array of calendar fields. The length is {@code FIELD_COUNT}.
+     * Contains broken-down field values for the current value of {@code time} if
+     * {@code areFieldsSet} is true, or stale data corresponding to some previous value otherwise.
+     * Accessing the fields via {@code get} will ensure the fields are up-to-date.
+     * The array length is always {@code FIELD_COUNT}.
      */
     protected int[] fields;
 
     /**
-     * A boolean array. Each element indicates if the corresponding field has
-     * been set. The length is {@code FIELD_COUNT}.
+     * Whether the corresponding element in {@code field[]} has been set. Initially, these are all
+     * false. The first time the fields are computed, these are set to true and remain set even if
+     * the data becomes stale: you <i>must</i> check {@code areFieldsSet} if you want to know
+     * whether the value is up-to-date.
+     * Note that {@code isSet} is <i>not</i> a safe alternative to accessing this array directly,
+     * and will likewise return stale data!
+     * The array length is always {@code FIELD_COUNT}.
      */
     protected boolean[] isSet;
 
     /**
-     * Set to {@code true} when the time has been set, set to {@code false} when a field is
-     * changed and the time must be recomputed.
+     * Whether {@code time} corresponds to the values in {@code fields[]}. If false, {@code time}
+     * is out-of-date with respect to changes {@code fields[]}.
+     * Accessing the time via {@code getTimeInMillis} will always return the correct value.
      */
     protected boolean isTimeSet;
 
     /**
-     * The time in milliseconds since January 1, 1970.
+     * A time in milliseconds since January 1, 1970. See {@code isTimeSet}.
+     * Accessing the time via {@code getTimeInMillis} will always return the correct value.
      */
     protected long time;
 
@@ -656,11 +669,35 @@
      */
     public static final int PM = 1;
 
-    private static String[] fieldNames = { "ERA=", "YEAR=", "MONTH=", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-            "WEEK_OF_YEAR=", "WEEK_OF_MONTH=", "DAY_OF_MONTH=", "DAY_OF_YEAR=", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-            "DAY_OF_WEEK=", "DAY_OF_WEEK_IN_MONTH=", "AM_PM=", "HOUR=", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
-            "HOUR_OF_DAY", "MINUTE=", "SECOND=", "MILLISECOND=", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-            "ZONE_OFFSET=", "DST_OFFSET=" }; //$NON-NLS-1$ //$NON-NLS-2$
+    /**
+     * Requests both {@code SHORT} and {@code LONG} styles in the map returned by
+     * {@link getDisplayNames}.
+     * @since 1.6
+     * @hide
+     */
+    public static final int ALL_STYLES = 0;
+
+    /**
+     * Requests short names (such as "Jan") from
+     * {@link getDisplayName} or {@link getDisplayNames}.
+     * @since 1.6
+     * @hide
+     */
+    public static final int SHORT = 1;
+
+    /**
+     * Requests long names (such as "January") from
+     * {@link getDisplayName} or {@link getDisplayNames}.
+     * @since 1.6
+     * @hide
+     */
+    public static final int LONG = 2;
+
+    private static final String[] FIELD_NAMES = { "ERA", "YEAR", "MONTH",
+            "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", "DAY_OF_YEAR",
+            "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
+            "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND",
+            "ZONE_OFFSET", "DST_OFFSET" };
 
     /**
      * Constructs a {@code Calendar} instance using the default {@code TimeZone} and {@code Locale}.
@@ -687,11 +724,9 @@
      */
     protected Calendar(TimeZone timezone, Locale locale) {
         this(timezone);
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
+        LocaleData localeData = LocaleData.get(locale);
         setFirstDayOfWeek(localeData.firstDayOfWeek.intValue());
         setMinimalDaysInFirstWeek(localeData.minimalDaysInFirstWeek.intValue());
-        // END android-changed
     }
 
 
@@ -921,12 +956,11 @@
     }
 
     /**
-     * Gets the list of installed {@code Locale}s which support {@code Calendar}.
-     *
-     * @return an array of {@code Locale}.
+     * Returns an array of locales for which custom {@code Calendar} instances
+     * are available.
      */
     public static synchronized Locale[] getAvailableLocales() {
-        return Locale.getAvailableLocales();
+        return ICU.getAvailableCalendarLocales();
     }
 
     /**
@@ -1116,7 +1150,16 @@
     }
 
     /**
-     * Returns whether the specified field is set.
+     * Returns whether the specified field is set. Note that the interpretation of "is set" is
+     * somewhat technical. In particular, it does <i>not</i> mean that the field's value is up
+     * to date. If you want to know whether a field contains an up-to-date value, you must also
+     * check {@code areFieldsSet}, making this method somewhat useless unless you're a subclass,
+     * in which case you can access the {@code isSet} array directly.
+     * <p>
+     * A field remains "set" from the first time its value is computed until it's cleared by one
+     * of the {@code clear} methods. Thus "set" does not mean "valid". You probably want to call
+     * {@code get} -- which will update fields as necessary -- rather than try to make use of
+     * this method.
      *
      * @param field
      *            a {@code Calendar} field number.
@@ -1328,7 +1371,7 @@
                 + minimalDaysInFirstWeek);
         for (int i = 0; i < FIELD_COUNT; i++) {
             result.append(',');
-            result.append(fieldNames[i]);
+            result.append(FIELD_NAMES[i]);
             result.append('=');
             if (isSet[i]) {
                 result.append(fields[i]);
@@ -1370,6 +1413,99 @@
         return -1;
     }
 
+    /**
+     * Returns a human-readable string for the value of {@code field}
+     * using the given style and locale. If no string is available, returns null.
+     * The value is retrieved by invoking {@code get(field)}.
+     * 
+     * <p>For example, {@code getDisplayName(MONTH, SHORT, Locale.US)} will return "Jan"
+     * while {@code getDisplayName(MONTH, LONG, Locale.US)} will return "January".
+     * 
+     * @param field the field
+     * @param style {@code SHORT} or {@code LONG}
+     * @param locale the locale
+     * @return the display name, or null
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException if {@code field} or {@code style} is invalid
+     * @since 1.6
+     * @hide
+     */
+    public String getDisplayName(int field, int style, Locale locale) {
+        // TODO: the RI's documentation says ALL_STYLES is invalid, but actually treats it as SHORT.
+        if (style == ALL_STYLES) {
+            style = SHORT;
+        }
+        String[] array = getDisplayNameArray(field, style, locale);
+        int value = get(field);
+        return (array != null) ? array[value] : null;
+    }
+
+    private String[] getDisplayNameArray(int field, int style, Locale locale) {
+        if (field < 0 || field >= FIELD_COUNT) {
+            throw new IllegalArgumentException("bad field " + field);
+        }
+        checkStyle(style);
+        DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale);
+        switch (field) {
+        case AM_PM:
+            return dfs.getAmPmStrings();
+        case DAY_OF_WEEK:
+            return (style == LONG) ? dfs.getWeekdays() : dfs.getShortWeekdays();
+        case ERA:
+            return dfs.getEras();
+        case MONTH:
+            return (style == LONG) ? dfs.getMonths() : dfs.getShortMonths();
+        }
+        return null;
+    }
+
+    private static void checkStyle(int style) {
+        if (style != ALL_STYLES && style != SHORT && style != LONG) {
+            throw new IllegalArgumentException("bad style " + style);
+        }
+    }
+
+    /**
+     * Returns a map of human-readable strings to corresponding values,
+     * for the given field, style, and locale.
+     * Returns null if no strings are available.
+     * 
+     * <p>For example, {@code getDisplayNames(MONTH, ALL_STYLES, Locale.US)} would
+     * contain mappings from "Jan" and "January" to {@link JANUARY}, and so on.
+     * 
+     * @param field the field
+     * @param style {@code SHORT}, {@code LONG}, or {@code ALL_STYLES}
+     * @param locale the locale
+     * @return the display name, or null
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException if {@code field} or {@code style} is invalid
+     * @since 1.6
+     * @hide
+     */
+    public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) {
+        checkStyle(style);
+        complete();
+        Map<String, Integer> result = new HashMap<String, Integer>();
+        if (style == SHORT || style == ALL_STYLES) {
+            insertValuesInMap(result, getDisplayNameArray(field, SHORT, locale));
+        }
+        if (style == LONG || style == ALL_STYLES) {
+            insertValuesInMap(result, getDisplayNameArray(field, LONG, locale));
+        }
+        return result.isEmpty() ? null : result;
+    }
+
+    private static void insertValuesInMap(Map<String, Integer> map, String[] values) {
+        if (values == null) {
+            return;
+        }
+        for (int i = 0; i < values.length; ++i) {
+            if (values[i] != null && !values[i].isEmpty()) {
+                map.put(values[i], i);
+            }
+        }
+    }
+
     @SuppressWarnings("nls")
     private static final ObjectStreamField[] serialPersistentFields = {
             new ObjectStreamField("areFieldsSet", Boolean.TYPE), //$NON-NLS-1$
diff --git a/luni/src/main/java/java/util/Collections.java b/luni/src/main/java/java/util/Collections.java
index 9774888..af49cc0 100644
--- a/luni/src/main/java/java/util/Collections.java
+++ b/luni/src/main/java/java/util/Collections.java
@@ -22,8 +22,6 @@
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.lang.reflect.Array;
-
-import org.apache.harmony.luni.internal.nls.Messages;
 import org.apache.harmony.luni.util.Msg;
 
 /**
@@ -211,31 +209,26 @@
         }
     }
 
-    private static final class ReverseComparatorWithComparator<T> implements
-            Comparator<T>, Serializable {
+    private static final class ReverseComparator2<T>
+            implements Comparator<T>, Serializable {
         private static final long serialVersionUID = 4374092139857L;
+        private final Comparator<T> cmp;
 
-        private final Comparator<T> comparator;
-
-        ReverseComparatorWithComparator(Comparator<T> comparator) {
-            super();
-            this.comparator = comparator;
+        ReverseComparator2(Comparator<T> comparator) {
+            this.cmp = comparator;
         }
 
         public int compare(T o1, T o2) {
-            return comparator.compare(o2, o1);
+            return cmp.compare(o2, o1);
         }
 
-        @Override
-        public boolean equals(Object o) {
-            return o instanceof ReverseComparatorWithComparator
-                    && ((ReverseComparatorWithComparator) o).comparator
-                            .equals(comparator);
+        @Override public boolean equals(Object o) {
+            return o instanceof ReverseComparator2
+                    && ((ReverseComparator2) o).cmp.equals(cmp);
         }
 
-        @Override
-        public int hashCode() {
-            return ~comparator.hashCode();
+        @Override public int hashCode() {
+            return ~cmp.hashCode();
         }
     }
 
@@ -1837,10 +1830,10 @@
         if (c == null) {
             return reverseOrder();
         }
-        if (c instanceof ReverseComparatorWithComparator) {
-            return ((ReverseComparatorWithComparator<T>) c).comparator;
+        if (c instanceof ReverseComparator2) {
+            return ((ReverseComparator2<T>) c).cmp;
         }
-        return new ReverseComparatorWithComparator<T>(c);
+        return new ReverseComparator2<T>(c);
     }
 
     /**
@@ -2687,10 +2680,8 @@
      */
     static <E> E checkType(E obj, Class<? extends E> type) {
         if (obj != null && !type.isInstance(obj)) {
-            // luni.05=Attempt to insert {0} element into collection with
-            // element type {1}
-            throw new ClassCastException(Messages.getString(
-                    "luni.05", obj.getClass(), type)); //$NON-NLS-1$
+            throw new ClassCastException("Attempt to insert element of type " + obj.getClass() +
+                    " into collection of type " + type);
         }
         return obj;
     }
diff --git a/luni/src/main/java/java/util/ConcurrentModificationException.java b/luni/src/main/java/java/util/ConcurrentModificationException.java
index 43d5a63..a9ca4e3 100644
--- a/luni/src/main/java/java/util/ConcurrentModificationException.java
+++ b/luni/src/main/java/java/util/ConcurrentModificationException.java
@@ -23,7 +23,6 @@
  * Collection as well.
  * 
  * @see java.lang.RuntimeException
- * @since Android 1.0
  */
 public class ConcurrentModificationException extends RuntimeException {
 
diff --git a/luni/src/main/java/java/util/Currency.java b/luni/src/main/java/java/util/Currency.java
index 6aa295a..83d7f80 100644
--- a/luni/src/main/java/java/util/Currency.java
+++ b/luni/src/main/java/java/util/Currency.java
@@ -17,16 +17,13 @@
 
 package java.util;
 
-// BEGIN android-added
+import com.ibm.icu4jni.util.ICU;
 import com.ibm.icu4jni.util.LocaleData;
-import com.ibm.icu4jni.util.Resources;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.logging.Logger;
 import org.apache.harmony.luni.util.Msg;
-// END android-added
-
-import java.security.AccessController;
-import java.io.Serializable;
-import java.security.PrivilegedAction;
 
 /**
  * This class represents a currency as identified in the ISO 4217 currency
@@ -58,8 +55,17 @@
             return;
         }
 
-        this.defaultFractionDigits = Resources.getCurrencyFractionDigitsNative(currencyCode);
+        // Ensure that we throw if the our currency code isn't an ISO currency code.
+        String symbol = ICU.getCurrencySymbolNative(Locale.US.toString(), currencyCode);
+        if (symbol == null) {
+            throw new IllegalArgumentException(Msg.getString("K0322", currencyCode));
+        }
+
+        this.defaultFractionDigits = ICU.getCurrencyFractionDigitsNative(currencyCode);
         if (defaultFractionDigits < 0) {
+            // In practice, I don't think this can fail because ICU doesn't care whether you give
+            // it a valid country code, and will just return a sensible default for the default
+            // locale's currency.
             throw new IllegalArgumentException(Msg.getString("K0322", currencyCode));
         }
         // END android-changed
@@ -111,7 +117,7 @@
             country = country + "_" + variant;
         }
 
-        String currencyCode = Resources.getCurrencyCodeNative(country);
+        String currencyCode = ICU.getCurrencyCodeNative(country);
         if (currencyCode == null) {
             throw new IllegalArgumentException(Msg.getString("K0323", locale.toString()));
         } else if (currencyCode.equals("None")) {
@@ -124,60 +130,45 @@
     }
 
     /**
-     * Returns this {@code Currency}'s ISO 4217 currency code.
-     *
-     * @return this {@code Currency}'s ISO 4217 currency code.
+     * Returns this currency's ISO 4217 currency code.
      */
     public String getCurrencyCode() {
         return currencyCode;
     }
 
     /**
-     * Returns the symbol for this currency in the default locale. For instance,
-     * if the default locale is the US, the symbol of the US dollar is "$". For
-     * other locales it may be "US$". If no symbol can be determined, the ISO
-     * 4217 currency code of the US dollar is returned.
-     *
-     * @return the symbol for this {@code Currency} in the default {@code Locale}.
+     * Returns the localized currency symbol for this currency in the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
     public String getSymbol() {
         return getSymbol(Locale.getDefault());
     }
 
     /**
-     * Returns the symbol for this currency in the given {@code Locale}.
+     * Returns the localized currency symbol for this currency in {@code locale}.
      * That is, given "USD" and Locale.US, you'd get "$", but given "USD" and a non-US locale,
      * you'd get "US$".
-     * <p>
-     * If the locale only specifies a language rather than a language and a countries (e.g.
-     * {@code Locale.JAPANESE, new Locale("en","")}), the the ISO
-     * 4217 currency code is returned.
-     * <p>
-     * If there is no currency symbol specific to this locale does not exist, the
-     * ISO 4217 currency code is returned.
-     * <p>
      *
-     * @param locale
-     *            the locale for which the currency symbol should be returned.
-     * @return the representation of this {@code Currency}'s symbol in the specified
-     *         locale.
+     * <p>If the locale only specifies a language rather than a language and a country (such as
+     * {@code Locale.JAPANESE} or {new Locale("en", "")} rather than {@code Locale.JAPAN} or
+     * {new Locale("en", "US")}), the ISO 4217 currency code is returned.
+     *
+     * <p>If there is no locale-specific currency symbol, the ISO 4217 currency code is returned.
      */
     public String getSymbol(Locale locale) {
-        // BEGIN android-changed
         if (locale.getCountry().length() == 0) {
             return currencyCode;
         }
 
         // Check the locale first, in case the locale has the same currency.
-        LocaleData localeData = Resources.getLocaleData(locale);
+        LocaleData localeData = LocaleData.get(locale);
         if (localeData.internationalCurrencySymbol.equals(currencyCode)) {
             return localeData.currencySymbol;
         }
 
         // Try ICU, and fall back to the currency code if ICU has nothing.
-        String symbol = Resources.getCurrencySymbolNative(locale.toString(), currencyCode);
+        String symbol = ICU.getCurrencySymbolNative(locale.toString(), currencyCode);
         return symbol != null ? symbol : currencyCode;
-        // END android-changed
     }
 
     /**
diff --git a/luni/src/main/java/java/util/Date.java b/luni/src/main/java/java/util/Date.java
index f69381a..90cd270 100644
--- a/luni/src/main/java/java/util/Date.java
+++ b/luni/src/main/java/java/util/Date.java
@@ -25,8 +25,6 @@
 import java.text.DateFormatSymbols;
 import java.text.SimpleDateFormat;
 
-import org.apache.harmony.luni.internal.nls.Messages;
-
 /**
  * {@code Date} represents a specific moment in time, to the millisecond.
  *
@@ -45,13 +43,6 @@
 
     private transient long milliseconds;
 
-    private static String[] dayOfWeekNames = { "Sun", "Mon", "Tue", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        "Wed", "Thu", "Fri", "Sat" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-
-    private static String[] monthNames = { "Jan", "Feb", "Mar", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-        "Apr", "May", "Jun", "Jul", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        "Aug", "Sep", "Oct", "Nov", "Dec"};  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-
     /**
      * Initializes this {@code Date} instance to the current time.
      */
@@ -377,10 +368,8 @@
      */
     @Deprecated
     public static long parse(String string) {
-
         if (string == null) {
-            // luni.06=The string argument is null
-            throw new IllegalArgumentException(Messages.getString("luni.06")); //$NON-NLS-1$
+            throw new IllegalArgumentException("The string argument is null");
         }
 
         char sign = 0;
@@ -415,7 +404,7 @@
                 nextState = LETTERS;
             } else if ('0' <= next && next <= '9') {
                 nextState = NUMBERS;
-            } else if (!Character.isSpace(next) && ",+-:/".indexOf(next) == -1) { //$NON-NLS-1$
+            } else if (!Character.isSpace(next) && ",+-:/".indexOf(next) == -1) {
                 throw new IllegalArgumentException();
             }
 
@@ -486,13 +475,13 @@
                 if (text.length() == 1) {
                     throw new IllegalArgumentException();
                 }
-                if (text.equals("AM")) { //$NON-NLS-1$
+                if (text.equals("AM")) {
                     if (hour == 12) {
                         hour = 0;
                     } else if (hour < 1 || hour > 12) {
                         throw new IllegalArgumentException();
                     }
-                } else if (text.equals("PM")) { //$NON-NLS-1$
+                } else if (text.equals("PM")) {
                     if (hour == 12) {
                         hour = 0;
                     } else if (hour < 1 || hour > 12) {
@@ -505,10 +494,8 @@
                             .getMonths();
                     int value;
                     if (parse(text, weekdays) != -1) {/* empty */
-                    } else if (month == -1
-                            && (month = parse(text, months)) != -1) {/* empty */
-                    } else if (text.equals("GMT") || text.equals("UT") //$NON-NLS-1$ //$NON-NLS-2$
-                            || text.equals("UTC")) { //$NON-NLS-1$
+                    } else if (month == -1 && (month = parse(text, months)) != -1) {/* empty */
+                    } else if (text.equals("GMT") || text.equals("UT") || text.equals("UTC")) {
                         zone = true;
                         zoneOffset = 0;
                     } else if ((value = zone(text)) != 0) {
@@ -676,10 +663,9 @@
     @Deprecated
     public String toGMTString() {
         // TODO: why does this insert the year manually instead of using one SimpleDateFormat?
-        SimpleDateFormat format1 = new SimpleDateFormat("d MMM ", Locale.US); //$NON-NLS-1$
-        SimpleDateFormat format2 = new SimpleDateFormat(
-                " HH:mm:ss 'GMT'", Locale.US); //$NON-NLS-1$
-        TimeZone gmtZone = TimeZone.getTimeZone("GMT"); //$NON-NLS-1$
+        SimpleDateFormat format1 = new SimpleDateFormat("d MMM ", Locale.US);
+        SimpleDateFormat format2 = new SimpleDateFormat(" HH:mm:ss 'GMT'", Locale.US);
+        TimeZone gmtZone = TimeZone.getTimeZone("GMT");
         format1.setTimeZone(gmtZone);
         format2.setTimeZone(gmtZone);
         GregorianCalendar gc = new GregorianCalendar(gmtZone);
@@ -719,18 +705,22 @@
         //   return new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").format(d);
         Calendar cal = new GregorianCalendar(milliseconds);
         TimeZone tz = cal.getTimeZone();
-        return dayOfWeekNames[cal.get(Calendar.DAY_OF_WEEK) - 1] + " " + monthNames[cal.get(Calendar.MONTH)]//$NON-NLS-1$
-                + " " + toTwoDigits(cal.get(Calendar.DAY_OF_MONTH)) + " " + toTwoDigits(cal.get(Calendar.HOUR_OF_DAY))//$NON-NLS-1$ //$NON-NLS-2$
-                + ":" + toTwoDigits(cal.get(Calendar.MINUTE)) + ":" + toTwoDigits(cal.get(Calendar.SECOND))//$NON-NLS-1$ //$NON-NLS-2$
-                + " " + tz.getDisplayName(tz.inDaylightTime(this), TimeZone.SHORT) + " " + cal.get(Calendar.YEAR);//$NON-NLS-1$ //$NON-NLS-2$
+        return dayOfWeekNames[cal.get(Calendar.DAY_OF_WEEK) - 1] + " " + monthNames[cal.get(Calendar.MONTH)]
+                + " " + toTwoDigits(cal.get(Calendar.DAY_OF_MONTH)) + " " + toTwoDigits(cal.get(Calendar.HOUR_OF_DAY))
+                + ":" + toTwoDigits(cal.get(Calendar.MINUTE)) + ":" + toTwoDigits(cal.get(Calendar.SECOND))
+                + " " + tz.getDisplayName(tz.inDaylightTime(this), TimeZone.SHORT) + " " + cal.get(Calendar.YEAR);
         // END android-changed
     }
+    private static final String[] dayOfWeekNames =
+            { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+    private static final String[] monthNames =
+            { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
 
     private String toTwoDigits(int n) {
         if (n >= 10) {
-            return Integer.toString(n);//$NON-NLS-1$
+            return Integer.toString(n);
         } else {
-            return "0" + n;//$NON-NLS-1$
+            return "0" + n;
         }
     }
 
@@ -760,34 +750,34 @@
     public static long UTC(int year, int month, int day, int hour, int minute,
             int second) {
         GregorianCalendar cal = new GregorianCalendar(false);
-        cal.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
+        cal.setTimeZone(TimeZone.getTimeZone("GMT"));
         cal.set(1900 + year, month, day, hour, minute, second);
         return cal.getTimeInMillis();
     }
 
     private static int zone(String text) {
-        if (text.equals("EST")) { //$NON-NLS-1$
+        if (text.equals("EST")) {
             return -5;
         }
-        if (text.equals("EDT")) { //$NON-NLS-1$
+        if (text.equals("EDT")) {
             return -4;
         }
-        if (text.equals("CST")) { //$NON-NLS-1$
+        if (text.equals("CST")) {
             return -6;
         }
-        if (text.equals("CDT")) { //$NON-NLS-1$
+        if (text.equals("CDT")) {
             return -5;
         }
-        if (text.equals("MST")) { //$NON-NLS-1$
+        if (text.equals("MST")) {
             return -7;
         }
-        if (text.equals("MDT")) { //$NON-NLS-1$
+        if (text.equals("MDT")) {
             return -6;
         }
-        if (text.equals("PST")) { //$NON-NLS-1$
+        if (text.equals("PST")) {
             return -8;
         }
-        if (text.equals("PDT")) { //$NON-NLS-1$
+        if (text.equals("PDT")) {
             return -7;
         }
         return 0;
diff --git a/luni/src/main/java/java/util/Deque.java b/luni/src/main/java/java/util/Deque.java
new file mode 100644
index 0000000..b13cdb0
--- /dev/null
+++ b/luni/src/main/java/java/util/Deque.java
@@ -0,0 +1,255 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * A kind of collection that can insert or remove element at both ends("double
+ * ended queue"). Mostly a deque has no limit of its size.
+ *
+ * Extending from Queue, a deque can be used as a Queue which behavior is
+ * first-in-first-out. Furthermore, a deque can also be used as a Stack(legacy
+ * class) which behavior is last-in-first-out.
+ *
+ * A typical deque does not allow null to be inserted as its element, while some
+ * implementations allow it. But null should not be inserted even in these
+ * implementations, since method poll return null to indicate that there is no
+ * element left in the deque.
+ *
+ * A deque can also remove interior elements by removeFirstOccurrence and
+ * removeLastOccurrence methods. A deque can not access elements by index.
+ *
+ * @param <E>
+ *            the type of elements in this collection
+ * @since 1.6
+ */
+public interface Deque<E> extends Queue<E> {
+
+    /**
+     * Inserts an element at the head of this deque if it dose not violate size
+     * limit immediately. It is better to use offerFirst(E) if a deque is
+     * size-limited.
+     *
+     * @param e
+     *            the element
+     * @throws IllegalStateException
+     *             if it can not add now due to size limit
+     * @throws ClassCastException
+     *             if the class of element can not be added into this deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     * @throws IllegalArgumentException
+     *             if the element can not be added due to some property.
+     */
+    void addFirst(E e);
+
+    /**
+     * Inserts an element at the tail of this deque if it dose not violate size
+     * limit immediately. It is better to use offerLast(E) if a deque is
+     * size-limited.
+     *
+     * @param e
+     *            the element
+     * @throws IllegalStateException
+     *             if it can not add now due to size limit
+     * @throws ClassCastException
+     *             if the class of element can not be added into this deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     * @throws IllegalArgumentException
+     *             if the element can not be added due to some property.
+     */
+    void addLast(E e);
+
+    /**
+     * Inserts an element at the head of this deque unless it would violate size
+     * limit. It is better than the addFirst(E) method in a size-limited deque,
+     * because the latter one may fail to add the element only by throwing an
+     * exception.
+     *
+     * @param e
+     *            the element
+     * @return true if the operation succeeds or false if it fails.
+     * @throws ClassCastException
+     *             if the class of element can not be added into this deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     * @throws IllegalArgumentException
+     *             if the element can not be added due to some property.
+     */
+    boolean offerFirst(E e);
+
+    /**
+     * Inserts an element at the tail of this deque unless it would violate size
+     * limit. It is better than the addLast(E) method in a size-limited deque,
+     * because the latter one may fail to add the element only by throwing an
+     * exception.
+     *
+     * @param e
+     *            the element
+     * @return true if the operation succeeds or false if it fails
+     * @throws ClassCastException
+     *             if the class of element can not be added into this deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     * @throws IllegalArgumentException
+     *             if the element can not be added due to some property
+     */
+    boolean offerLast(E e);
+
+    /**
+     * Gets and removes the head element of this deque. This method throws an
+     * exception if the deque is empty.
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     */
+    E removeFirst();
+
+    /**
+     * Gets and removes the tail element of this deque. This method throws an
+     * exception if the deque is empty.
+     *
+     * @return the tail element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     */
+    E removeLast();
+
+    /**
+     * Gets and removes the head element of this deque. This method returns null
+     * if the deque is empty.
+     *
+     * @return the head element or null if the deque is empty
+     */
+    E pollFirst();
+
+    /**
+     * Gets and removes the tail element of this deque. This method returns null
+     * if the deque is empty.
+     *
+     * @return the tail element or null if the deque is empty
+     */
+    E pollLast();
+
+    /**
+     * Gets but not removes the head element of this deque. This method throws
+     * an exception if the deque is empty.
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     */
+    E getFirst();
+
+    /**
+     * Gets but not removes the tail element of this deque. This method throws
+     * an exception if the deque is empty.
+     *
+     * @return the tail element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     */
+    E getLast();
+
+    /**
+     * Gets but not removes the head element of this deque. This method returns
+     * null if the deque is empty.
+     *
+     * @return the head element or null if the deque is empty
+     */
+    E peekFirst();
+
+    /**
+     * Gets but not removes the tail element of this deque. This method returns
+     * null if the deque is empty.
+     *
+     * @return the tail element or null if the deque is empty
+     */
+    E peekLast();
+
+    /**
+     * Removes the first equivalent element of the specified object. If the
+     * deque does not contain the element, it is unchanged and returns false.
+     *
+     * @param o
+     *            the element to be removed
+     * @return true if the operation succeeds or false if the deque does not
+     *         contain the element.
+     * @throws ClassCastException
+     *             if the class of the element is incompatible with the deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     */
+    boolean removeFirstOccurrence(Object o);
+
+    /**
+     * Removes the last equivalent element of the specified object. If the deque
+     * does not contain the element, it is unchanged and returns false.
+     *
+     * @param o
+     *            the element to be removed
+     * @return true if the operation succeeds or false if the deque does not
+     *         contain the element.
+     * @throws ClassCastException
+     *             if the class of the element is incompatible with the deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     */
+    boolean removeLastOccurrence(Object o);
+
+    /**
+     * Pushes the element to the deque(at the head of the deque), just same as
+     * addFirst(E).
+     *
+     * @param e
+     *            the element
+     * @throws IllegalStateException
+     *             if it can not add now due to size limit
+     * @throws ClassCastException
+     *             if the class of element can not be added into this deque
+     * @throws NullPointerException
+     *             if the element is null and the deque can not contain null
+     *             element
+     * @throws IllegalArgumentException
+     *             if the element can not be added due to some property.
+     */
+    void push(E e);
+
+    /**
+     * Pops the head element of the deque, just same as removeFirst().
+     *
+     * @return the head element
+     * @throws NoSuchElementException
+     *             if the deque is empty
+     */
+    E pop();
+
+    /**
+     * Returns the iterator in reverse order, from tail to head.
+     *
+     * @return the iterator in reverse order
+     */
+    Iterator<E> descendingIterator();
+}
\ No newline at end of file
diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java
index 744df1f..a27e7a1 100644
--- a/luni/src/main/java/java/util/Formatter.java
+++ b/luni/src/main/java/java/util/Formatter.java
@@ -15,6 +15,7 @@
  */
 package java.util;
 
+import com.ibm.icu4jni.util.LocaleData;
 import java.io.BufferedWriter;
 import java.io.Closeable;
 import java.io.File;
@@ -32,14 +33,9 @@
 import java.nio.charset.Charset;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.text.DateFormatSymbols;
 import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
 import java.text.NumberFormat;
-
-// BEGIN android-added
 import org.apache.harmony.luni.util.LocaleCache;
-// END android-added
 
 /**
  * Formats arguments according to a format string (like {@code printf} in C).
@@ -517,8 +513,13 @@
  * <td width="30%">{@code CEST}</td>
  * </tr>
  * </table>
- * <p>
- * Formatter is not thread-safe.
+ * <p><i>Number localization</i>. Some conversions use localized decimal digits rather than the
+ * usual ASCII digits. So formatting {@code 123} with {@code %d} will give 123 in English locales
+ * but &#x0661;&#x0662;&#x0663; in appropriate Arabic locales, for example. This number localization
+ * occurs for the decimal integer conversion {@code %d}, the floating point conversions {@code %e},
+ * {@code %f}, and {@code %g}, and all date/time {@code %t} or {@code %T} conversions, but no other
+ * conversions.
+ * <p><i>Thread safety</i>. Formatter is not thread-safe.
  *
  * @since 1.5
  * @see java.text.DateFormat
@@ -526,6 +527,10 @@
  * @see java.text.SimpleDateFormat
  */
 public final class Formatter implements Closeable, Flushable {
+    private static final char[] ZEROS = new char[] { '0', '0', '0', '0', '0', '0', '0', '0', '0' };
+
+    // The cached line separator.
+    private static String lineSeparator;
 
     /**
      * The enumeration giving the available styles for formatting very large
@@ -542,22 +547,25 @@
         DECIMAL_FLOAT
     }
 
+    // User-settable parameters.
     private Appendable out;
-
     private Locale locale;
 
+    // Implementation details.
+    private Object arg;
     private boolean closed = false;
-
+    private FormatToken formatToken;
     private IOException lastIOException;
+    private LocaleData localeData;
 
     /**
      * Constructs a {@code Formatter}.
      *
-     * The output is written to a {@code StringBuilder} which can be acquired by invoking
-     * {@link #out()} and whose content can be obtained by calling
-     * {@code toString()}.
+     * <p>The output is written to a {@code StringBuilder} which can be acquired by invoking
+     * {@link #out()} and whose content can be obtained by calling {@code toString}.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
     public Formatter() {
         this(new StringBuilder(), Locale.getDefault());
@@ -567,8 +575,9 @@
      * Constructs a {@code Formatter} whose output will be written to the
      * specified {@code Appendable}.
      *
-     * The locale for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param a
      *            the output destination of the {@code Formatter}. If {@code a} is {@code null},
      *            then a {@code StringBuilder} will be used.
@@ -580,9 +589,8 @@
     /**
      * Constructs a {@code Formatter} with the specified {@code Locale}.
      *
-     * The output is written to a {@code StringBuilder} which can be acquired by invoking
-     * {@link #out()} and whose content can be obtained by calling
-     * {@code toString()}.
+     * <p>The output is written to a {@code StringBuilder} which can be acquired by invoking
+     * {@link #out()} and whose content can be obtained by calling {@code toString}.
      *
      * @param l
      *            the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
@@ -605,7 +613,7 @@
      *            then no localization will be used.
      */
     public Formatter(Appendable a, Locale l) {
-        if (null == a) {
+        if (a == null) {
             out = new StringBuilder();
         } else {
             out = a;
@@ -616,10 +624,11 @@
     /**
      * Constructs a {@code Formatter} whose output is written to the specified file.
      *
-     * The charset of the {@code Formatter} is the default charset.
+     * <p>The charset of the {@code Formatter} is the default charset.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param fileName
      *            the filename of the file that is used as the output
      *            destination for the {@code Formatter}. The file will be truncated to
@@ -641,8 +650,9 @@
     /**
      * Constructs a {@code Formatter} whose output is written to the specified file.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param fileName
      *            the filename of the file that is used as the output
      *            destination for the {@code Formatter}. The file will be truncated to
@@ -700,8 +710,9 @@
      *
      * The charset of the {@code Formatter} is the default charset.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param file
      *            the {@code File} that is used as the output destination for the
      *            {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
@@ -723,8 +734,9 @@
      * Constructs a {@code Formatter} with the given charset,
      * and whose output is written to the specified {@code File}.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param file
      *            the {@code File} that is used as the output destination for the
      *            {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
@@ -776,10 +788,7 @@
         FileOutputStream fout = null;
         try {
             fout = new FileOutputStream(file);
-            OutputStreamWriter writer = new OutputStreamWriter(fout, csn);
-            // BEGIN android-changed
-            out = new BufferedWriter(writer, 8192);
-            // END android-changed
+            out = new BufferedWriter(new OutputStreamWriter(fout, csn));
         } catch (RuntimeException e) {
             closeOutputStream(fout);
             throw e;
@@ -794,19 +803,16 @@
     /**
      * Constructs a {@code Formatter} whose output is written to the specified {@code OutputStream}.
      *
-     * The charset of the {@code Formatter} is the default charset.
+     * <p>The charset of the {@code Formatter} is the default charset.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param os
      *            the stream to be used as the destination of the {@code Formatter}.
      */
     public Formatter(OutputStream os) {
-        OutputStreamWriter writer = new OutputStreamWriter(os, Charset
-                .defaultCharset());
-        // BEGIN android-changed
-        out = new BufferedWriter(writer, 8192);
-        // END android-changed
+        out = new BufferedWriter(new OutputStreamWriter(os, Charset.defaultCharset()));
         locale = Locale.getDefault();
     }
 
@@ -814,8 +820,9 @@
      * Constructs a {@code Formatter} with the given charset,
      * and whose output is written to the specified {@code OutputStream}.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param os
      *            the stream to be used as the destination of the {@code Formatter}.
      * @param csn
@@ -823,9 +830,7 @@
      * @throws UnsupportedEncodingException
      *             if the charset with the specified name is not supported.
      */
-    public Formatter(OutputStream os, String csn)
-            throws UnsupportedEncodingException {
-
+    public Formatter(OutputStream os, String csn) throws UnsupportedEncodingException {
         this(os, csn, Locale.getDefault());
     }
 
@@ -843,38 +848,33 @@
      * @throws UnsupportedEncodingException
      *             if the charset with the specified name is not supported.
      */
-    public Formatter(OutputStream os, String csn, Locale l)
-            throws UnsupportedEncodingException {
-
-        OutputStreamWriter writer = new OutputStreamWriter(os, csn);
-        // BEGIN android-changed
-        out = new BufferedWriter(writer, 8192);
-        // END android-changed
-
+    public Formatter(OutputStream os, String csn, Locale l) throws UnsupportedEncodingException {
+        out = new BufferedWriter(new OutputStreamWriter(os, csn));
         locale = l;
     }
 
     /**
      * Constructs a {@code Formatter} whose output is written to the specified {@code PrintStream}.
      *
-     * The charset of the {@code Formatter} is the default charset.
+     * <p>The charset of the {@code Formatter} is the default charset.
      *
-     * The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
-     *
+     * <p>The {@code Locale} used is the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param ps
      *            the {@code PrintStream} used as destination of the {@code Formatter}. If
      *            {@code ps} is {@code null}, then a {@code NullPointerException} will
      *            be raised.
      */
     public Formatter(PrintStream ps) {
-        if (null == ps) {
+        if (ps == null) {
             throw new NullPointerException();
         }
         out = ps;
         locale = Locale.getDefault();
     }
 
-    private void checkClosed() {
+    private void checkNotClosed() {
         if (closed) {
             throw new FormatterClosedException();
         }
@@ -888,7 +888,7 @@
      *             if the {@code Formatter} has been closed.
      */
     public Locale locale() {
-        checkClosed();
+        checkNotClosed();
         return locale;
     }
 
@@ -900,7 +900,7 @@
      *             if the {@code Formatter} has been closed.
      */
     public Appendable out() {
-        checkClosed();
+        checkNotClosed();
         return out;
     }
 
@@ -915,7 +915,7 @@
      */
     @Override
     public String toString() {
-        checkClosed();
+        checkNotClosed();
         return out.toString();
     }
 
@@ -927,7 +927,7 @@
      *             if the {@code Formatter} has been closed.
      */
     public void flush() {
-        checkClosed();
+        checkNotClosed();
         if (out instanceof Flushable) {
             try {
                 ((Flushable) out).flush();
@@ -990,20 +990,9 @@
      *             if the {@code Formatter} has been closed.
      */
     public Formatter format(String format, Object... args) {
-        // BEGIN android-changed
-        doFormat(format, args);
-        return this;
-        // END android-changed
+        return format(this.locale, format, args);
     }
 
-    // BEGIN android-added
-    /**
-     * Cached transformer. Improves performance when format() is called multiple
-     * times.
-     */
-    private Transformer transformer;
-    // END android-added
-
     /**
      * Writes a formatted string to the output destination of the {@code Formatter}.
      *
@@ -1028,29 +1017,21 @@
      *             if the {@code Formatter} has been closed.
      */
     public Formatter format(Locale l, String format, Object... args) {
-        // BEGIN android-changed
         Locale originalLocale = locale;
         try {
-            this.locale = l;
+            this.locale = (l == null ? Locale.US : l);
+            this.localeData = LocaleData.get(locale);
             doFormat(format, args);
         } finally {
             this.locale = originalLocale;
         }
         return this;
-        // END android-changed
     }
 
-    // BEGIN android-changed
     private void doFormat(String format, Object... args) {
-        checkClosed();
-
-        // Reuse the previous transformer if the locale matches.
-        if (transformer == null || !transformer.locale.equals(locale)) {
-            transformer = new Transformer(this, locale);
-        }
+        checkNotClosed();
 
         FormatSpecifierParser fsp = new FormatSpecifierParser(format);
-
         int currentObjectIndex = 0;
         Object lastArgument = null;
         boolean hasLastArgumentSet = false;
@@ -1079,7 +1060,7 @@
                     hasLastArgumentSet = true;
                 }
 
-                CharSequence substitution = transformer.transform(token, argument);
+                CharSequence substitution = transform(token, argument);
                 // The substitution is null if we called Formattable.formatTo.
                 if (substitution != null) {
                     outputCharSequence(substitution, 0, substitution.length());
@@ -1088,9 +1069,7 @@
             }
         }
     }
-    // END android-changed
 
-    // BEGIN android-added
     // Fixes http://code.google.com/p/android/issues/detail?id=1767.
     private void outputCharSequence(CharSequence cs, int start, int end) {
         try {
@@ -1099,15 +1078,14 @@
             lastIOException = e;
         }
     }
-    // END android-added
 
     private Object getArgument(Object[] args, int index, FormatSpecifierParser fsp,
             Object lastArgument, boolean hasLastArgumentSet) {
         if (index == FormatToken.LAST_ARGUMENT_INDEX && !hasLastArgumentSet) {
-            throw new MissingFormatArgumentException("<"); //$NON-NLS-1$
+            throw new MissingFormatArgumentException("<");
         }
 
-        if (null == args) {
+        if (args == null) {
             return null;
         }
 
@@ -1123,12 +1101,11 @@
     }
 
     private static void closeOutputStream(OutputStream os) {
-        if (null == os) {
+        if (os == null) {
             return;
         }
         try {
             os.close();
-
         } catch (IOException e) {
             // silently
         }
@@ -1171,28 +1148,14 @@
 
         // Tests whether there were no flags, no width, and no precision specified.
         boolean isDefault() {
-            // TODO: call hasDefaultFlags when the JIT can inline it.
             return !flagAdd && !flagComma && !flagMinus && !flagParenthesis && !flagSharp &&
                     !flagSpace && !flagZero && width == UNSET && precision == UNSET;
         }
 
-        boolean hasDefaultFlags() {
-            return !flagAdd && !flagComma && !flagMinus && !flagParenthesis && !flagSharp &&
-                    !flagSpace && !flagZero;
-        }
-
         boolean isPrecisionSet() {
             return precision != UNSET;
         }
 
-        boolean isWidthSet() {
-            return width != UNSET;
-        }
-
-        boolean hasArg() {
-            return argIndex != UNSET;
-        }
-
         int getArgIndex() {
             return argIndex;
         }
@@ -1289,1169 +1252,705 @@
             return conversionType != '%' && conversionType != 'n';
         }
 
-        void checkMissingWidth() {
-            if (flagMinus && width == UNSET) {
+        void checkFlags(Object arg) {
+            // Work out which flags are allowed.
+            boolean allowAdd = false;
+            boolean allowComma = false;
+            boolean allowMinus = true;
+            boolean allowParenthesis = false;
+            boolean allowSharp = false;
+            boolean allowSpace = false;
+            boolean allowZero = false;
+            // Precision and width?
+            boolean allowPrecision = true;
+            boolean allowWidth = true;
+            // Argument?
+            boolean allowArgument = true;
+            switch (conversionType) {
+            // Character and date/time.
+            case 'c': case 'C': case 't': case 'T':
+                // Only '-' is allowed.
+                allowPrecision = false;
+                break;
+
+            // String.
+            case 's': case 'S':
+                if (arg instanceof Formattable) {
+                    allowSharp = true;
+                }
+                break;
+
+            // Floating point.
+            case 'g': case 'G':
+                allowAdd = allowComma = allowParenthesis = allowSpace = allowZero = true;
+                break;
+            case 'f':
+                allowAdd = allowComma = allowParenthesis = allowSharp = allowSpace = allowZero = true;
+                break;
+            case 'e': case 'E':
+                allowAdd = allowParenthesis = allowSharp = allowSpace = allowZero = true;
+                break;
+            case 'a': case 'A':
+                allowAdd = allowSharp = allowSpace = allowZero = true;
+                break;
+
+            // Integral.
+            case 'd':
+                allowAdd = allowComma = allowParenthesis = allowSpace = allowZero = true;
+                allowPrecision = false;
+                break;
+            case 'o': case 'x': case 'X':
+                allowSharp = allowZero = true;
+                if (arg == null || arg instanceof BigInteger) {
+                    allowAdd = allowParenthesis = allowSpace = true;
+                }
+                allowPrecision = false;
+                break;
+
+            // Special.
+            case 'n':
+                // Nothing is allowed.
+                allowMinus = false;
+                allowArgument = allowPrecision = allowWidth = false;
+                break;
+            case '%':
+                // The only flag allowed is '-', and no argument or precision is allowed.
+                allowArgument = false;
+                allowPrecision = false;
+                break;
+
+            // Booleans and hash codes.
+            case 'b': case 'B': case 'h': case 'H':
+                break;
+
+            default:
+                throw unknownFormatConversionException();
+            }
+            
+            // Check for disallowed flags.
+            String mismatch = null;
+            if (!allowAdd && flagAdd) {
+                mismatch = "+";
+            } else if (!allowComma && flagComma) {
+                mismatch = ",";
+            } else if (!allowMinus && flagMinus) {
+                mismatch = "-";
+            } else if (!allowParenthesis && flagParenthesis) {
+                mismatch = "(";
+            } else if (!allowSharp && flagSharp) {
+                mismatch = "#";
+            } else if (!allowSpace && flagSpace) {
+                mismatch = " ";
+            } else if (!allowZero && flagZero) {
+                mismatch = "0";
+            }
+            if (mismatch != null) {
+                if (conversionType == 'n') {
+                    // For no good reason, %n is a special case...
+                    throw new IllegalFormatFlagsException(mismatch);
+                } else {
+                    throw new FormatFlagsConversionMismatchException(mismatch, conversionType);
+                }
+            }
+            
+            // Check for a missing width with flags that require a width.
+            if ((flagMinus || flagZero) && width == UNSET) {
                 throw new MissingFormatWidthException("-" + conversionType);
             }
-        }
-
-        void ensureOnlyMinus() {
-            if (flagAdd || flagComma || flagParenthesis || flagSharp || flagSpace || flagZero) {
-                throw new FormatFlagsConversionMismatchException(getStrFlags(), conversionType);
+            
+            // Check that no-argument conversion types don't have an argument.
+            // Note: the RI doesn't enforce this.
+            if (!allowArgument && argIndex != UNSET) {
+                throw new IllegalFormatFlagsException(getStrFlags());
             }
-        }
-
-        void ensureNoPrecision() {
-            if (isPrecisionSet()) {
+            
+            // Check that we don't have a precision or width where they're not allowed.
+            if (!allowPrecision && precision != UNSET) {
                 throw new IllegalFormatPrecisionException(precision);
             }
+            if (!allowWidth && width != UNSET) {
+                throw new IllegalFormatWidthException(width);
+            }
+            
+            // Some combinations make no sense...
+            if (flagAdd && flagSpace) {
+                throw new IllegalFormatFlagsException("the '+' and ' ' flags are incompatible");
+            }
+            if (flagMinus && flagZero) {
+                throw new IllegalFormatFlagsException("the '-' and '0' flags are incompatible");
+            }
         }
+
+        public UnknownFormatConversionException unknownFormatConversionException() {
+            if (conversionType == 't' || conversionType == 'T') {
+                throw new UnknownFormatConversionException(String.format("%c%c",
+                        conversionType, dateSuffix));
+            }
+            throw new UnknownFormatConversionException(String.valueOf(conversionType));
+        }
+    }
+
+    private NumberFormat getNumberFormat() {
+        return LocaleCache.getNumberFormat(locale);
     }
 
     /*
-     * Transforms the argument to the formatted string according to the format
-     * information contained in the format token.
+     * Gets the formatted string according to the format token and the
+     * argument.
      */
-    private static class Transformer {
-        private Formatter formatter;
-        private FormatToken formatToken;
-        private Object arg;
-        private Locale locale;
-        private DecimalFormatSymbols decimalFormatSymbols;
-        private static String lineSeparator;
+    private CharSequence transform(FormatToken token, Object argument) {
+        this.formatToken = token;
+        this.arg = argument;
 
-        // BEGIN android-changed
-        // This object is mutated during use, so can't be cached safely.
-        // private NumberFormat numberFormat;
-        // END android-changed
-
-        private DateTimeUtil dateTimeUtil;
-
-        Transformer(Formatter formatter, Locale locale) {
-            this.formatter = formatter;
-            this.locale = (null == locale ? Locale.US : locale);
-        }
-
-        private NumberFormat getNumberFormat() {
-            // BEGIN android-changed
-            return LocaleCache.getNumberFormat(locale);
-            // END android-changed
-        }
-
-        // BEGIN android-changed
-        DecimalFormatSymbols getDecimalFormatSymbols() {
-            if (decimalFormatSymbols == null) {
-                decimalFormatSymbols = new DecimalFormatSymbols(locale);
-            }
-            return decimalFormatSymbols;
-        }
-        // END android-changed
-
-        /*
-         * Gets the formatted string according to the format token and the
-         * argument.
-         */
-        CharSequence transform(FormatToken token, Object argument) {
-            this.formatToken = token;
-            this.arg = argument;
-
-            // There are only two format specifiers that matter: "%d" and "%s".
-            // Nothing else is common in the wild. We fast-path these two to
-            // avoid the heavyweight machinery needed to cope with flags, width,
-            // and precision.
-            if (token.isDefault()) {
-                switch (token.getConversionType()) {
-                case 's':
-                    if (arg == null) {
-                        return "null";
-                    } else if (!(arg instanceof Formattable)) {
-                        return arg.toString();
-                    }
-                    break;
-                case 'd':
-                    if (arg instanceof Integer || arg instanceof Long || arg instanceof Short || arg instanceof Byte) {
-                        // TODO: when we fix the rest of formatter to correctly use locale-specific
-                        // digits when getDecimalFormatSymbols().getZeroDigit() != '0', we'll need
-                        // to add a special case here too.
-                        return arg.toString();
-                    }
-                }
-            }
-
-            CharSequence result;
+        // There are only two format specifiers that matter: "%d" and "%s".
+        // Nothing else is common in the wild. We fast-path these two to
+        // avoid the heavyweight machinery needed to cope with flags, width,
+        // and precision.
+        if (token.isDefault()) {
             switch (token.getConversionType()) {
-                case 'B':
-                case 'b': {
-                    result = transformFromBoolean();
-                    break;
+            case 's':
+                if (arg == null) {
+                    return "null";
+                } else if (!(arg instanceof Formattable)) {
+                    return arg.toString();
                 }
-                case 'H':
-                case 'h': {
-                    result = transformFromHashCode();
-                    break;
-                }
-                case 'S':
-                case 's': {
-                    result = transformFromString();
-                    break;
-                }
-                case 'C':
-                case 'c': {
-                    result = transformFromCharacter();
-                    break;
-                }
-                case 'd':
-                case 'o':
-                case 'x':
-                case 'X': {
-                    if (null == arg || arg instanceof BigInteger) {
-                        result = transformFromBigInteger();
-                    } else {
-                        result = transformFromInteger();
-                    }
-                    break;
-                }
-                case 'e':
-                case 'E':
-                case 'g':
-                case 'G':
-                case 'f':
-                case 'a':
-                case 'A': {
-                    result = transformFromFloat();
-                    break;
-                }
-                case '%': {
-                    result = transformFromPercent();
-                    break;
-                }
-                case 'n': {
-                    result = transformFromLineSeparator();
-                    break;
-                }
-                case 't':
-                case 'T': {
-                    result = transformFromDateTime();
-                    break;
-                }
-                default: {
-                    throw new UnknownFormatConversionException(String
-                            .valueOf(token.getConversionType()));
+                break;
+            case 'd':
+                if (arg instanceof Integer || arg instanceof Long || arg instanceof Short || arg instanceof Byte) {
+                    String result = arg.toString();
+                    return (localeData.zeroDigit == '0') ? result : localizeDigits(result);
                 }
             }
-
-            if (Character.isUpperCase(token.getConversionType())) {
-                if (result != null) {
-                    result = result.toString().toUpperCase(locale);
-                }
-            }
-            return result;
         }
 
-        private IllegalFormatConversionException badArgumentType() {
-            throw new IllegalFormatConversionException(formatToken.getConversionType(),
-                    arg.getClass());
-        }
-
-        /*
-         * Transforms the Boolean argument to a formatted string.
-         */
-        private CharSequence transformFromBoolean() {
-            formatToken.checkMissingWidth();
-            formatToken.ensureOnlyMinus();
-            CharSequence result;
-            if (arg instanceof Boolean) {
-                result = arg.toString();
-            } else if (arg == null) {
-                result = "false"; //$NON-NLS-1$
+        formatToken.checkFlags(arg);
+        CharSequence result;
+        switch (token.getConversionType()) {
+        case 'B': case 'b':
+            result = transformFromBoolean();
+            break;
+        case 'H': case 'h':
+            result = transformFromHashCode();
+            break;
+        case 'S': case 's':
+            result = transformFromString();
+            break;
+        case 'C': case 'c':
+            result = transformFromCharacter();
+            break;
+        case 'd': case 'o': case 'x': case 'X':
+            if (arg == null || arg instanceof BigInteger) {
+                result = transformFromBigInteger();
             } else {
-                result = "true"; //$NON-NLS-1$
+                result = transformFromInteger();
             }
-            return padding(result, 0);
+            break;
+        case 'A': case 'a': case 'E': case 'e': case 'f': case 'G': case 'g':
+            result = transformFromFloat();
+            break;
+        case '%':
+            result = transformFromPercent();
+            break;
+        case 'n':
+            result = transformFromLineSeparator();
+            break;
+        case 't': case 'T':
+            result = transformFromDateTime();
+            break;
+        default:
+            throw token.unknownFormatConversionException();
         }
 
-        /*
-         * Transforms the hash code of the argument to a formatted string.
-         */
-        private CharSequence transformFromHashCode() {
-            formatToken.checkMissingWidth();
-            formatToken.ensureOnlyMinus();
-            CharSequence result;
-            if (arg == null) {
-                result = "null"; //$NON-NLS-1$
-            } else {
-                result = Integer.toHexString(arg.hashCode());
-            }
-            return padding(result, 0);
-        }
-
-        /*
-         * Transforms the String to a formatted string.
-         */
-        private CharSequence transformFromString() {
-            formatToken.checkMissingWidth();
-            if (arg instanceof Formattable) {
-                // only minus and sharp flag is valid
-                if (formatToken.flagAdd || formatToken.flagComma || formatToken.flagParenthesis || formatToken.flagSpace || formatToken.flagZero) {
-                    throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-                }
-                int flag = 0;
-                if (formatToken.flagMinus) {
-                    flag |= FormattableFlags.LEFT_JUSTIFY;
-                }
-                if (formatToken.flagSharp) {
-                    flag |= FormattableFlags.ALTERNATE;
-                }
-                if (Character.isUpperCase(formatToken.getConversionType())) {
-                    flag |= FormattableFlags.UPPERCASE;
-                }
-                ((Formattable) arg).formatTo(formatter, flag, formatToken.getWidth(),
-                        formatToken.getPrecision());
-                // all actions have been taken out in the
-                // Formattable.formatTo, thus there is nothing to do, just
-                // returns null, which tells the Parser to add nothing to the
-                // output.
-                return null;
-            }
-            // only '-' is valid for flags if the argument is not an instance of Formattable
-            formatToken.ensureOnlyMinus();
-            CharSequence result = arg != null ? arg.toString() : "null";
-            return padding(result, 0);
-        }
-
-        /*
-         * Transforms the Character to a formatted string.
-         */
-        private CharSequence transformFromCharacter() {
-            formatToken.checkMissingWidth();
-            formatToken.ensureOnlyMinus();
-            formatToken.ensureNoPrecision();
-
-            if (arg == null) {
-                return padding("null", 0);
-            }
-            if (arg instanceof Character) {
-                return padding(String.valueOf(arg), 0);
-            } else if (arg instanceof Byte || arg instanceof Short || arg instanceof Integer) {
-                int codePoint = ((Number) arg).intValue();
-                if (!Character.isValidCodePoint(codePoint)) {
-                    throw new IllegalFormatCodePointException(codePoint);
-                }
-                CharSequence result = (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT)
-                        ? String.valueOf((char) codePoint)
-                        : String.valueOf(Character.toChars(codePoint));
-                return padding(result, 0);
-            } else {
-                throw badArgumentType();
+        if (Character.isUpperCase(token.getConversionType())) {
+            if (result != null) {
+                result = result.toString().toUpperCase(locale);
             }
         }
+        return result;
+    }
 
-        /*
-         * Transforms percent to a formatted string. Only '-' is legal flag.
-         * Precision and arguments are illegal.
-         */
-        private CharSequence transformFromPercent() {
-            formatToken.checkMissingWidth();
-            formatToken.ensureOnlyMinus();
-            formatToken.ensureNoPrecision();
-            if (formatToken.hasArg()) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+    private IllegalFormatConversionException badArgumentType() {
+        throw new IllegalFormatConversionException(formatToken.getConversionType(), arg.getClass());
+    }
+
+    /**
+     * Returns a CharSequence corresponding to {@code s} with all the ASCII digits replaced
+     * by digits appropriate to this formatter's locale. Other characters remain unchanged.
+     */
+    private CharSequence localizeDigits(String s) {
+        int length = s.length();
+        int offsetToLocalizedDigits = localeData.zeroDigit - '0';
+        StringBuilder result = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            char ch = s.charAt(i);
+            if (ch >= '0' && ch <= '9') {
+                ch += offsetToLocalizedDigits;
             }
-            return padding("%", 0);
+            result.append(ch);
         }
+        return result;
+    }
 
-        /*
-         * Transforms line separator to a formatted string. Any flag, width,
-         * precision or argument is illegal.
-         */
-        private CharSequence transformFromLineSeparator() {
-            formatToken.ensureNoPrecision();
-
-            if (formatToken.isWidthSet()) {
-                throw new IllegalFormatWidthException(formatToken.getWidth());
-            }
-
-            if (!formatToken.hasDefaultFlags() || formatToken.hasArg()) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-            }
-
-            if (lineSeparator == null) {
-                lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
-                    public String run() {
-                        return System.getProperty("line.separator"); //$NON-NLS-1$
-                    }
-                });
-            }
-            return lineSeparator;
+    private CharSequence transformFromBoolean() {
+        CharSequence result;
+        if (arg instanceof Boolean) {
+            result = arg.toString();
+        } else if (arg == null) {
+            result = "false";
+        } else {
+            result = "true";
         }
+        return padding(result, 0);
+    }
 
-        /*
-         * Pads characters to the formatted string.
-         */
-        private CharSequence padding(CharSequence source, int startIndex) {
-            boolean sourceIsStringBuilder = (source instanceof StringBuilder);
-
-            int start = startIndex;
-            int width = formatToken.getWidth();
-            int precision = formatToken.getPrecision();
-
-            int length = source.length();
-            if (precision >= 0) {
-                length = Math.min(length, precision);
-                if (sourceIsStringBuilder) {
-                    ((StringBuilder) source).setLength(length);
-                } else {
-                    source = source.subSequence(0, length);
-                }
-            }
-            if (width > 0) {
-                width = Math.max(source.length(), width);
-            }
-            if (length >= width) {
-                return source;
-            }
-
-            char paddingChar = '\u0020'; // space as padding char.
-            if (formatToken.flagZero) {
-                if (formatToken.getConversionType() == 'd') {
-                    paddingChar = getDecimalFormatSymbols().getZeroDigit();
-                } else {
-                    paddingChar = '0';
-                }
-            } else {
-                // if padding char is space, always pad from the start.
-                start = 0;
-            }
-            char[] paddingChars = new char[width - length];
-            Arrays.fill(paddingChars, paddingChar);
-
-            boolean paddingRight = formatToken.flagMinus;
-            StringBuilder result = toStringBuilder(source);
-            if (paddingRight) {
-                result.append(paddingChars);
-            } else {
-                result.insert(start, paddingChars);
-            }
-            return result;
+    private CharSequence transformFromHashCode() {
+        CharSequence result;
+        if (arg == null) {
+            result = "null";
+        } else {
+            result = Integer.toHexString(arg.hashCode());
         }
+        return padding(result, 0);
+    }
 
-        private StringBuilder toStringBuilder(CharSequence cs) {
-            return cs instanceof StringBuilder ? (StringBuilder) cs : new StringBuilder(cs);
-        }
-
-        private StringBuilder wrapParentheses(StringBuilder result) {
-            result.setCharAt(0, '('); // Replace the '-'.
-            if (formatToken.flagZero) {
-                formatToken.setWidth(formatToken.getWidth() - 1);
-                result = (StringBuilder) padding(result, 1);
-                result.append(')');
-            } else {
-                result.append(')');
-                result = (StringBuilder) padding(result, 0);
+    private CharSequence transformFromString() {
+        if (arg instanceof Formattable) {
+            int flags = 0;
+            if (formatToken.flagMinus) {
+                flags |= FormattableFlags.LEFT_JUSTIFY;
             }
-            return result;
-        }
-
-        /*
-         * Transforms the Integer to a formatted string.
-         */
-        private CharSequence transformFromInteger() {
-            int startIndex = 0;
-            StringBuilder result = new StringBuilder();
-            char currentConversionType = formatToken.getConversionType();
-
-            if (formatToken.flagMinus || formatToken.flagZero) {
-                if (!formatToken.isWidthSet()) {
-                    throw new MissingFormatWidthException(formatToken.getStrFlags());
-                }
-            }
-            // Combination of '+' and ' ' is illegal.
-            if (formatToken.flagAdd && formatToken.flagSpace) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-            }
-            formatToken.ensureNoPrecision();
-            long value;
-            if (arg instanceof Long) {
-                value = ((Long) arg).longValue();
-            } else if (arg instanceof Integer) {
-                value = ((Integer) arg).longValue();
-            } else if (arg instanceof Short) {
-                value = ((Short) arg).longValue();
-            } else if (arg instanceof Byte) {
-                value = ((Byte) arg).longValue();
-            } else {
-                throw badArgumentType();
-            }
-            if ('d' != currentConversionType) {
-                if (formatToken.flagAdd || formatToken.flagSpace || formatToken.flagComma ||
-                        formatToken.flagParenthesis) {
-                    throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                            formatToken.getConversionType());
-                }
-            }
-
             if (formatToken.flagSharp) {
-                if ('d' == currentConversionType) {
-                    throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                            formatToken.getConversionType());
-                } else if ('o' == currentConversionType) {
-                    result.append("0"); //$NON-NLS-1$
-                    startIndex += 1;
-                } else {
-                    result.append("0x"); //$NON-NLS-1$
-                    startIndex += 2;
-                }
+                flags |= FormattableFlags.ALTERNATE;
             }
-
-            if (formatToken.flagMinus && formatToken.flagZero) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
+            if (Character.isUpperCase(formatToken.getConversionType())) {
+                flags |= FormattableFlags.UPPERCASE;
             }
+            ((Formattable) arg).formatTo(this, flags, formatToken.getWidth(),
+                    formatToken.getPrecision());
+            // all actions have been taken out in the
+            // Formattable.formatTo, thus there is nothing to do, just
+            // returns null, which tells the Parser to add nothing to the
+            // output.
+            return null;
+        }
+        CharSequence result = arg != null ? arg.toString() : "null";
+        return padding(result, 0);
+    }
 
-            if ('d' == currentConversionType) {
-                if (formatToken.flagComma) {
-                    NumberFormat numberFormat = getNumberFormat();
-                    numberFormat.setGroupingUsed(true);
-                    result.append(numberFormat.format(arg));
-                } else {
-                    result.append(value);
-                }
+    private CharSequence transformFromCharacter() {
+        if (arg == null) {
+            return padding("null", 0);
+        }
+        if (arg instanceof Character) {
+            return padding(String.valueOf(arg), 0);
+        } else if (arg instanceof Byte || arg instanceof Short || arg instanceof Integer) {
+            int codePoint = ((Number) arg).intValue();
+            if (!Character.isValidCodePoint(codePoint)) {
+                throw new IllegalFormatCodePointException(codePoint);
+            }
+            CharSequence result = (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT)
+                    ? String.valueOf((char) codePoint)
+                    : String.valueOf(Character.toChars(codePoint));
+            return padding(result, 0);
+        } else {
+            throw badArgumentType();
+        }
+    }
 
-                if (value < 0) {
-                    if (formatToken.flagParenthesis) {
-                        return wrapParentheses(result);
-                    } else if (formatToken.flagZero) {
-                        startIndex++;
-                    }
-                } else {
-                    if (formatToken.flagAdd) {
-                        result.insert(0, '+');
-                        startIndex += 1;
-                    } else if (formatToken.flagSpace) {
-                        result.insert(0, ' ');
-                        startIndex += 1;
-                    }
+    private CharSequence transformFromPercent() {
+        return padding("%", 0);
+    }
+
+    private CharSequence transformFromLineSeparator() {
+        if (lineSeparator == null) {
+            lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty("line.separator");
                 }
+            });
+        }
+        return lineSeparator;
+    }
+
+    private CharSequence padding(CharSequence source, int startIndex) {
+        int start = startIndex;
+        int width = formatToken.getWidth();
+        int precision = formatToken.getPrecision();
+
+        int length = source.length();
+        if (precision >= 0) {
+            length = Math.min(length, precision);
+            if (source instanceof StringBuilder) {
+                ((StringBuilder) source).setLength(length);
             } else {
-                // Undo sign-extension, since we'll be using Long.to(Octal|Hex)String.
-                if (arg instanceof Byte) {
-                    value &= 0xffL;
-                } else if (arg instanceof Short) {
-                    value &= 0xffffL;
-                } else if (arg instanceof Integer) {
-                    value &= 0xffffffffL;
-                }
-                if ('o' == currentConversionType) {
-                    result.append(Long.toOctalString(value));
-                } else {
-                    result.append(Long.toHexString(value));
-                }
+                source = source.subSequence(0, length);
             }
-
-            return padding(result, startIndex);
+        }
+        if (width > 0) {
+            width = Math.max(source.length(), width);
+        }
+        if (length >= width) {
+            return source;
         }
 
-        private CharSequence transformFromSpecialNumber() {
-            if (!(arg instanceof Number) || arg instanceof BigDecimal) {
-                return null;
-            }
-
-            Number number = (Number) arg;
-            double d = number.doubleValue();
-            String source = null;
-            if (Double.isNaN(d)) {
-                source = "NaN"; //$NON-NLS-1$
-            } else if (d == Double.POSITIVE_INFINITY) {
-                if (formatToken.flagAdd) {
-                    source = "+Infinity"; //$NON-NLS-1$
-                } else if (formatToken.flagSpace) {
-                    source = " Infinity"; //$NON-NLS-1$
-                } else {
-                    source = "Infinity"; //$NON-NLS-1$
-                }
-            } else if (d == Double.NEGATIVE_INFINITY) {
-                if (formatToken.flagParenthesis) {
-                    source = "(Infinity)"; //$NON-NLS-1$
-                } else {
-                    source = "-Infinity"; //$NON-NLS-1$
-                }
+        char paddingChar = '\u0020'; // space as padding char.
+        if (formatToken.flagZero) {
+            if (formatToken.getConversionType() == 'd') {
+                paddingChar = localeData.zeroDigit;
             } else {
-                return null;
+                paddingChar = '0'; // No localized digits for bases other than decimal.
             }
+        } else {
+            // if padding char is space, always pad from the start.
+            start = 0;
+        }
+        char[] paddingChars = new char[width - length];
+        Arrays.fill(paddingChars, paddingChar);
 
-            formatToken.setPrecision(FormatToken.UNSET);
-            formatToken.flagZero = false;
-            return padding(source, 0);
+        boolean paddingRight = formatToken.flagMinus;
+        StringBuilder result = toStringBuilder(source);
+        if (paddingRight) {
+            result.append(paddingChars);
+        } else {
+            result.insert(start, paddingChars);
+        }
+        return result;
+    }
+
+    private StringBuilder toStringBuilder(CharSequence cs) {
+        return cs instanceof StringBuilder ? (StringBuilder) cs : new StringBuilder(cs);
+    }
+
+    private StringBuilder wrapParentheses(StringBuilder result) {
+        result.setCharAt(0, '('); // Replace the '-'.
+        if (formatToken.flagZero) {
+            formatToken.setWidth(formatToken.getWidth() - 1);
+            result = (StringBuilder) padding(result, 1);
+            result.append(')');
+        } else {
+            result.append(')');
+            result = (StringBuilder) padding(result, 0);
+        }
+        return result;
+    }
+
+    private CharSequence transformFromInteger() {
+        int startIndex = 0;
+        StringBuilder result = new StringBuilder();
+        char currentConversionType = formatToken.getConversionType();
+
+        long value;
+        if (arg instanceof Long) {
+            value = ((Long) arg).longValue();
+        } else if (arg instanceof Integer) {
+            value = ((Integer) arg).longValue();
+        } else if (arg instanceof Short) {
+            value = ((Short) arg).longValue();
+        } else if (arg instanceof Byte) {
+            value = ((Byte) arg).longValue();
+        } else {
+            throw badArgumentType();
         }
 
-        private CharSequence transformFromNull() {
-            formatToken.flagZero = false;
-            return padding("null", 0); //$NON-NLS-1$
+        if (formatToken.flagSharp) {
+            if (currentConversionType == 'o') {
+                result.append("0");
+                startIndex += 1;
+            } else {
+                result.append("0x");
+                startIndex += 2;
+            }
         }
 
-        /*
-         * Transforms a BigInteger to a formatted string.
-         */
-        private CharSequence transformFromBigInteger() {
-            int startIndex = 0;
-            boolean isNegative = false;
-            StringBuilder result = new StringBuilder();
-            BigInteger bigInt = (BigInteger) arg;
-            char currentConversionType = formatToken.getConversionType();
-
-            if (formatToken.flagMinus || formatToken.flagZero) {
-                if (!formatToken.isWidthSet()) {
-                    throw new MissingFormatWidthException(formatToken.getStrFlags());
-                }
-            }
-
-            // Combination of '+' & ' ' is illegal.
-            if (formatToken.flagAdd && formatToken.flagSpace) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-            }
-
-            // Combination of '-' & '0' is illegal.
-            if (formatToken.flagZero && formatToken.flagMinus) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-            }
-
-            formatToken.ensureNoPrecision();
-
-            if ('d' != currentConversionType && formatToken.flagComma) {
-                throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                        currentConversionType);
-            }
-
-            if (formatToken.flagSharp && 'd' == currentConversionType) {
-                throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                        currentConversionType);
-            }
-
-            if (bigInt == null) {
-                return transformFromNull();
-            }
-
-            isNegative = (bigInt.compareTo(BigInteger.ZERO) < 0);
-
-            if ('d' == currentConversionType) {
+        if ('d' == currentConversionType) {
+            if (formatToken.flagComma) {
                 NumberFormat numberFormat = getNumberFormat();
-                numberFormat.setGroupingUsed(formatToken.flagComma);
-                result.append(numberFormat.format(bigInt));
-            } else if ('o' == currentConversionType) {
-                // convert BigInteger to a string presentation using radix 8
-                result.append(bigInt.toString(8));
+                numberFormat.setGroupingUsed(true);
+                result.append(numberFormat.format(arg));
+            } else if (localeData.zeroDigit != '0') {
+                result.append(localizeDigits(Long.toString(value)));
             } else {
-                // convert BigInteger to a string presentation using radix 16
-                result.append(bigInt.toString(16));
-            }
-            if (formatToken.flagSharp) {
-                startIndex = isNegative ? 1 : 0;
-                if ('o' == currentConversionType) {
-                    result.insert(startIndex, "0"); //$NON-NLS-1$
-                    startIndex += 1;
-                } else if ('x' == currentConversionType
-                        || 'X' == currentConversionType) {
-                    result.insert(startIndex, "0x"); //$NON-NLS-1$
-                    startIndex += 2;
-                }
+                result.append(value);
             }
 
-            if (!isNegative) {
+            if (value < 0) {
+                if (formatToken.flagParenthesis) {
+                    return wrapParentheses(result);
+                } else if (formatToken.flagZero) {
+                    startIndex++;
+                }
+            } else {
                 if (formatToken.flagAdd) {
                     result.insert(0, '+');
                     startIndex += 1;
-                }
-                if (formatToken.flagSpace) {
+                } else if (formatToken.flagSpace) {
                     result.insert(0, ' ');
                     startIndex += 1;
                 }
             }
-
-            /* pad paddingChar to the output */
-            if (isNegative && formatToken.flagParenthesis) {
-                return wrapParentheses(result);
+        } else {
+            // Undo sign-extension, since we'll be using Long.to(Octal|Hex)String.
+            if (arg instanceof Byte) {
+                value &= 0xffL;
+            } else if (arg instanceof Short) {
+                value &= 0xffffL;
+            } else if (arg instanceof Integer) {
+                value &= 0xffffffffL;
             }
-            if (isNegative && formatToken.flagZero) {
-                startIndex++;
+            if ('o' == currentConversionType) {
+                result.append(Long.toOctalString(value));
+            } else {
+                result.append(Long.toHexString(value));
             }
-            return padding(result, startIndex);
         }
 
-        /*
-         * Transforms a Float,Double or BigDecimal to a formatted string.
-         */
-        private CharSequence transformFromFloat() {
-            StringBuilder result = new StringBuilder();
-            int startIndex = 0;
-            char currentConversionType = formatToken.getConversionType();
+        return padding(result, startIndex);
+    }
 
-            if (formatToken.flagMinus || formatToken.flagZero) {
-                if (!formatToken.isWidthSet()) {
-                    throw new MissingFormatWidthException(formatToken.getStrFlags());
-                }
-            }
+    private CharSequence transformFromSpecialNumber() {
+        if (!(arg instanceof Number) || arg instanceof BigDecimal) {
+            return null;
+        }
 
-            if (formatToken.flagAdd && formatToken.flagSpace) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-            }
-
-            if (formatToken.flagMinus && formatToken.flagZero) {
-                throw new IllegalFormatFlagsException(formatToken.getStrFlags());
-            }
-
-            if (currentConversionType == 'e' || currentConversionType == 'E') {
-                if (formatToken.flagComma) {
-                    throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                            currentConversionType);
-                }
-            } else if (currentConversionType == 'g' || currentConversionType == 'G') {
-                if (formatToken.flagSharp) {
-                    throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                            currentConversionType);
-                }
-            } else if (currentConversionType == 'a' || currentConversionType == 'A') {
-                if (formatToken.flagComma || formatToken.flagParenthesis) {
-                    throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                            currentConversionType);
-                }
-            }
-
-            if (null == arg) {
-                return transformFromNull();
-            }
-
-            if (!(arg instanceof Float || arg instanceof Double || arg instanceof BigDecimal)) {
-                throw badArgumentType();
-            }
-
-            CharSequence specialNumberResult = transformFromSpecialNumber();
-            if (null != specialNumberResult) {
-                return specialNumberResult;
-            }
-
-            if (currentConversionType != 'a' && currentConversionType != 'A' &&
-                    !formatToken.isPrecisionSet()) {
-                formatToken.setPrecision(FormatToken.DEFAULT_PRECISION);
-            }
-
-            // output result
-            DecimalFormatSymbols decimalFormatSymbols = getDecimalFormatSymbols();
-            FloatUtil floatUtil = new FloatUtil(result, formatToken,
-                    (DecimalFormat) getNumberFormat(), decimalFormatSymbols, arg);
-            floatUtil.transform(currentConversionType);
-
-            formatToken.setPrecision(FormatToken.UNSET);
-
-            if (decimalFormatSymbols.getMinusSign() == result.charAt(0)) {
-                if (formatToken.flagParenthesis) {
-                    return wrapParentheses(result);
-                }
+        Number number = (Number) arg;
+        double d = number.doubleValue();
+        String source = null;
+        if (Double.isNaN(d)) {
+            source = "NaN";
+        } else if (d == Double.POSITIVE_INFINITY) {
+            if (formatToken.flagAdd) {
+                source = "+Infinity";
+            } else if (formatToken.flagSpace) {
+                source = " Infinity";
             } else {
-                if (formatToken.flagSpace) {
-                    result.insert(0, ' ');
-                    startIndex++;
-                }
-                if (formatToken.flagAdd) {
-                    result.insert(0, floatUtil.getAddSign());
-                    startIndex++;
-                }
+                source = "Infinity";
             }
-
-            char firstChar = result.charAt(0);
-            if (formatToken.flagZero
-                    && (firstChar == floatUtil.getAddSign() || firstChar == decimalFormatSymbols.getMinusSign())) {
-                startIndex = 1;
+        } else if (d == Double.NEGATIVE_INFINITY) {
+            if (formatToken.flagParenthesis) {
+                source = "(Infinity)";
+            } else {
+                source = "-Infinity";
             }
+        } else {
+            return null;
+        }
 
-            if (currentConversionType == 'a' || currentConversionType == 'A') {
+        formatToken.setPrecision(FormatToken.UNSET);
+        formatToken.flagZero = false;
+        return padding(source, 0);
+    }
+
+    private CharSequence transformFromNull() {
+        formatToken.flagZero = false;
+        return padding("null", 0);
+    }
+
+    private CharSequence transformFromBigInteger() {
+        int startIndex = 0;
+        StringBuilder result = new StringBuilder();
+        BigInteger bigInt = (BigInteger) arg;
+        char currentConversionType = formatToken.getConversionType();
+
+        if (bigInt == null) {
+            return transformFromNull();
+        }
+
+        boolean isNegative = (bigInt.compareTo(BigInteger.ZERO) < 0);
+
+        if ('d' == currentConversionType) {
+            NumberFormat numberFormat = getNumberFormat();
+            numberFormat.setGroupingUsed(formatToken.flagComma);
+            result.append(numberFormat.format(bigInt));
+        } else if ('o' == currentConversionType) {
+            // convert BigInteger to a string presentation using radix 8
+            result.append(bigInt.toString(8));
+        } else {
+            // convert BigInteger to a string presentation using radix 16
+            result.append(bigInt.toString(16));
+        }
+        if (formatToken.flagSharp) {
+            startIndex = isNegative ? 1 : 0;
+            if (currentConversionType == 'o') {
+                result.insert(startIndex, "0");
+                startIndex += 1;
+            } else if (currentConversionType == 'x' || currentConversionType == 'X') {
+                result.insert(startIndex, "0x");
                 startIndex += 2;
             }
-            return padding(result, startIndex);
         }
 
-        /*
-         * Transforms a Date to a formatted string.
-         */
-        private CharSequence transformFromDateTime() {
-            formatToken.ensureNoPrecision();
-
-            char currentConversionType = formatToken.getConversionType();
-
-            if (formatToken.flagSharp) {
-                throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(),
-                        currentConversionType);
+        if (!isNegative) {
+            if (formatToken.flagAdd) {
+                result.insert(0, '+');
+                startIndex += 1;
             }
-
-            if (formatToken.flagMinus && formatToken.getWidth() == FormatToken.UNSET) {
-                throw new MissingFormatWidthException("-" //$NON-NLS-1$
-                        + currentConversionType);
+            if (formatToken.flagSpace) {
+                result.insert(0, ' ');
+                startIndex += 1;
             }
-
-            if (null == arg) {
-                return transformFromNull();
-            }
-
-            Calendar calendar;
-            if (arg instanceof Calendar) {
-                calendar = (Calendar) arg;
-            } else {
-                Date date = null;
-                if (arg instanceof Long) {
-                    date = new Date(((Long) arg).longValue());
-                } else if (arg instanceof Date) {
-                    date = (Date) arg;
-                } else {
-                    throw badArgumentType();
-                }
-                calendar = Calendar.getInstance(locale);
-                calendar.setTime(date);
-            }
-
-            if (null == dateTimeUtil) {
-                dateTimeUtil = new DateTimeUtil(locale);
-            }
-            StringBuilder result = new StringBuilder();
-            // output result
-            dateTimeUtil.transform(formatToken, calendar, result);
-            return padding(result, 0);
         }
+
+        /* pad paddingChar to the output */
+        if (isNegative && formatToken.flagParenthesis) {
+            return wrapParentheses(result);
+        }
+        if (isNegative && formatToken.flagZero) {
+            startIndex++;
+        }
+        return padding(result, startIndex);
     }
 
-    private static class FloatUtil {
-        private final StringBuilder result;
-        private final DecimalFormat decimalFormat;
-        private final DecimalFormatSymbols decimalFormatSymbols;
-        private final FormatToken formatToken;
-        private final Object argument;
-
-        FloatUtil(StringBuilder result, FormatToken formatToken, DecimalFormat decimalFormat,
-                DecimalFormatSymbols decimalFormatSymbols, Object argument) {
-            this.result = result;
-            this.formatToken = formatToken;
-            this.decimalFormat = decimalFormat;
-            this.decimalFormatSymbols = decimalFormatSymbols;
-            this.argument = argument;
+    private CharSequence transformFromDateTime() {
+        if (arg == null) {
+            return transformFromNull();
         }
 
-        void transform(char conversionType) {
-            switch (conversionType) {
-                case 'e':
-                case 'E': {
-                    transform_e();
-                    break;
-                }
-                case 'f': {
-                    transform_f();
-                    break;
-                }
-                case 'g':
-                case 'G': {
-                    transform_g();
-                    break;
-                }
-                case 'a':
-                case 'A': {
-                    transform_a();
-                    break;
-                }
-                default: {
-                    throw new UnknownFormatConversionException(String.valueOf(conversionType));
-                }
-            }
-        }
-
-        char getAddSign() {
-            return '+';
-        }
-
-        void transform_e() {
-            StringBuilder pattern = new StringBuilder();
-            pattern.append('0');
-            if (formatToken.getPrecision() > 0) {
-                pattern.append('.');
-                char[] zeros = new char[formatToken.getPrecision()];
-                Arrays.fill(zeros, '0');
-                pattern.append(zeros);
-            }
-            pattern.append('E');
-            pattern.append("+00"); //$NON-NLS-1$
-            decimalFormat.applyPattern(pattern.toString());
-            String formattedString = decimalFormat.format(argument);
-            result.append(formattedString.replace('E', 'e'));
-
-            // if the flag is sharp and decimal separator is always given
-            // out.
-            if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
-                int indexOfE = result.indexOf("e"); //$NON-NLS-1$
-                result.insert(indexOfE, decimalFormatSymbols.getDecimalSeparator());
-            }
-        }
-
-        void transform_g() {
-            int precision = formatToken.getPrecision();
-            precision = (0 == precision ? 1 : precision);
-            formatToken.setPrecision(precision);
-
-            if (0.0 == ((Number) argument).doubleValue()) {
-                precision--;
-                formatToken.setPrecision(precision);
-                transform_f();
-                return;
-            }
-
-            boolean requireScientificRepresentation = true;
-            double d = ((Number) argument).doubleValue();
-            d = Math.abs(d);
-            if (Double.isInfinite(d)) {
-                precision = formatToken.getPrecision();
-                precision--;
-                formatToken.setPrecision(precision);
-                transform_e();
-                return;
-            }
-            BigDecimal b = new BigDecimal(d, new MathContext(precision));
-            d = b.doubleValue();
-            long l = b.longValue();
-
-            if (d >= 1 && d < Math.pow(10, precision)) {
-                if (l < Math.pow(10, precision)) {
-                    requireScientificRepresentation = false;
-                    precision -= String.valueOf(l).length();
-                    precision = precision < 0 ? 0 : precision;
-                    l = Math.round(d * Math.pow(10, precision + 1));
-                    if (String.valueOf(l).length() <= formatToken
-                            .getPrecision()) {
-                        precision++;
-                    }
-                    formatToken.setPrecision(precision);
-                }
-
+        Calendar calendar;
+        if (arg instanceof Calendar) {
+            calendar = (Calendar) arg;
+        } else {
+            Date date = null;
+            if (arg instanceof Long) {
+                date = new Date(((Long) arg).longValue());
+            } else if (arg instanceof Date) {
+                date = (Date) arg;
             } else {
-                l = b.movePointRight(4).longValue();
-                if (d >= Math.pow(10, -4) && d < 1) {
-                    requireScientificRepresentation = false;
-                    precision += 4 - String.valueOf(l).length();
-                    l = b.movePointRight(precision + 1).longValue();
-                    if (String.valueOf(l).length() <= formatToken
-                            .getPrecision()) {
-                        precision++;
-                    }
-                    l = b.movePointRight(precision).longValue();
-                    if (l >= Math.pow(10, precision - 4)) {
-                        formatToken.setPrecision(precision);
-                    }
-                }
+                throw badArgumentType();
             }
-            if (requireScientificRepresentation) {
-                precision = formatToken.getPrecision();
-                precision--;
-                formatToken.setPrecision(precision);
-                transform_e();
-            } else {
-                transform_f();
-            }
+            calendar = Calendar.getInstance(locale);
+            calendar.setTime(date);
         }
 
-        void transform_f() {
-            // TODO: store a default DecimalFormat we can clone?
-            String pattern = "0.000000";
-            if (formatToken.flagComma || formatToken.getPrecision() != 6) {
-                StringBuilder patternBuilder = new StringBuilder();
-                if (formatToken.flagComma) {
-                    patternBuilder.append(',');
-                    int groupingSize = decimalFormat.getGroupingSize();
-                    if (groupingSize > 1) {
-                        char[] sharps = new char[groupingSize - 1];
-                        Arrays.fill(sharps, '#');
-                        patternBuilder.append(sharps);
-                    }
-                }
-                patternBuilder.append(0);
-                if (formatToken.getPrecision() > 0) {
-                    patternBuilder.append('.');
-                    char[] zeros = new char[formatToken.getPrecision()];
-                    Arrays.fill(zeros, '0');
-                    patternBuilder.append(zeros);
-                }
-                pattern = patternBuilder.toString();
-            }
-            // TODO: if DecimalFormat.toPattern was cheap, we could make this cheap (preferably *in* DecimalFormat).
-            decimalFormat.applyPattern(pattern);
-            result.append(decimalFormat.format(argument));
-            // if the flag is sharp and decimal separator is always given
-            // out.
-            if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
-                result.append(decimalFormatSymbols.getDecimalSeparator());
-            }
+        StringBuilder result = new StringBuilder();
+        if (!appendT(result, formatToken.getDateSuffix(), calendar)) {
+            throw formatToken.unknownFormatConversionException();
         }
-
-        void transform_a() {
-            if (argument instanceof Float) {
-                Float F = (Float) argument;
-                result.append(Float.toHexString(F.floatValue()));
-
-            } else if (argument instanceof Double) {
-                Double D = (Double) argument;
-                result.append(Double.toHexString(D.doubleValue()));
-            } else {
-                // BigInteger is not supported.
-                throw new IllegalFormatConversionException(
-                        formatToken.getConversionType(), argument.getClass());
-            }
-
-            if (!formatToken.isPrecisionSet()) {
-                return;
-            }
-
-            int precision = formatToken.getPrecision();
-            precision = (0 == precision ? 1 : precision);
-            int indexOfFirstFractionalDigit = result.indexOf(".") + 1; //$NON-NLS-1$
-            int indexOfP = result.indexOf("p"); //$NON-NLS-1$
-            int fractionalLength = indexOfP - indexOfFirstFractionalDigit;
-
-            if (fractionalLength == precision) {
-                return;
-            }
-
-            if (fractionalLength < precision) {
-                char zeros[] = new char[precision - fractionalLength];
-                Arrays.fill(zeros, '0');
-                result.insert(indexOfP, zeros);
-                return;
-            }
-            result.delete(indexOfFirstFractionalDigit + precision, indexOfP);
-        }
+        return padding(result, 0);
     }
-
-    private static class DateTimeUtil {
-        private Calendar calendar;
-
-        private Locale locale;
-
-        private StringBuilder result;
-
-        private DateFormatSymbols dateFormatSymbols;
-
-        DateTimeUtil(Locale locale) {
-            this.locale = locale;
-        }
-
-        void transform(FormatToken formatToken, Calendar aCalendar,
-                StringBuilder aResult) {
-            this.result = aResult;
-            this.calendar = aCalendar;
-            char suffix = formatToken.getDateSuffix();
-
-            switch (suffix) {
-                case 'H': {
-                    transform_H();
-                    break;
-                }
-                case 'I': {
-                    transform_I();
-                    break;
-                }
-                case 'M': {
-                    transform_M();
-                    break;
-                }
-                case 'S': {
-                    transform_S();
-                    break;
-                }
-                case 'L': {
-                    transform_L();
-                    break;
-                }
-                case 'N': {
-                    transform_N();
-                    break;
-                }
-                case 'k': {
-                    transform_k();
-                    break;
-                }
-                case 'l': {
-                    transform_l();
-                    break;
-                }
-                case 'p': {
-                    transform_p(true);
-                    break;
-                }
-                case 's': {
-                    transform_s();
-                    break;
-                }
-                case 'z': {
-                    transform_z();
-                    break;
-                }
-                case 'Z': {
-                    transform_Z();
-                    break;
-                }
-                case 'Q': {
-                    transform_Q();
-                    break;
-                }
-                case 'B': {
-                    transform_B();
-                    break;
-                }
-                case 'b':
-                case 'h': {
-                    transform_b();
-                    break;
-                }
-                case 'A': {
-                    transform_A();
-                    break;
-                }
-                case 'a': {
-                    transform_a();
-                    break;
-                }
-                case 'C': {
-                    transform_C();
-                    break;
-                }
-                case 'Y': {
-                    transform_Y();
-                    break;
-                }
-                case 'y': {
-                    transform_y();
-                    break;
-                }
-                case 'j': {
-                    transform_j();
-                    break;
-                }
-                case 'm': {
-                    transform_m();
-                    break;
-                }
-                case 'd': {
-                    transform_d();
-                    break;
-                }
-                case 'e': {
-                    transform_e();
-                    break;
-                }
-                case 'R': {
-                    transform_R();
-                    break;
-                }
-
-                case 'T': {
-                    transform_T();
-                    break;
-                }
-                case 'r': {
-                    transform_r();
-                    break;
-                }
-                case 'D': {
-                    transform_D();
-                    break;
-                }
-                case 'F': {
-                    transform_F();
-                    break;
-                }
-                case 'c': {
-                    transform_c();
-                    break;
-                }
-                default: {
-                    throw new UnknownFormatConversionException(String
-                            .valueOf(formatToken.getConversionType())
-                            + formatToken.getDateSuffix());
-                }
-            }
-        }
-
-        private void transform_e() {
-            int day = calendar.get(Calendar.DAY_OF_MONTH);
-            result.append(day);
-        }
-
-        private void transform_d() {
-            int day = calendar.get(Calendar.DAY_OF_MONTH);
-            result.append(paddingZeros(day, 2));
-        }
-
-        private void transform_m() {
-            int month = calendar.get(Calendar.MONTH);
-            // The returned month starts from zero, which needs to be
-            // incremented by 1.
-            month++;
-            result.append(paddingZeros(month, 2));
-        }
-
-        private void transform_j() {
-            int day = calendar.get(Calendar.DAY_OF_YEAR);
-            result.append(paddingZeros(day, 3));
-        }
-
-        private void transform_y() {
-            int year = calendar.get(Calendar.YEAR);
-            year %= 100;
-            result.append(paddingZeros(year, 2));
-        }
-
-        private void transform_Y() {
-            int year = calendar.get(Calendar.YEAR);
-            result.append(paddingZeros(year, 4));
-        }
-
-        private void transform_C() {
-            int year = calendar.get(Calendar.YEAR);
-            year /= 100;
-            result.append(paddingZeros(year, 2));
-        }
-
-        private void transform_a() {
-            int day = calendar.get(Calendar.DAY_OF_WEEK);
-            result.append(getDateFormatSymbols().getShortWeekdays()[day]);
-        }
-
-        private void transform_A() {
-            int day = calendar.get(Calendar.DAY_OF_WEEK);
-            result.append(getDateFormatSymbols().getWeekdays()[day]);
-        }
-
-        private void transform_b() {
-            int month = calendar.get(Calendar.MONTH);
-            result.append(getDateFormatSymbols().getShortMonths()[month]);
-        }
-
-        private void transform_B() {
-            int month = calendar.get(Calendar.MONTH);
-            result.append(getDateFormatSymbols().getMonths()[month]);
-        }
-
-        private void transform_Q() {
-            long milliSeconds = calendar.getTimeInMillis();
-            result.append(milliSeconds);
-        }
-
-        private void transform_s() {
-            long milliSeconds = calendar.getTimeInMillis();
-            milliSeconds /= 1000;
-            result.append(milliSeconds);
-        }
-
-        private void transform_Z() {
+        
+    private boolean appendT(StringBuilder result, char conversion, Calendar calendar) {
+        switch (conversion) {
+        case 'A':
+            result.append(localeData.longWeekdayNames[calendar.get(Calendar.DAY_OF_WEEK)]);
+            return true;
+        case 'a':
+            result.append(localeData.shortWeekdayNames[calendar.get(Calendar.DAY_OF_WEEK)]);
+            return true;
+        case 'B':
+            result.append(localeData.longMonthNames[calendar.get(Calendar.MONTH)]);
+            return true;
+        case 'b': case 'h':
+            result.append(localeData.shortMonthNames[calendar.get(Calendar.MONTH)]);
+            return true;
+        case 'C':
+            appendLocalized(result, calendar.get(Calendar.YEAR) / 100, 2);
+            return true;
+        case 'D':
+            appendT(result, 'm', calendar);
+            result.append('/');
+            appendT(result, 'd', calendar);
+            result.append('/');
+            appendT(result, 'y', calendar);
+            return true;
+        case 'F':
+            appendT(result, 'Y', calendar);
+            result.append('-');
+            appendT(result, 'm', calendar);
+            result.append('-');
+            appendT(result, 'd', calendar);
+            return true;
+        case 'H':
+            appendLocalized(result, calendar.get(Calendar.HOUR_OF_DAY), 2);
+            return true;
+        case 'I':
+            appendLocalized(result, to12Hour(calendar.get(Calendar.HOUR)), 2);
+            return true;
+        case 'L':
+            appendLocalized(result, calendar.get(Calendar.MILLISECOND), 3);
+            return true;
+        case 'M':
+            appendLocalized(result, calendar.get(Calendar.MINUTE), 2);
+            return true;
+        case 'N':
+            appendLocalized(result, calendar.get(Calendar.MILLISECOND) * 1000000L, 9);
+            return true;
+        case 'Q':
+            appendLocalized(result, calendar.getTimeInMillis(), 0);
+            return true;
+        case 'R':
+            appendT(result, 'H', calendar);
+            result.append(':');
+            appendT(result, 'M', calendar);
+            return true;
+        case 'S':
+            appendLocalized(result, calendar.get(Calendar.SECOND), 2);
+            return true;
+        case 'T':
+            appendT(result, 'H', calendar);
+            result.append(':');
+            appendT(result, 'M', calendar);
+            result.append(':');
+            appendT(result, 'S', calendar);
+            return true;
+        case 'Y':
+            appendLocalized(result, calendar.get(Calendar.YEAR), 4);
+            return true;
+        case 'Z':
             TimeZone timeZone = calendar.getTimeZone();
-            result.append(timeZone
-                    .getDisplayName(
-                            timeZone.inDaylightTime(calendar.getTime()),
-                            TimeZone.SHORT, locale));
-        }
-
-        private void transform_z() {
+            result.append(timeZone.getDisplayName(timeZone.inDaylightTime(calendar.getTime()),
+                    TimeZone.SHORT, locale));
+            return true;
+        case 'c':
+            appendT(result, 'a', calendar);
+            result.append(' ');
+            appendT(result, 'b', calendar);
+            result.append(' ');
+            appendT(result, 'd', calendar);
+            result.append(' ');
+            appendT(result, 'T', calendar);
+            result.append(' ');
+            appendT(result, 'Z', calendar);
+            result.append(' ');
+            appendT(result, 'Y', calendar);
+            return true;
+        case 'd':
+            appendLocalized(result, calendar.get(Calendar.DAY_OF_MONTH), 2);
+            return true;
+        case 'e':
+            appendLocalized(result, calendar.get(Calendar.DAY_OF_MONTH), 0);
+            return true;
+        case 'j':
+            appendLocalized(result, calendar.get(Calendar.DAY_OF_YEAR), 3);
+            return true;
+        case 'k':
+            appendLocalized(result, calendar.get(Calendar.HOUR_OF_DAY), 0);
+            return true;
+        case 'l':
+            appendLocalized(result, to12Hour(calendar.get(Calendar.HOUR)), 0);
+            return true;
+        case 'm':
+            // Calendar.JANUARY is 0; humans want January represented as 1.
+            appendLocalized(result, calendar.get(Calendar.MONTH) + 1, 2);
+            return true;
+        case 'p':
+            result.append(localeData.amPm[calendar.get(Calendar.AM_PM)].toLowerCase(locale));
+            return true;
+        case 'r':
+            appendT(result, 'I', calendar);
+            result.append(':');
+            appendT(result, 'M', calendar);
+            result.append(':');
+            appendT(result, 'S', calendar);
+            result.append(' ');
+            result.append(localeData.amPm[calendar.get(Calendar.AM_PM)]);
+            return true;
+        case 's':
+            appendLocalized(result, calendar.getTimeInMillis() / 1000, 0);
+            return true;
+        case 'y':
+            appendLocalized(result, calendar.get(Calendar.YEAR) % 100, 2);
+            return true;
+        case 'z':
             long offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
             char sign = '+';
             if (offset < 0) {
@@ -2459,144 +1958,252 @@
                 offset = -offset;
             }
             result.append(sign);
-            result.append(paddingZeros(offset / 3600000, 2));
-            result.append(paddingZeros((offset % 3600000) / 60000, 2));
+            appendLocalized(result, offset / 3600000, 2);
+            appendLocalized(result, (offset % 3600000) / 60000, 2);
+            return true;
         }
-
-        private void transform_p(boolean isLowerCase) {
-            int i = calendar.get(Calendar.AM_PM);
-            String s = getDateFormatSymbols().getAmPmStrings()[i];
-            if (isLowerCase) {
-                s = s.toLowerCase(locale);
+        return false;
+    }
+    
+    private int to12Hour(int hour) {
+        return hour == 0 ? 12 : hour;
+    }
+    
+    private void appendLocalized(StringBuilder result, long value, int width) {
+        int paddingIndex = result.length();
+        char zeroDigit = localeData.zeroDigit;
+        if (zeroDigit == '0') {
+            result.append(value);
+        } else {
+            result.append(localizeDigits(Long.toString(value)));
+        }
+        int zeroCount = width - (result.length() - paddingIndex);
+        if (zeroCount <= 0) {
+            return;
+        }
+        if (zeroDigit == '0') {
+            result.insert(paddingIndex, ZEROS, 0, zeroCount);
+        } else {
+            for (int i = 0; i < zeroCount; ++i) {
+                result.insert(paddingIndex, zeroDigit);
             }
-            result.append(s);
+        }
+    }
+
+    private CharSequence transformFromFloat() {
+        if (arg == null) {
+            return transformFromNull();
         }
 
-        private void transform_N() {
-            long nanosecond = calendar.get(Calendar.MILLISECOND) * 1000000L;
-            result.append(paddingZeros(nanosecond, 9));
+        if (!(arg instanceof Float || arg instanceof Double || arg instanceof BigDecimal)) {
+            throw badArgumentType();
         }
 
-        private void transform_L() {
-            int millisecond = calendar.get(Calendar.MILLISECOND);
-            result.append(paddingZeros(millisecond, 3));
+        CharSequence specialNumberResult = transformFromSpecialNumber();
+        if (specialNumberResult != null) {
+            return specialNumberResult;
         }
 
-        private void transform_S() {
-            int second = calendar.get(Calendar.SECOND);
-            result.append(paddingZeros(second, 2));
+        char conversionType = formatToken.getConversionType();
+        if (conversionType != 'a' && conversionType != 'A' && !formatToken.isPrecisionSet()) {
+            formatToken.setPrecision(FormatToken.DEFAULT_PRECISION);
         }
 
-        private void transform_M() {
-            int minute = calendar.get(Calendar.MINUTE);
-            result.append(paddingZeros(minute, 2));
+        StringBuilder result = new StringBuilder();
+        switch (conversionType) {
+        case 'a': case 'A':
+            transform_a(result);
+            break;
+        case 'e': case 'E':
+            transform_e(result);
+            break;
+        case 'f':
+            transform_f(result);
+            break;
+        case 'g':
+        case 'G':
+            transform_g(result);
+            break;
+        default:
+            throw formatToken.unknownFormatConversionException();
         }
 
-        private void transform_l() {
-            int hour = calendar.get(Calendar.HOUR);
-            if (0 == hour) {
-                hour = 12;
+        formatToken.setPrecision(FormatToken.UNSET);
+
+        int startIndex = 0;
+        if (localeData.minusSign == result.charAt(0)) {
+            if (formatToken.flagParenthesis) {
+                return wrapParentheses(result);
             }
-            result.append(hour);
-        }
-
-        private void transform_k() {
-            int hour = calendar.get(Calendar.HOUR_OF_DAY);
-            result.append(hour);
-        }
-
-        private void transform_I() {
-            int hour = calendar.get(Calendar.HOUR);
-            if (0 == hour) {
-                hour = 12;
+        } else {
+            if (formatToken.flagSpace) {
+                result.insert(0, ' ');
+                startIndex++;
             }
-            result.append(paddingZeros(hour, 2));
-        }
-
-        private void transform_H() {
-            int hour = calendar.get(Calendar.HOUR_OF_DAY);
-            result.append(paddingZeros(hour, 2));
-        }
-
-        private void transform_R() {
-            transform_H();
-            result.append(':');
-            transform_M();
-        }
-
-        private void transform_T() {
-            transform_H();
-            result.append(':');
-            transform_M();
-            result.append(':');
-            transform_S();
-        }
-
-        private void transform_r() {
-            transform_I();
-            result.append(':');
-            transform_M();
-            result.append(':');
-            transform_S();
-            result.append(' ');
-            transform_p(false);
-        }
-
-        private void transform_D() {
-            transform_m();
-            result.append('/');
-            transform_d();
-            result.append('/');
-            transform_y();
-        }
-
-        private void transform_F() {
-            transform_Y();
-            result.append('-');
-            transform_m();
-            result.append('-');
-            transform_d();
-        }
-
-        private void transform_c() {
-            transform_a();
-            result.append(' ');
-            transform_b();
-            result.append(' ');
-            transform_d();
-            result.append(' ');
-            transform_T();
-            result.append(' ');
-            transform_Z();
-            result.append(' ');
-            transform_Y();
-        }
-
-        // TODO: this doesn't need a temporary StringBuilder!
-        private static String paddingZeros(long number, int length) {
-            int len = length;
-            StringBuilder result = new StringBuilder();
-            result.append(number);
-            int startIndex = 0;
-            if (number < 0) {
-                len++;
-                startIndex = 1;
+            if (formatToken.flagAdd) {
+                result.insert(0, '+');
+                startIndex++;
             }
-            len -= result.length();
-            if (len > 0) {
-                char[] zeros = new char[len];
-                Arrays.fill(zeros, '0');
-                result.insert(startIndex, zeros);
-            }
-            return result.toString();
         }
 
-        private DateFormatSymbols getDateFormatSymbols() {
-            if (null == dateFormatSymbols) {
-                dateFormatSymbols = new DateFormatSymbols(locale);
-            }
-            return dateFormatSymbols;
+        char firstChar = result.charAt(0);
+        if (formatToken.flagZero && (firstChar == '+' || firstChar == localeData.minusSign)) {
+            startIndex = 1;
         }
+
+        if (conversionType == 'a' || conversionType == 'A') {
+            startIndex += 2;
+        }
+        return padding(result, startIndex);
+    }
+
+    private void transform_e(StringBuilder result) {
+        StringBuilder pattern = new StringBuilder();
+        pattern.append('0');
+        if (formatToken.getPrecision() > 0) {
+            pattern.append('.');
+            char[] zeros = new char[formatToken.getPrecision()];
+            Arrays.fill(zeros, '0'); // This is a *pattern* character, so no localization.
+            pattern.append(zeros);
+        }
+        pattern.append("E+00");
+        DecimalFormat decimalFormat = (DecimalFormat) getNumberFormat();
+        decimalFormat.applyPattern(pattern.toString());
+        String formattedString = decimalFormat.format(arg);
+        result.append(formattedString.replace('E', 'e'));
+
+        // if the flag is sharp and decimal separator is always given out.
+        if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
+            int indexOfE = result.indexOf("e");
+            result.insert(indexOfE, localeData.decimalSeparator);
+        }
+    }
+
+    private void transform_g(StringBuilder result) {
+        int precision = formatToken.getPrecision();
+        precision = (0 == precision ? 1 : precision);
+        formatToken.setPrecision(precision);
+
+        double d = ((Number) arg).doubleValue();
+        if (d == 0.0) {
+            precision--;
+            formatToken.setPrecision(precision);
+            transform_f(result);
+            return;
+        }
+
+        boolean requireScientificRepresentation = true;
+        d = Math.abs(d);
+        if (Double.isInfinite(d)) {
+            precision = formatToken.getPrecision();
+            precision--;
+            formatToken.setPrecision(precision);
+            transform_e(result);
+            return;
+        }
+        BigDecimal b = new BigDecimal(d, new MathContext(precision));
+        d = b.doubleValue();
+        long l = b.longValue();
+
+        if (d >= 1 && d < Math.pow(10, precision)) {
+            if (l < Math.pow(10, precision)) {
+                requireScientificRepresentation = false;
+                precision -= String.valueOf(l).length();
+                precision = precision < 0 ? 0 : precision;
+                l = Math.round(d * Math.pow(10, precision + 1));
+                if (String.valueOf(l).length() <= formatToken.getPrecision()) {
+                    precision++;
+                }
+                formatToken.setPrecision(precision);
+            }
+        } else {
+            l = b.movePointRight(4).longValue();
+            if (d >= Math.pow(10, -4) && d < 1) {
+                requireScientificRepresentation = false;
+                precision += 4 - String.valueOf(l).length();
+                l = b.movePointRight(precision + 1).longValue();
+                if (String.valueOf(l).length() <= formatToken.getPrecision()) {
+                    precision++;
+                }
+                l = b.movePointRight(precision).longValue();
+                if (l >= Math.pow(10, precision - 4)) {
+                    formatToken.setPrecision(precision);
+                }
+            }
+        }
+        if (requireScientificRepresentation) {
+            precision = formatToken.getPrecision();
+            precision--;
+            formatToken.setPrecision(precision);
+            transform_e(result);
+        } else {
+            transform_f(result);
+        }
+    }
+
+    private void transform_f(StringBuilder result) {
+        // TODO: store a default DecimalFormat we can clone?
+        String pattern = "0.000000";
+        DecimalFormat decimalFormat = (DecimalFormat) getNumberFormat();
+        if (formatToken.flagComma || formatToken.getPrecision() != 6) {
+            StringBuilder patternBuilder = new StringBuilder();
+            if (formatToken.flagComma) {
+                patternBuilder.append(',');
+                int groupingSize = decimalFormat.getGroupingSize();
+                if (groupingSize > 1) {
+                    char[] sharps = new char[groupingSize - 1];
+                    Arrays.fill(sharps, '#');
+                    patternBuilder.append(sharps);
+                }
+            }
+            patternBuilder.append('0');
+            if (formatToken.getPrecision() > 0) {
+                patternBuilder.append('.');
+                char[] zeros = new char[formatToken.getPrecision()];
+                Arrays.fill(zeros, '0'); // This is a *pattern* character, so no localization.
+                patternBuilder.append(zeros);
+            }
+            pattern = patternBuilder.toString();
+        }
+        // TODO: if DecimalFormat.toPattern was cheap, we could make this cheap (preferably *in* DecimalFormat).
+        decimalFormat.applyPattern(pattern);
+        result.append(decimalFormat.format(arg));
+        // if the flag is sharp and decimal separator is always given out.
+        if (formatToken.flagSharp && formatToken.getPrecision() == 0) {
+            result.append(localeData.decimalSeparator);
+        }
+    }
+
+    private void transform_a(StringBuilder result) {
+        if (arg instanceof Float) {
+            result.append(Float.toHexString(((Float) arg).floatValue()));
+        } else if (arg instanceof Double) {
+            result.append(Double.toHexString(((Double) arg).doubleValue()));
+        } else {
+            throw badArgumentType();
+        }
+
+        if (!formatToken.isPrecisionSet()) {
+            return;
+        }
+
+        int precision = formatToken.getPrecision();
+        precision = (0 == precision ? 1 : precision);
+        int indexOfFirstFractionalDigit = result.indexOf(".") + 1;
+        int indexOfP = result.indexOf("p");
+        int fractionalLength = indexOfP - indexOfFirstFractionalDigit;
+
+        if (fractionalLength == precision) {
+            return;
+        }
+
+        if (fractionalLength < precision) {
+            char zeros[] = new char[precision - fractionalLength];
+            Arrays.fill(zeros, '0'); // %a shouldn't be localized.
+            result.insert(indexOfP, zeros);
+            return;
+        }
+        result.delete(indexOfFirstFractionalDigit + precision, indexOfP);
     }
 
     private static class FormatSpecifierParser {
@@ -2638,11 +2245,15 @@
 
         private char advance() {
             if (i >= length) {
-                throw new UnknownFormatConversionException(getFormatSpecifierText());
+                throw unknownFormatConversionException();
             }
             return format.charAt(i++);
         }
-
+        
+        private UnknownFormatConversionException unknownFormatConversionException() {
+            throw new UnknownFormatConversionException(getFormatSpecifierText());
+        }
+        
         private FormatToken parseArgumentIndexAndFlags(FormatToken token) {
             // Parse the argument index, if there is one.
             int position = i;
@@ -2708,7 +2319,7 @@
                 return parseConversionType(token);
             } else {
                 // The precision is required but not given by the format string.
-                throw new UnknownFormatConversionException(getFormatSpecifierText());
+                throw unknownFormatConversionException();
             }
         }
 
diff --git a/luni/src/main/java/java/util/Grego.java b/luni/src/main/java/java/util/Grego.java
new file mode 100644
index 0000000..df7a7fa
--- /dev/null
+++ b/luni/src/main/java/java/util/Grego.java
@@ -0,0 +1,214 @@
+/**

+ *******************************************************************************

+ * Copyright (C) 2003-2008, International Business Machines Corporation and

+ * others. All Rights Reserved.

+ *******************************************************************************

+ * Partial port from ICU4C's Grego class in i18n/gregoimp.h.

+ *

+ * Methods ported, or moved here from OlsonTimeZone, initially

+ * for work on Jitterbug 5470:

+ *   tzdata2006n Brazil incorrect fall-back date 2009-mar-01

+ * Only the methods necessary for that work are provided - this is not a full

+ * port of ICU4C's Grego class (yet).

+ *

+ * These utilities are used by both OlsonTimeZone and SimpleTimeZone.

+ */

+

+package java.util; // android-changed: com.ibm.icu.impl (ICU4J 4.2)

+

+// android-changed: import com.ibm.icu.util.Calendar;

+

+/**

+ * A utility class providing proleptic Gregorian calendar functions

+ * used by time zone and calendar code.  Do not instantiate.

+ *

+ * Note:  Unlike GregorianCalendar, all computations performed by this

+ * class occur in the pure proleptic GregorianCalendar.

+ */

+// android-changed: public

+class Grego {

+

+    // Max/min milliseconds 

+    public static final long MIN_MILLIS = -184303902528000000L;

+    public static final long MAX_MILLIS = 183882168921600000L;

+

+    public static final int MILLIS_PER_SECOND = 1000;

+    public static final int MILLIS_PER_MINUTE = 60*MILLIS_PER_SECOND;

+    public static final int MILLIS_PER_HOUR = 60*MILLIS_PER_MINUTE;

+    public static final int MILLIS_PER_DAY = 24*MILLIS_PER_HOUR;

+    

+    //  January 1, 1 CE Gregorian

+    private static final int JULIAN_1_CE = 1721426;

+

+    //  January 1, 1970 CE Gregorian

+    private static final int JULIAN_1970_CE = 2440588;

+

+    private static final int[] MONTH_LENGTH = new int[] {

+        31,28,31,30,31,30,31,31,30,31,30,31,

+        31,29,31,30,31,30,31,31,30,31,30,31

+    };

+

+    private static final int[] DAYS_BEFORE = new int[] {

+        0,31,59,90,120,151,181,212,243,273,304,334,

+        0,31,60,91,121,152,182,213,244,274,305,335 };

+

+    /**

+     * Return true if the given year is a leap year.

+     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.

+     * @return true if the year is a leap year

+     */

+    public static final boolean isLeapYear(int year) {

+        // year&0x3 == year%4

+        return ((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0));

+    }

+

+    /**

+     * Return the number of days in the given month.

+     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.

+     * @param month 0-based month, with 0==Jan

+     * @return the number of days in the given month

+     */

+    public static final int monthLength(int year, int month) {

+        return MONTH_LENGTH[month + (isLeapYear(year) ? 12 : 0)];

+    }

+

+    /**

+     * Return the length of a previous month of the Gregorian calendar.

+     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.

+     * @param month 0-based month, with 0==Jan

+     * @return the number of days in the month previous to the given month

+     */

+    public static final int previousMonthLength(int year, int month) {

+        return (month > 0) ? monthLength(year, month-1) : 31;

+    }

+

+    /**

+     * Convert a year, month, and day-of-month, given in the proleptic

+     * Gregorian calendar, to 1970 epoch days.

+     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.

+     * @param month 0-based month, with 0==Jan

+     * @param dom 1-based day of month

+     * @return the day number, with day 0 == Jan 1 1970

+     */

+    public static long fieldsToDay(int year, int month, int dom) {

+        int y = year - 1;

+        long julian =

+            365 * y + floorDivide(y, 4) + (JULIAN_1_CE - 3) +    // Julian cal

+            floorDivide(y, 400) - floorDivide(y, 100) + 2 +   // => Gregorian cal

+            DAYS_BEFORE[month + (isLeapYear(year) ? 12 : 0)] + dom; // => month/dom

+        return julian - JULIAN_1970_CE; // JD => epoch day

+    }

+

+    /**

+     * Return the day of week on the 1970-epoch day

+     * @param day the 1970-epoch day (integral value)

+     * @return the day of week

+     */

+    public static int dayOfWeek(long day) {

+        long[] remainder = new long[1];

+        floorDivide(day + Calendar.THURSDAY, 7, remainder);

+        int dayOfWeek = (int)remainder[0];

+        dayOfWeek = (dayOfWeek == 0) ? 7 : dayOfWeek;

+        return dayOfWeek;

+    }

+

+    public static int[] dayToFields(long day, int[] fields) {

+        if (fields == null || fields.length < 5) {

+            fields = new int[5];

+        }

+        // Convert from 1970 CE epoch to 1 CE epoch (Gregorian calendar)

+        day += JULIAN_1970_CE - JULIAN_1_CE;

+

+        long[] rem = new long[1];

+        long n400 = floorDivide(day, 146097, rem);

+        long n100 = floorDivide(rem[0], 36524, rem);

+        long n4 = floorDivide(rem[0], 1461, rem);

+        long n1 = floorDivide(rem[0], 365, rem);

+

+        int year = (int)(400 * n400 + 100 * n100 + 4 * n4 + n1);

+        int dayOfYear = (int)rem[0];

+        if (n100 == 4 || n1 == 4) {

+            dayOfYear = 365;    // Dec 31 at end of 4- or 400-yr cycle

+        }

+        else {

+            ++year;

+        }

+

+        boolean isLeap = isLeapYear(year);

+        int correction = 0;

+        int march1 = isLeap ? 60 : 59;  // zero-based DOY for March 1

+        if (dayOfYear >= march1) {

+            correction = isLeap ? 1 : 2;

+        }

+        int month = (12 * (dayOfYear + correction) + 6) / 367;  // zero-based month

+        int dayOfMonth = dayOfYear - DAYS_BEFORE[isLeap ? month + 12 : month] + 1; // one-based DOM

+        int dayOfWeek = (int)((day + 2) % 7);  // day 0 is Monday(2)

+        if (dayOfWeek < 1 /* Sunday */) {

+            dayOfWeek += 7;

+        }

+        dayOfYear++; // 1-based day of year

+

+        fields[0] = year;

+        fields[1] = month;

+        fields[2] = dayOfMonth;

+        fields[3] = dayOfWeek;

+        fields[4] = dayOfYear;

+

+        return fields;

+    }

+

+    /*

+     * Convert long time to date/time fields

+     * 

+     * result[0] : year

+     * result[1] : month

+     * result[2] : dayOfMonth

+     * result[3] : dayOfWeek

+     * result[4] : dayOfYear

+     * result[5] : millisecond in day

+     */

+    public static int[] timeToFields(long time, int[] fields) {

+        if (fields == null || fields.length < 6) {

+            fields = new int[6];

+        }

+        long[] remainder = new long[1];

+        long day = floorDivide(time, 24*60*60*1000 /* milliseconds per day */, remainder);

+        dayToFields(day, fields);

+        fields[5] = (int)remainder[0];

+        return fields;

+    }

+

+    public static long floorDivide(long numerator, long denominator) {

+        // We do this computation in order to handle

+        // a numerator of Long.MIN_VALUE correctly

+        return (numerator >= 0) ?

+            numerator / denominator :

+            ((numerator + 1) / denominator) - 1;

+    }

+

+    private static long floorDivide(long numerator, long denominator, long[] remainder) {

+        if (numerator >= 0) {

+            remainder[0] = numerator % denominator;

+            return numerator / denominator;

+        }

+        long quotient = ((numerator + 1) / denominator) - 1;

+        remainder[0] = numerator - (quotient * denominator);

+        return quotient;

+    }

+

+    /*

+     * Returns the ordinal number for the specified day of week in the month.

+     * The valid return value is 1, 2, 3, 4 or -1.

+     */

+    public static int getDayOfWeekInMonth(int year, int month, int dayOfMonth) {

+        int weekInMonth = (dayOfMonth + 6)/7;

+        if (weekInMonth == 4) {

+            if (dayOfMonth + 7 > monthLength(year, month)) {

+                weekInMonth = -1;

+            }

+        } else if (weekInMonth == 5) {

+            weekInMonth = -1;

+        }

+        return weekInMonth;

+    }

+}

diff --git a/luni/src/main/java/java/util/GregorianCalendar.java b/luni/src/main/java/java/util/GregorianCalendar.java
index 7339151..18a10ad 100644
--- a/luni/src/main/java/java/util/GregorianCalendar.java
+++ b/luni/src/main/java/java/util/GregorianCalendar.java
@@ -591,15 +591,14 @@
 
     @Override
     protected void computeFields() {
-        int zoneOffset = getTimeZone().getRawOffset();
-
-        if(!isSet[ZONE_OFFSET]) {
-            fields[ZONE_OFFSET] = zoneOffset;
-        }
+        TimeZone timeZone = getTimeZone();
+        int dstOffset = timeZone.inDaylightTime(new Date(time)) ? timeZone.getDSTSavings() : 0;
+        int zoneOffset = timeZone.getRawOffset();
+        fields[DST_OFFSET] = dstOffset;
+        fields[ZONE_OFFSET] = zoneOffset;
 
         int millis = (int) (time % 86400000);
         int savedMillis = millis;
-        int dstOffset = fields[DST_OFFSET];
         // compute without a change in daylight saving time
         int offset = zoneOffset + dstOffset;
         long newTime = time + offset;
@@ -610,6 +609,8 @@
             newTime = 0x8000000000000000L;
         }
 
+        // FIXME: I don't think this caching ever really gets used, because it requires that the
+        // time zone doesn't use daylight savings (ever). So unless you're somewhere like Taiwan...
         if (isCached) {
             if (millis < 0) {
                 millis += 86400000;
@@ -636,11 +637,11 @@
             fields[AM_PM] = fields[HOUR_OF_DAY] > 11 ? 1 : 0;
             fields[HOUR] = fields[HOUR_OF_DAY] % 12;
 
+            // FIXME: this has to be wrong; useDaylightTime doesn't mean what they think it means!
             long newTimeAdjusted = newTime;
-            if (getTimeZone().useDaylightTime()) {
+            if (timeZone.useDaylightTime()) {
                 // BEGIN android-changed: removed unnecessary cast
-                int dstSavings = (/* (SimpleTimeZone) */ getTimeZone())
-                        .getDSTSavings();
+                int dstSavings = timeZone.getDSTSavings();
                 // END android-changed
                 newTimeAdjusted += (dstOffset == 0) ? dstSavings : -dstSavings;
             }
@@ -665,7 +666,7 @@
         if (!isCached
                 && newTime != 0x7fffffffffffffffL
                 && newTime != 0x8000000000000000L
-                && (!getTimeZone().useDaylightTime() || getTimeZone() instanceof SimpleTimeZone)) {
+                && (!timeZone.useDaylightTime() || timeZone instanceof SimpleTimeZone)) {
             int cacheMillis = 0;
 
             cachedFields[0] = fields[YEAR];
@@ -992,6 +993,12 @@
      */
     @Override
     public boolean equals(Object object) {
+        if (!(object instanceof GregorianCalendar)) {
+            return false;
+        }
+        if (object == this) {
+            return true;
+        }
         return super.equals(object)
                 && gregorianCutover == ((GregorianCalendar) object).gregorianCutover;
     }
@@ -1151,7 +1158,7 @@
         return minimums[field];
     }
 
-    int getOffset(long localTime) {
+    private int getOffset(long localTime) {
         TimeZone timeZone = getTimeZone();
         if (!timeZone.useDaylightTime()) {
             return timeZone.getRawOffset();
diff --git a/luni/src/main/java/java/util/ListResourceBundle.java b/luni/src/main/java/java/util/ListResourceBundle.java
index 6206ee6..278f130 100644
--- a/luni/src/main/java/java/util/ListResourceBundle.java
+++ b/luni/src/main/java/java/util/ListResourceBundle.java
@@ -21,7 +21,7 @@
  * {@code ListResourceBundle} is the abstract superclass of classes which provide
  * resources by implementing the {@code getContents()} method to return
  * the list of resources.
- *
+ * 
  * @see ResourceBundle
  * @since 1.1
  */
@@ -36,20 +36,15 @@
     }
 
     /**
-     * Returns an {@code Object} array which contains the resources of this
+     * Returns an {@code Object} array containing the resources of this
      * {@code ListResourceBundle}. Each element in the array is an array of two
      * elements, the first is the resource key string and the second is the
      * resource.
-     *
+     * 
      * @return a {@code Object} array containing the resources.
      */
     protected abstract Object[][] getContents();
 
-    /**
-     * Returns the names of the resources contained in this {@code ListResourceBundle}.
-     *
-     * @return an {@code Enumeration} of the resource names.
-     */
     @Override
     public Enumeration<String> getKeys() {
         initializeTable();
@@ -131,4 +126,16 @@
             }
         }
     }
+    
+    /**
+     * Returns a set of the keys in this ResourceBundle but not in its parents.
+     * 
+     * @return a set of the keys in this ResourceBundle but not in its parents.
+     * @since 1.6
+     * @hide
+     */
+    protected Set<String> handleKeySet() {
+        initializeTable();
+        return table.keySet();
+    }
 }
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index 5337e48..c6535c1 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -17,23 +17,16 @@
 
 package java.util;
 
-// BEGIN android-changed
-// import java.io.File;
+import com.ibm.icu4jni.util.ICU;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
 import java.security.AccessController;
-// import java.util.zip.ZipEntry;
-// import java.util.zip.ZipFile;
-
 import org.apache.harmony.luni.util.PriviAction;
 import org.apache.harmony.luni.util.Util;
 
-import com.ibm.icu4jni.util.Resources;
-// END android-changed
-
 /**
  * {@code Locale} represents a language/country/variant combination. Locales are used to
  * alter the presentation of information such as numbers or dates to suit the conventions
@@ -58,9 +51,25 @@
  * spoken in Spain), for example. The opposite may well be true for a device sold in Europe.
  * (This limitation even affects those locales pre-defined as constants in this class.)
  *
- * <p>You can use {@code getDefault} to get an appropriate locale for the device you're
- * running on, or {@code getAvailableLocales} to get a list of all the locales available
- * on the device you're running on.
+ * <p>You can use {@code getDefault} to get an appropriate locale for the <i>user</i> of
+ * the device you're running on, or {@code getAvailableLocales} to get a list of all the locales
+ * available on the device you're running on.
+ *
+ * <a name="default_locale"><h3>Be wary of the default locale</h3></a>
+ * <p>Note that there are many convenience methods that automatically use the default locale, but
+ * these may not be as convenient as you imagine. The default locale is appropriate for anything
+ * that involves presenting data to the user. You should use the user's date/time formats, number
+ * formats, rules for conversion to lowercase, and so on. A common mistake is to implicitly use the
+ * default locale when producing output meant to be machine-readable. This tends to work on the
+ * developer's test devices but fail when run on a device whose user is in a less conventional
+ * locale. For example, if you're formatting integers some locales will use non-ASCII decimal
+ * digits. As another example, if you're formatting floating-point numbers some locales will use
+ * {@code ','} as the decimal point. That's correct for human-readable output, but likely to cause
+ * problems if presented to another computer ({@code Double.parseDouble} can't parse such a number,
+ * for example). The best choice for computer-readable output is usually {@code Locale.US}: this
+ * locale is guaranteed to be available on all devices, and the combination of no surprising
+ * behavior and frequent use (especially for computer-computer communication) means that it tends
+ * to be the most efficient choice too.
  *
  * @see ResourceBundle
  */
@@ -68,10 +77,6 @@
 
     private static final long serialVersionUID = 9149081749638150636L;
 
-    // BEGIN android-added
-    private static volatile Locale[] availableLocales;
-    // END android-added
-
     // Initialize a default which is used during static
     // initialization of the default for the platform.
     private static Locale defaultLocale = new Locale();
@@ -79,120 +84,124 @@
     /**
      * Locale constant for en_CA.
      */
-    public static final Locale CANADA = new Locale("en", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale CANADA = new Locale("en", "CA");
 
     /**
      * Locale constant for fr_CA.
      */
-    public static final Locale CANADA_FRENCH = new Locale("fr", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale CANADA_FRENCH = new Locale("fr", "CA");
 
     /**
      * Locale constant for zh_CN.
      */
-    public static final Locale CHINA = new Locale("zh", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale CHINA = new Locale("zh", "CN");
 
     /**
      * Locale constant for zh.
      */
-    public static final Locale CHINESE = new Locale("zh", ""); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale CHINESE = new Locale("zh", "");
 
     /**
      * Locale constant for en.
      */
-    public static final Locale ENGLISH = new Locale("en", ""); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale ENGLISH = new Locale("en", "");
 
     /**
      * Locale constant for fr_FR.
      */
-    public static final Locale FRANCE = new Locale("fr", "FR"); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale FRANCE = new Locale("fr", "FR");
 
     /**
      * Locale constant for fr.
      */
-    public static final Locale FRENCH = new Locale("fr", ""); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale FRENCH = new Locale("fr", "");
 
     /**
      * Locale constant for de.
      */
-    public static final Locale GERMAN = new Locale("de", ""); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale GERMAN = new Locale("de", "");
 
     /**
      * Locale constant for de_DE.
      */
-    public static final Locale GERMANY = new Locale("de", "DE"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale GERMANY = new Locale("de", "DE");
 
     /**
      * Locale constant for it.
      */
-    public static final Locale ITALIAN = new Locale("it", ""); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale ITALIAN = new Locale("it", "");
 
     /**
      * Locale constant for it_IT.
      */
-    public static final Locale ITALY = new Locale("it", "IT"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale ITALY = new Locale("it", "IT");
 
     /**
      * Locale constant for ja_JP.
      */
-    public static final Locale JAPAN = new Locale("ja", "JP"); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale JAPAN = new Locale("ja", "JP");
 
     /**
      * Locale constant for ja.
      */
-    public static final Locale JAPANESE = new Locale("ja", ""); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale JAPANESE = new Locale("ja", "");
 
     /**
      * Locale constant for ko_KR.
      */
-    public static final Locale KOREA = new Locale("ko", "KR"); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale KOREA = new Locale("ko", "KR");
 
     /**
      * Locale constant for ko.
      */
-    public static final Locale KOREAN = new Locale("ko", ""); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale KOREAN = new Locale("ko", "");
 
     /**
      * Locale constant for zh_CN.
      */
-    public static final Locale PRC = new Locale("zh", "CN"); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale PRC = new Locale("zh", "CN");
+
+    /**
+     * Locale constant for the root locale. The root locale has an empty language,
+     * country, and variant.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final Locale ROOT = new Locale("", "", "");
 
     /**
      * Locale constant for zh_CN.
      */
-    public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN"); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN");
 
     /**
      * Locale constant for zh_TW.
      */
-    public static final Locale TAIWAN = new Locale("zh", "TW"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale TAIWAN = new Locale("zh", "TW");
 
     /**
      * Locale constant for zh_TW.
      */
-    public static final Locale TRADITIONAL_CHINESE = new Locale("zh", "TW"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale TRADITIONAL_CHINESE = new Locale("zh", "TW");
 
     /**
      * Locale constant for en_GB.
      */
-    public static final Locale UK = new Locale("en", "GB"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final Locale UK = new Locale("en", "GB");
 
     /**
      * Locale constant for en_US.
      */
-    public static final Locale US = new Locale("en", "US"); //$NON-NLS-1$//$NON-NLS-2$
+    public static final Locale US = new Locale("en", "US");
 
     private static final PropertyPermission setLocalePermission = new PropertyPermission(
-            "user.language", "write"); //$NON-NLS-1$//$NON-NLS-2$
+            "user.language", "write");
 
     static {
-        String language = AccessController
-                .doPrivileged(new PriviAction<String>("user.language", "en")); //$NON-NLS-1$ //$NON-NLS-2$
-        // BEGIN android-changed
-        String region = AccessController.doPrivileged(new PriviAction<String>(
-                "user.region", "US")); //$NON-NLS-1$ //$NON-NLS-2$
-        // END android-changed
-        String variant = AccessController.doPrivileged(new PriviAction<String>(
-                "user.variant", "")); //$NON-NLS-1$ //$NON-NLS-2$
+        String language = AccessController.doPrivileged(new PriviAction<String>("user.language", "en"));
+        String region = AccessController.doPrivileged(new PriviAction<String>("user.region", "US"));
+        String variant = AccessController.doPrivileged(new PriviAction<String>("user.variant", ""));
         defaultLocale = new Locale(language, region, variant);
     }
 
@@ -201,61 +210,39 @@
     private transient String variantCode;
     private transient String cachedToStringResult;
 
-    // BEGIN android-removed
-    // private transient ULocale uLocale;
-    // END android-removed
-
-	/**
-	 * Constructs a default which is used during static initialization of the
-	 * default for the platform.
-	 */
-	private Locale() {
-		languageCode = "en"; //$NON-NLS-1$
-		countryCode = "US"; //$NON-NLS-1$
-		variantCode = ""; //$NON-NLS-1$
-	}
+    /**
+     * Constructs a default which is used during static initialization of the
+     * default for the platform.
+     */
+    private Locale() {
+        languageCode = "en";
+        countryCode = "US";
+        variantCode = "";
+    }
 
     /**
      * Constructs a new {@code Locale} using the specified language.
-     *
-     * @param language
-     *            the language this {@code Locale} represents.
      */
     public Locale(String language) {
-        this(language, "", ""); //$NON-NLS-1$//$NON-NLS-2$
+        this(language, "", "");
     }
 
     /**
      * Constructs a new {@code Locale} using the specified language and country codes.
-     *
-     * @param language
-     *            the language this {@code Locale} represents.
-     * @param country
-     *            the country this {@code Locale} represents.
      */
     public Locale(String language, String country) {
-        this(language, country, ""); //$NON-NLS-1$
+        this(language, country, "");
     }
 
     /**
-     * Constructs a new {@code Locale} using the specified language, country, and
-     * variant codes.
-     *
-     * @param language
-     *            the language this {@code Locale} represents.
-     * @param country
-     *            the country this {@code Locale} represents.
-     * @param variant
-     *            the variant this {@code Locale} represents.
-     * @throws NullPointerException
-     *             if {@code language}, {@code country}, or
-     *             {@code variant} is {@code null}.
+     * Constructs a new {@code Locale} using the specified language, country,
+     * and variant codes.
      */
     public Locale(String language, String country, String variant) {
         if (language == null || country == null || variant == null) {
             throw new NullPointerException();
         }
-        if(language.length() == 0 && country.length() == 0){
+        if(language.isEmpty() && country.isEmpty()){
             languageCode = "";
             countryCode = "";
             variantCode = variant;
@@ -268,12 +255,12 @@
         // END android-changed
         // Map new language codes to the obsolete language
         // codes so the correct resource bundles will be used.
-        if (languageCode.equals("he")) {//$NON-NLS-1$
-            languageCode = "iw"; //$NON-NLS-1$
-        } else if (languageCode.equals("id")) {//$NON-NLS-1$
-            languageCode = "in"; //$NON-NLS-1$
-        } else if (languageCode.equals("yi")) {//$NON-NLS-1$
-            languageCode = "ji"; //$NON-NLS-1$
+        if (languageCode.equals("he")) {
+            languageCode = "iw";
+        } else if (languageCode.equals("id")) {
+            languageCode = "in";
+        } else if (languageCode.equals("yi")) {
+            languageCode = "ji";
         }
 
         // countryCode is defined in ASCII character set
@@ -286,35 +273,19 @@
         variantCode = variant;
     }
 
-    /**
-     * Returns a new {@code Locale} with the same language, country and variant codes as
-     * this {@code Locale}.
-     *
-     * @return a shallow copy of this {@code Locale}.
-     * @see java.lang.Cloneable
-     */
-    @Override
-    public Object clone() {
+    @Override public Object clone() {
         try {
             return super.clone();
         } catch (CloneNotSupportedException e) {
-            throw new AssertionError(e); // android-changed
+            throw new AssertionError(e);
         }
     }
 
     /**
-     * Compares the specified object to this {@code Locale} and returns whether they are
-     * equal. The object must be an instance of {@code Locale} and have the same
-     * language, country and variant.
-     *
-     * @param object
-     *            the object to compare with this object.
-     * @return {@code true} if the specified object is equal to this {@code Locale},
-     *         {@code false} otherwise.
-     * @see #hashCode
+     * Returns true if {@code object} is a locale with the same language,
+     * country and variant.
      */
-    @Override
-    public boolean equals(Object object) {
+    @Override public boolean equals(Object object) {
         if (object == this) {
             return true;
         }
@@ -327,180 +298,131 @@
         return false;
     }
 
-    // BEGIN android-added
-    static Locale[] find() {
-        String[] locales = Resources.getAvailableLocales();
-        ArrayList<Locale> temp = new ArrayList<Locale>();
-        for (int i = 0; i < locales.length; i++) {
-            String s = locales[i];
-            int first = s.indexOf('_');
-            int second = s.indexOf('_', first + 1);
-
-            if (first == -1) {
-                // Language only
-                temp.add(new Locale(s));
-            } else if (second == -1) {
-                // Language and country
-                temp.add(new Locale(s.substring(0, first), s.substring(first + 1)));
-            } else {
-                // Language and country and variant
-                temp.add(new Locale(s.substring(0, first), s.substring(first + 1, second), s.substring(second + 1)));
-            }
-        }
-        Locale[] result = new Locale[temp.size()];
-        return temp.toArray(result);
-    }
-    // END android-added
-
     /**
-     * Gets the list of installed {@code Locale}s. At least a {@code Locale} that is equal to
-     * {@code Locale.US} must be contained in this array.
+     * Returns the system's installed locales. This array always includes {@code
+     * Locale.US}, and usually several others. Most locale-sensitive classes
+     * offer their own {@code getAvailableLocales} method, which should be
+     * preferred over this general purpose method.
      * 
-     * @return an array of {@code Locale}s.
+     * @see java.text.BreakIterator#getAvailableLocales()
+     * @see java.text.Collator#getAvailableLocales()
+     * @see java.text.DateFormat#getAvailableLocales()
+     * @see java.text.DateFormatSymbols#getAvailableLocales()
+     * @see java.text.DecimalFormatSymbols#getAvailableLocales()
+     * @see java.text.NumberFormat#getAvailableLocales()
+     * @see java.util.Calendar#getAvailableLocales()
      */
     public static Locale[] getAvailableLocales() {
-        // BEGIN android-changed
-        // ULocale[] ulocales =  ULocale.getAvailableLocales();
-        // Locale[] locales = new Locale[ulocales.length];
-        // for (int i = 0; i < locales.length; i++) {
-        //     locales[i] = ulocales[i].toLocale();
-        // }
-        // return locales;
-        if (availableLocales == null) {
-            availableLocales = find();
-        }
-        return availableLocales.clone();
-        // END android-changed
+        return ICU.getAvailableLocales();
     }
 
     /**
-     * Gets the country code for this {@code Locale} or an empty string of no country
-     * was set.
-     *
-     * @return a country code.
+     * Returns the country code for this locale, or {@code ""} if this locale
+     * doesn't correspond to a specific country.
      */
     public String getCountry() {
         return countryCode;
     }
 
     /**
-     * Gets the default {@code Locale}.
+     * Returns the user's preferred locale. This may have been overridden for
+     * this process with {@link #setDefault}.
      *
-     * @return the default {@code Locale}.
+     * <p>Since the user's locale changes dynamically, avoid caching this value.
+     * Instead, use this method to look it up for each use.
      */
     public static Locale getDefault() {
         return defaultLocale;
     }
 
     /**
-     * Gets the full country name in the default {@code Locale} for the country code of
-     * this {@code Locale}. If there is no matching country name, the country code is
-     * returned.
-     *
-     * @return a country name.
+     * Equivalent to {@code getDisplayCountry(Locale.getDefault())}.
      */
     public final String getDisplayCountry() {
         return getDisplayCountry(getDefault());
     }
 
     /**
-     * Gets the full country name in the specified {@code Locale} for the country code
-     * of this {@code Locale}. If there is no matching country name, the country code is
-     * returned.
-     *
-     * @param locale
-     *            the {@code Locale} for which the display name is retrieved.
-     * @return a country name.
+     * 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
+     * country.
      */
     public String getDisplayCountry(Locale locale) {
-        // BEGIN android-changed
-        if (countryCode.length() == 0) {
-            return countryCode;
+        if (countryCode.isEmpty()) {
+            return "";
         }
-        String result = Resources.getDisplayCountryNative(toString(), locale.toString());
+        String result = ICU.getDisplayCountryNative(toString(), locale.toString());
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = Resources.getDisplayCountryNative(toString(), Locale.getDefault().toString());
+            result = ICU.getDisplayCountryNative(toString(), Locale.getDefault().toString());
         }
         return result;
-        // END android-changed
     }
 
     /**
-     * Gets the full language name in the default {@code Locale} for the language code
-     * of this {@code Locale}. If there is no matching language name, the language code
-     * is returned.
-     *
-     * @return a language name.
+     * Equivalent to {@code getDisplayLanguage(Locale.getDefault())}.
      */
     public final String getDisplayLanguage() {
         return getDisplayLanguage(getDefault());
     }
 
     /**
-     * Gets the full language name in the specified {@code Locale} for the language code
-     * of this {@code Locale}. If there is no matching language name, the language code
-     * is returned.
-     *
-     * @param locale
-     *            the {@code Locale} for which the display name is retrieved.
-     * @return a language name.
+     * Returns the name of this locale's language, localized to {@code locale}.
+     * If the language name is unknown, the language code is returned.
      */
     public String getDisplayLanguage(Locale locale) {
-        // BEGIN android-changed
-        if (languageCode.length() == 0) {
-            return languageCode;
+        if (languageCode.isEmpty()) {
+            return "";
         }
-        String result = Resources.getDisplayLanguageNative(toString(), locale.toString());
+        String result = ICU.getDisplayLanguageNative(toString(), locale.toString());
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = Resources.getDisplayLanguageNative(toString(), Locale.getDefault().toString());
+            result = ICU.getDisplayLanguageNative(toString(), Locale.getDefault().toString());
         }
         return result;
-        // END android-changed
     }
 
     /**
-     * Gets the full language, country, and variant names in the default {@code Locale}
-     * for the codes of this {@code Locale}.
-     *
-     * @return a {@code Locale} name.
+     * Equivalent to {@code getDisplayName(Locale.getDefault())}.
      */
     public final String getDisplayName() {
         return getDisplayName(getDefault());
     }
 
     /**
-     * Gets the full language, country, and variant names in the specified
-     * Locale for the codes of this {@code Locale}.
-     *
-     * @param locale
-     *            the {@code Locale} for which the display name is retrieved.
-     * @return a {@code Locale} name.
+     * Returns this locale's language name, country name, and variant, localized
+     * to {@code locale}. The exact output form depends on whether this locale
+     * corresponds to a specific language, country and variant, such as:
+     * {@code English}, {@code English (United States)}, {@code English (United
+     * States,Computer)}, {@code anglais (&#x00c9;tats-Unis)}, {@code anglais
+     * (&#x00c9;tats-Unis,informatique)}.
      */
     public String getDisplayName(Locale locale) {
         int count = 0;
         StringBuilder buffer = new StringBuilder();
-        if (languageCode.length() > 0) {
-            buffer.append(getDisplayLanguage(locale));
-            count++;
+        if (!languageCode.isEmpty()) {
+            String displayLanguage = getDisplayLanguage(locale);
+            buffer.append(displayLanguage.isEmpty() ? languageCode : displayLanguage);
+            ++count;
         }
-        if (countryCode.length() > 0) {
+        if (!countryCode.isEmpty()) {
             if (count == 1) {
-                buffer.append(" ("); //$NON-NLS-1$
+                buffer.append(" (");
             }
-            buffer.append(getDisplayCountry(locale));
-            count++;
+            String displayCountry = getDisplayCountry(locale);
+            buffer.append(displayCountry.isEmpty() ? countryCode : displayCountry);
+            ++count;
         }
-        if (variantCode.length() > 0) {
+        if (!variantCode.isEmpty()) {
             if (count == 1) {
-                buffer.append(" ("); //$NON-NLS-1$
+                buffer.append(" (");
             } else if (count == 2) {
-                buffer.append(","); //$NON-NLS-1$
+                buffer.append(",");
             }
-            buffer.append(getDisplayVariant(locale));
-            count++;
+            String displayVariant = getDisplayVariant(locale);
+            buffer.append(displayVariant.isEmpty() ? variantCode : displayVariant);
+            ++count;
         }
         if (count > 1) {
-            buffer.append(")"); //$NON-NLS-1$
+            buffer.append(")");
         }
         return buffer.toString();
     }
@@ -526,16 +448,14 @@
      * @return a variant name.
      */
     public String getDisplayVariant(Locale locale) {
-        // BEGIN android-changed
         if (variantCode.length() == 0) {
             return variantCode;
         }
-        String result = Resources.getDisplayVariantNative(toString(), locale.toString());
+        String result = ICU.getDisplayVariantNative(toString(), locale.toString());
         if (result == null) { // TODO: do we need to do this, or does ICU do it for us?
-            result = Resources.getDisplayVariantNative(toString(), Locale.getDefault().toString());
+            result = ICU.getDisplayVariantNative(toString(), Locale.getDefault().toString());
         }
         return result;
-        // END android-changed
     }
 
     /**
@@ -547,12 +467,10 @@
      *                if there is no matching three letter ISO country code.
      */
     public String getISO3Country() throws MissingResourceException {
-        // BEGIN android-changed
         if (countryCode.length() == 0) {
             return countryCode;
         }
-        return Resources.getISO3CountryNative(toString());
-        // END android-changed
+        return ICU.getISO3CountryNative(toString());
     }
 
     /**
@@ -564,12 +482,10 @@
      *                if there is no matching three letter ISO language code.
      */
     public String getISO3Language() throws MissingResourceException {
-        // BEGIN android-changed
         if (languageCode.length() == 0) {
             return languageCode;
         }
-        return Resources.getISO3LanguageNative(toString());
-        // END android-changed
+        return ICU.getISO3LanguageNative(toString());
     }
 
     /**
@@ -579,9 +495,7 @@
      * @return an array of strings.
      */
     public static String[] getISOCountries() {
-        // BEGIN android-changed
-        return Resources.getISOCountries();
-        // END android-changed
+        return ICU.getISOCountries();
     }
 
     /**
@@ -591,9 +505,7 @@
      * @return an array of strings.
      */
     public static String[] getISOLanguages() {
-        // BEGIN android-changed
-        return Resources.getISOLanguages();
-        // END android-changed
+        return ICU.getISOLanguages();
     }
 
     /**
@@ -630,24 +542,24 @@
     }
 
     /**
-     * Sets the default {@code Locale} to the specified {@code Locale}.
-     *
-     * @param locale
-     *            the new default {@code Locale}.
-     * @throws SecurityException
-     *                if there is a {@code SecurityManager} in place which does not allow this
-     *                operation.
+     * Overrides the default locale. This does not affect system configuration,
+     * and attempts to override the system-provided default locale may
+     * themselves be overridden by actual changes to the system configuration.
+     * Code that calls this method is usually incorrect, and should be fixed by
+     * passing the appropriate locale to each locale-sensitive method that's
+     * called.
      */
     public synchronized static void setDefault(Locale locale) {
-        if (locale != null) {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkPermission(setLocalePermission);
-            }
-            defaultLocale = locale;
-        } else {
+        if (locale == null) {
             throw new NullPointerException();
         }
+
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(setLocalePermission);
+        }
+
+        defaultLocale = locale;
     }
 
     /**
@@ -692,25 +604,24 @@
     }
 
     private static final ObjectStreamField[] serialPersistentFields = {
-            new ObjectStreamField("country", String.class), //$NON-NLS-1$
-            new ObjectStreamField("hashcode", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("language", String.class), //$NON-NLS-1$
-            new ObjectStreamField("variant", String.class) }; //$NON-NLS-1$
+            new ObjectStreamField("country", String.class),
+            new ObjectStreamField("hashcode", Integer.TYPE),
+            new ObjectStreamField("language", String.class),
+            new ObjectStreamField("variant", String.class) };
 
     private void writeObject(ObjectOutputStream stream) throws IOException {
         ObjectOutputStream.PutField fields = stream.putFields();
-        fields.put("country", countryCode); //$NON-NLS-1$
-        fields.put("hashcode", -1); //$NON-NLS-1$
-        fields.put("language", languageCode); //$NON-NLS-1$
-        fields.put("variant", variantCode); //$NON-NLS-1$
+        fields.put("country", countryCode);
+        fields.put("hashcode", -1);
+        fields.put("language", languageCode);
+        fields.put("variant", variantCode);
         stream.writeFields();
     }
 
-    private void readObject(ObjectInputStream stream) throws IOException,
-            ClassNotFoundException {
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         ObjectInputStream.GetField fields = stream.readFields();
-        countryCode = (String) fields.get("country", ""); //$NON-NLS-1$//$NON-NLS-2$
-        languageCode = (String) fields.get("language", ""); //$NON-NLS-1$//$NON-NLS-2$
-        variantCode = (String) fields.get("variant", ""); //$NON-NLS-1$//$NON-NLS-2$
+        countryCode = (String) fields.get("country", "");
+        languageCode = (String) fields.get("language", "");
+        variantCode = (String) fields.get("variant", "");
     }
 }
diff --git a/luni/src/main/java/java/util/NavigableMap.java b/luni/src/main/java/java/util/NavigableMap.java
new file mode 100644
index 0000000..a87a8c0
--- /dev/null
+++ b/luni/src/main/java/java/util/NavigableMap.java
@@ -0,0 +1,262 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * NavigableMap is a SortedMap with navigation methods answering the closest
+ * matches for specified item.
+ *
+ * @param <K>
+ *            the type of key
+ * @param <V>
+ *            the type of value
+ * @since 1.6
+ */
+public interface NavigableMap<K, V> extends SortedMap<K, V> {
+    /**
+     * Returns the entry with the smallest key, or null if the map is empty.
+     *
+     * @return the entry with the smallest key, or null if the map is empty
+     */
+    Map.Entry<K, V> firstEntry();
+
+    /**
+     * Returns the entry with the biggest key, or null if the map is empty.
+     *
+     * @return the entry with the biggest key, or null if the map is empty
+     */
+    Map.Entry<K, V> lastEntry();
+
+    /**
+     * Deletes and returns the entry with the smallest key, or null if the map
+     * is empty.
+     *
+     * @return the entry with the smallest key, or null if the map is empty
+     */
+    Map.Entry<K, V> pollFirstEntry();
+
+    /**
+     * Deletes and returns the entry with the biggest key, or null if the map is
+     * empty.
+     *
+     * @return the entry with the biggest key, or null if the map is empty
+     */
+    Map.Entry<K, V> pollLastEntry();
+
+    /**
+     * Returns an entry related with the smallest key greater than or equal to
+     * the specified key, or null if no such key.
+     *
+     * @param key
+     *            the key
+     * @return the entry, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    Map.Entry<K, V> ceilingEntry(K key);
+
+    /**
+     * Returns the smallest key greater than or equal to the specified key, or
+     * null if no such key.
+     *
+     * @param key
+     *            the key
+     * @return the smallest key greater than or equal to key, or null if no such
+     *         key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    K ceilingKey(K key);
+
+    /**
+     * Returns an entry related with the smallest key greater than the specified
+     * key, or null if no such key.
+     *
+     * @param key
+     *            the key
+     * @return the entry, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    Map.Entry<K, V> higherEntry(K key);
+
+    /**
+     * Returns the smallest key greater than the specified key, or null if no
+     * such key.
+     *
+     * @param key
+     *            the key
+     * @return the smallest key greater than key, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    K higherKey(K key);
+
+    /**
+     * Returns an entry related with the biggest key less than or equal to the
+     * specified key, or null if no such key.
+     *
+     * @param key
+     *            the key
+     * @return the entry, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    Map.Entry<K, V> floorEntry(K key);
+
+    /**
+     * Returns the biggest key less than or equal to the specified key, or null
+     * if no such key.
+     *
+     * @param key
+     *            the key
+     * @return the biggest key less than or equal to key, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    K floorKey(K key);
+
+    /**
+     * Returns an entry related with the biggest key less than the specified
+     * key, or null if no such key.
+     *
+     * @param key
+     *            the key
+     * @return the entry, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    Map.Entry<K, V> lowerEntry(K key);
+
+    /**
+     * Returns the biggest key less than the specified key, or null if no such
+     * key.
+     *
+     * @param key
+     *            the key
+     * @return the biggest key less than key, or null if no such key
+     * @throws ClassCastException
+     *             if the key cannot be compared with the keys in the map
+     * @throws NullPointerException
+     *             if the key is null and the map can not contain null key
+     */
+    K lowerKey(K key);
+
+    /**
+     * Returns a NavigableSet view of the keys in ascending order.
+     *
+     * @return the navigable set view
+     */
+    NavigableSet<K> navigableKeySet();
+
+    /**
+     * Returns a reverse order view of the map.
+     *
+     * @return the reverse order view of the map
+     */
+    NavigableMap<K, V> descendingMap();
+
+    /**
+     * Returns a NavigableSet view of the keys in descending order.
+     *
+     * @return the navigable set view
+     */
+    NavigableSet<K> descendingKeySet();
+
+    /**
+     * Returns a view of part of the map whose keys is from startKey to endKey.
+     *
+     * @param startKey
+     *            the start key
+     * @param startInclusive
+     *            true if the start key is in the returned map
+     * @param endKey
+     *            the end key
+     * @param endInclusive
+     *            true if the end key is in the returned map
+     * @return the sub-map view
+     *
+     * @exception ClassCastException
+     *                when the class of the start or end key is inappropriate
+     *                for this SubMap
+     * @exception NullPointerException
+     *                when the start or end key is null and this SortedMap does
+     *                not support null keys
+     * @exception IllegalArgumentException
+     *                when the start key is greater than the end key
+     */
+    NavigableMap<K, V> subMap(K startKey, boolean startInclusive, K endKey,
+            boolean endInclusive);
+
+    /**
+     * Returns a view of the head of the map whose keys are smaller than (or
+     * equal to, depends on inclusive argument) endKey.
+     *
+     * @param endKey
+     *            the end key
+     * @param inclusive
+     *            true if the end key is in the returned map
+     * @return the head-map view
+     *
+     * @exception ClassCastException
+     *                when the class of the end key is inappropriate for this
+     *                SubMap
+     * @exception NullPointerException
+     *                when the end key is null and this SortedMap does not
+     *                support null keys
+     * @exception IllegalArgumentException
+     *                when the map is range-limited and end key is out of the
+     *                range of the map
+     */
+    NavigableMap<K, V> headMap(K endKey, boolean inclusive);
+
+    /**
+     * Returns a view of the tail of the map whose keys are bigger than (or
+     * equal to, depends on inclusive argument) startKey.
+     *
+     * @param startKey
+     *            the start key
+     * @param inclusive
+     *            true if the start key is in the returned map
+     * @return the tail-map view
+     *
+     * @exception ClassCastException
+     *                when the class of the start key is inappropriate for this
+     *                SubMap
+     * @exception NullPointerException
+     *                when the start key is null and this SortedMap does not
+     *                support null keys
+     * @exception IllegalArgumentException
+     *                when the map is range-limited and start key is out of the
+     *                range of the map
+     */
+    NavigableMap<K, V> tailMap(K startKey, boolean inclusive);
+}
\ No newline at end of file
diff --git a/luni/src/main/java/java/util/NavigableSet.java b/luni/src/main/java/java/util/NavigableSet.java
new file mode 100644
index 0000000..ae94b77
--- /dev/null
+++ b/luni/src/main/java/java/util/NavigableSet.java
@@ -0,0 +1,192 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * NavigableSet is a SortedSet with navigation methods answering the closest
+ * matches for specified item.
+ *
+ * @param <E>
+ *            the type of element
+ * @since 1.6
+ */
+public interface NavigableSet<E> extends SortedSet<E> {
+
+    /**
+     * Deletes and returns the smallest element, or null if the set is empty.
+     *
+     * @return the smallest element, or null if the set is empty
+     */
+    E pollFirst();
+
+    /**
+     * Deletes and returns the biggest element, or null if the set is empty.
+     *
+     * @return the biggest element, or null if the set is empty
+     */
+    E pollLast();
+
+    /**
+     * Returns the smallest element bigger than the specified one, or null if no
+     * such element.
+     *
+     * @param e
+     *            the specified element
+     * @return the smallest element bigger than the specified one, or null if no
+     *         such element
+     * @throws ClassCastException
+     *             if the element cannot be compared with the ones in the set
+     * @throws NullPointerException
+     *             if the element is null and the set can not contain null
+     */
+    E higher(E e);
+
+    /**
+     * Returns the smallest element bigger than or equal to the specified one,
+     * or null if no such element.
+     *
+     * @param e
+     *            the specified element
+     * @return the smallest element bigger than or equal to the specified one,
+     *         or null if no such element
+     * @throws ClassCastException
+     *             if the element cannot be compared with the ones in the set
+     * @throws NullPointerException
+     *             if the element is null and the set can not contain null
+     */
+    E ceiling(E e);
+
+    /**
+     * Returns the biggest element less than the specified one, or null if no
+     * such element.
+     *
+     * @param e
+     *            the specified element
+     * @return the biggest element less than the specified one, or null if no
+     *         such element
+     * @throws ClassCastException
+     *             if the element cannot be compared with the ones in the set
+     * @throws NullPointerException
+     *             if the element is null and the set can not contain null
+     */
+    E lower(E e);
+
+    /**
+     * Returns the biggest element less than or equal to the specified one, or
+     * null if no such element.
+     *
+     * @param e
+     *            the specified element
+     * @return the biggest element less than or equal to the specified one, or
+     *         null if no such element
+     * @throws ClassCastException
+     *             if the element cannot be compared with the ones in the set
+     * @throws NullPointerException
+     *             if the element is null and the set can not contain null
+     */
+    E floor(E e);
+
+    /**
+     * Returns a descending iterator of this set.
+     *
+     * @return the descending iterator
+     */
+    Iterator<E> descendingIterator();
+
+    /**
+     * Returns a reverse order view of this set.
+     *
+     * @return the reverse order view
+     */
+    NavigableSet<E> descendingSet();
+
+    /**
+     * Returns a NavigableSet of the specified portion of this set which
+     * contains elements greater (or equal to, depends on startInclusive) the
+     * start element but less than (or equal to, depends on endInclusive) the
+     * end element. The returned NavigableSet is backed by this set so changes
+     * to one are reflected by the other.
+     *
+     * @param start
+     *            the start element
+     * @param startInclusive
+     *            true if the start element is in the returned set
+     * @param end
+     *            the end element
+     * @param endInclusive
+     *            true if the end element is in the returned set
+     * @return the subset
+     *
+     * @throws ClassCastException
+     *             when the start or end object cannot be compared with the
+     *             elements in this set
+     * @throws NullPointerException
+     *             when the start or end object is null and the set cannot
+     *             contain null
+     * @throws IllegalArgumentException
+     *             when the start is bigger than end; or start or end is out of
+     *             range and the set has a range
+     */
+    NavigableSet<E> subSet(E start, boolean startInclusive, E end,
+            boolean endInclusive);
+
+    /**
+     * Returns a NavigableSet of the specified portion of this set which
+     * contains elements less than (or equal to, depends on endInclusive) the
+     * end element. The returned NavigableSet is backed by this set so changes
+     * to one are reflected by the other.
+     *
+     * @param end
+     *            the end element
+     * @param endInclusive
+     *            true if the end element is in the returned set
+     * @return the subset
+     *
+     * @throws ClassCastException
+     *             when the end object cannot be compared with the elements in
+     *             this set
+     * @throws NullPointerException
+     *             when the end object is null and the set cannot contain handle
+     *             null
+     * @throws IllegalArgumentException
+     *             when end is out of range and the set has a range
+     */
+    NavigableSet<E> headSet(E end, boolean endInclusive);
+
+    /**
+     * Returns a NavigableSet of the specified portion of this set which
+     * contains elements greater (or equal to, depends on startInclusive) the
+     * start element. The returned NavigableSet is backed by this set so changes
+     * to one are reflected by the other.
+     *
+     * @param start
+     *            the start element
+     * @param startInclusive
+     *            true if the start element is in the returned set
+     * @return the subset
+     *
+     * @throws ClassCastException
+     *             when the start object cannot be compared with the elements in
+     *             this set
+     * @throws NullPointerException
+     *             when the start object is null and the set cannot contain null
+     * @throws IllegalArgumentException
+     *             when start is out of range and the set has a range
+     */
+    NavigableSet<E> tailSet(E start, boolean startInclusive);
+}
\ No newline at end of file
diff --git a/luni/src/main/java/java/util/NoSuchElementException.java b/luni/src/main/java/java/util/NoSuchElementException.java
index 5378e1d..4334f86 100644
--- a/luni/src/main/java/java/util/NoSuchElementException.java
+++ b/luni/src/main/java/java/util/NoSuchElementException.java
@@ -25,7 +25,6 @@
  * 
  * @see Enumeration
  * @see java.lang.RuntimeException
- * @since Android 1.0
  */
 public class NoSuchElementException extends RuntimeException {
 
diff --git a/luni/src/main/java/java/util/Properties.java b/luni/src/main/java/java/util/Properties.java
index b0f3b9d..f5bd8a7 100644
--- a/luni/src/main/java/java/util/Properties.java
+++ b/luni/src/main/java/java/util/Properties.java
@@ -17,40 +17,36 @@
 
 package java.util;
 
+import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.BufferedInputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.io.Reader;
 import java.io.StringReader;
+import java.io.Writer;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException;
 import java.security.AccessController;
-
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
-
+import org.apache.harmony.luni.util.PriviAction;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-// BEGIN android-added
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-// END android-added
-
-import org.apache.harmony.luni.internal.nls.Messages;
-import org.apache.harmony.luni.util.PriviAction;
-
 /**
  * A {@code Properties} object is a {@code Hashtable} where the keys and values
  * must be {@code String}s. Each property can have a default
@@ -106,7 +102,7 @@
     private void dumpString(StringBuilder buffer, String string, boolean key) {
         int i = 0;
         if (!key && i < string.length() && string.charAt(i) == ' ') {
-            buffer.append("\\ "); //$NON-NLS-1$
+            buffer.append("\\ ");
             i++;
         }
 
@@ -114,16 +110,16 @@
             char ch = string.charAt(i);
             switch (ch) {
             case '\t':
-                buffer.append("\\t"); //$NON-NLS-1$
+                buffer.append("\\t");
                 break;
             case '\n':
-                buffer.append("\\n"); //$NON-NLS-1$
+                buffer.append("\\n");
                 break;
             case '\f':
-                buffer.append("\\f"); //$NON-NLS-1$
+                buffer.append("\\f");
                 break;
             case '\r':
-                buffer.append("\\r"); //$NON-NLS-1$
+                buffer.append("\\r");
                 break;
             default:
                 if ("\\#!=:".indexOf(ch) >= 0 || (key && ch == ' ')) {
@@ -133,9 +129,9 @@
                     buffer.append(ch);
                 } else {
                     String hex = Integer.toHexString(ch);
-                    buffer.append("\\u"); //$NON-NLS-1$
+                    buffer.append("\\u");
                     for (int j = 0; j < 4 - hex.length(); j++) {
-                        buffer.append("0"); //$NON-NLS-1$
+                        buffer.append("0");
                     }
                     buffer.append(hex);
                 }
@@ -212,7 +208,7 @@
             }
             if (property.length() > 40) {
                 buffer.append(property.substring(0, 37));
-                buffer.append("..."); //$NON-NLS-1$
+                buffer.append("...");
             } else {
                 buffer.append(property);
             }
@@ -248,7 +244,7 @@
             }
             if (property.length() > 40) {
                 buffer.append(property.substring(0, 37));
-                buffer.append("..."); //$NON-NLS-1$
+                buffer.append("...");
             } else {
                 buffer.append(property);
             }
@@ -259,33 +255,45 @@
 
     /**
      * Loads properties from the specified {@code InputStream}. The encoding is
-     * ISO8859-1. The {@code Properties} file is interpreted according to the
-     * following rules:
+     * ISO8859-1.
+     * @param in the {@code InputStream}
+     * @throws IOException
+     */
+    public synchronized void load(InputStream in) throws IOException {
+        if (in == null) {
+            throw new NullPointerException();
+        }
+        load(new InputStreamReader(in, "ISO8859_1"));
+    }
+
+    /**
+     * Loads properties from the specified {@code Reader}.
+     * The properties file is interpreted according to the following rules:
      * <ul>
      * <li>Empty lines are ignored.</li>
      * <li>Lines starting with either a "#" or a "!" are comment lines and are
      * ignored.</li>
      * <li>A backslash at the end of the line escapes the following newline
-     * character ("\r", "\n", "\r\n"). If there's a whitespace after the
+     * character ("\r", "\n", "\r\n"). If there's whitespace after the
      * backslash it will just escape that whitespace instead of concatenating
      * the lines. This does not apply to comment lines.</li>
      * <li>A property line consists of the key, the space between the key and
      * the value, and the value. The key goes up to the first whitespace, "=" or
      * ":" that is not escaped. The space between the key and the value contains
-     * either one whitespace, one "=" or one ":" and any number of additional
-     * whitespaces before and after that character. The value starts with the
+     * either one whitespace, one "=" or one ":" and any amount of additional
+     * whitespace before and after that character. The value starts with the
      * first character after the space between the key and the value.</li>
      * <li>Following escape sequences are recognized: "\ ", "\\", "\r", "\n",
      * "\!", "\#", "\t", "\b", "\f", and "&#92;uXXXX" (unicode character).</li>
      * </ul>
      *
-     * @param in
-     *            the {@code InputStream}.
+     * @param in the {@code Reader}
      * @throws IOException
-     *             if error occurs during reading from the {@code InputStream}.
+     * @since 1.6
+     * @hide
      */
     @SuppressWarnings("fallthrough")
-    public synchronized void load(InputStream in) throws IOException {
+    public synchronized void load(Reader in) throws IOException {
         if (in == null) {
             throw new NullPointerException();
         }
@@ -294,27 +302,14 @@
         int offset = 0, keyLength = -1, intVal;
         boolean firstChar = true;
 
-        // BEGIN android-changed
-        BufferedInputStream bis = new BufferedInputStream(in, 8192);
-        // END android-changed
+        BufferedReader br = new BufferedReader(in);
 
         while (true) {
-            intVal = bis.read();
+            intVal = br.read();
             if (intVal == -1) {
-                // if mode is UNICODE but has less than 4 hex digits, should
-                // throw an IllegalArgumentException
-                // luni.08=Invalid Unicode sequence: expected format \\uxxxx
-                if (mode == UNICODE && count < 4) {
-                    throw new IllegalArgumentException(Messages.getString("luni.08")); //$NON-NLS-1$
-                }
-                // if mode is SLASH and no data is read, should append '\u0000'
-                // to buf
-                if (mode == SLASH) {
-                    buf[offset++] = '\u0000';
-                }
                 break;
             }
-            nextChar = (char) (intVal & 0xff);
+            nextChar = (char) intVal;
 
             if (offset == buf.length) {
                 char[] newBuf = new char[buf.length * 2];
@@ -329,8 +324,7 @@
                         continue;
                     }
                 } else if (count <= 4) {
-                    // luni.09=Invalid Unicode sequence: illegal character
-                    throw new IllegalArgumentException(Messages.getString("luni.09")); //$NON-NLS-1$
+                    throw new IllegalArgumentException("Invalid Unicode sequence: illegal character");
                 }
                 mode = NONE;
                 buf[offset++] = (char) unicode;
@@ -373,11 +367,10 @@
                 case '!':
                     if (firstChar) {
                         while (true) {
-                            intVal = bis.read();
+                            intVal = br.read();
                             if (intVal == -1) {
                                 break;
                             }
-                            // & 0xff not required
                             nextChar = (char) intVal;
                             if (nextChar == '\r' || nextChar == '\n') {
                                 break;
@@ -445,39 +438,67 @@
             }
             buf[offset++] = nextChar;
         }
+        if (mode == UNICODE && count <= 4) {
+            throw new IllegalArgumentException("Invalid Unicode sequence: expected format \\uxxxx");
+        }
         if (keyLength == -1 && offset > 0) {
             keyLength = offset;
         }
         if (keyLength >= 0) {
             String temp = new String(buf, 0, offset);
-            put(temp.substring(0, keyLength), temp.substring(keyLength));
+            String key = temp.substring(0, keyLength);
+            String value = temp.substring(keyLength);
+            if (mode == SLASH) {
+                value += "\u0000";
+            }
+            put(key, value);
         }
     }
 
     /**
-     * Returns all of the property names that this {@code Properties} object
-     * contains.
-     *
-     * @return an {@code Enumeration} containing the names of all properties
-     *         that this {@code Properties} object contains.
+     * Returns all of the property names (keys) in this {@code Properties} object.
      */
     public Enumeration<?> propertyNames() {
-        if (defaults == null) {
-            return keys();
-        }
+        Hashtable<Object, Object> selected = new Hashtable<Object, Object>();
+        selectProperties(selected, false);
+        return selected.keys();
+    }
 
-        Hashtable<Object, Object> set = new Hashtable<Object, Object>(defaults
-                .size()
-                + size());
-        Enumeration<?> keys = defaults.propertyNames();
-        while (keys.hasMoreElements()) {
-            set.put(keys.nextElement(), set);
+    /**
+     * Returns those property names (keys) in this {@code Properties} object for which
+     * both key and value are strings.
+     * 
+     * @return a set of keys in the property list
+     * @since 1.6
+     * @hide
+     */
+    public Set<String> stringPropertyNames() {
+        Hashtable<String, String> stringProperties = new Hashtable<String, String>();
+        selectProperties(stringProperties, true);
+        return Collections.unmodifiableSet(stringProperties.keySet());
+    }
+
+    private void selectProperties(Hashtable selectProperties, final boolean isStringOnly) {
+        if (defaults != null) {
+            defaults.selectProperties(selectProperties, isStringOnly);
         }
-        keys = keys();
+        Enumeration<?> keys = keys();
+        Object key, value;
         while (keys.hasMoreElements()) {
-            set.put(keys.nextElement(), set);
+            key = keys.nextElement();
+            if (isStringOnly) {
+                // Only select property with string key and value
+                if (key instanceof String) {
+                    value = get(key);
+                    if (value instanceof String) {
+                        selectProperties.put(key, value);
+                    }
+                }
+            } else {
+                value = get(key);
+                selectProperties.put(key, value);
+            }
         }
-        return set.keys();
     }
 
     /**
@@ -516,39 +537,48 @@
         return put(name, value);
     }
 
+    /**
+     * Stores the mappings in this {@code Properties} object to {@code out},
+     * putting the specified comment at the beginning. The encoding is
+     * ISO8859-1.
+     * 
+     * @param out the {@code OutputStream}
+     * @param comment an optional comment to be written, or null
+     * @throws IOException
+     * @throws ClassCastException if a key or value is not a string
+     */
+    public synchronized void store(OutputStream out, String comment) throws IOException {
+        store(new OutputStreamWriter(out, "ISO8859_1"), comment);
+    }
+
     private static String lineSeparator;
 
     /**
-     * Stores the mappings in this {@code Properties} to the specified {@code
-     * OutputStream}, putting the specified comment at the beginning. The output
-     * from this method is suitable for being read by the
-     * {@link #load(InputStream)} method.
-     *
-     * @param out the {@code OutputStream} to write to.
-     * @param comment the comment to put at the beginning.
-     * @throws IOException if an error occurs during the write to the {@code
-     *             OutputStream}.
-     * @throws ClassCastException if the key or value of a mapping is not a
-     *                {@code String}.
+     * Stores the mappings in this {@code Properties} object to {@code out},
+     * putting the specified comment at the beginning.
+     * 
+     * @param out the {@code Writer}
+     * @param comment an optional comment to be written, or null
+     * @throws IOException
+     * @throws ClassCastException if a key or value is not a string
+     * @since 1.6
+     * @hide
      */
-    public synchronized void store(OutputStream out, String comment)
-            throws IOException {
+    public synchronized void store(Writer writer, String comment) throws IOException {
         if (lineSeparator == null) {
-            lineSeparator = AccessController
-                    .doPrivileged(new PriviAction<String>("line.separator")); //$NON-NLS-1$
+            lineSeparator = AccessController.doPrivileged(new PriviAction<String>("line.separator"));
         }
 
-        StringBuilder buffer = new StringBuilder(200);
-        OutputStreamWriter writer = new OutputStreamWriter(out, "ISO8859_1"); //$NON-NLS-1$
         if (comment != null) {
-            writer.write("#"); //$NON-NLS-1$
+            writer.write("#");
             writer.write(comment);
             writer.write(lineSeparator);
         }
-        writer.write("#"); //$NON-NLS-1$
+        writer.write("#");
         writer.write(new Date().toString());
         writer.write(lineSeparator);
 
+        StringBuilder buffer = new StringBuilder(200);
         for (Map.Entry<Object, Object> entry : entrySet()) {
             String key = (String) entry.getKey();
             dumpString(buffer, key, true);
@@ -587,7 +617,7 @@
 
         if (builder == null) {
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            // BEGIN android-removed
+            // BEGIN android-removed: we still don't support validation.
             // factory.setValidating(true);
             // END android-removed
 
@@ -637,12 +667,7 @@
             for (int i = 0; i < entriesListLength; i++) {
                 Element entry = (Element) entries.item(i);
                 String key = entry.getAttribute("key");
-                // BEGIN android-removed
-                // String value = entry.getTextContent();
-                // END android-removed
-                // BEGIN android-added
                 String value = getTextContent(entry);
-                // END android-added
 
                 /*
                  * key != null & value != null but key or(and) value can be
@@ -675,7 +700,7 @@
      * @throws IOException if an error occurs during writing to the output.
      */
     public void storeToXML(OutputStream os, String comment) throws IOException {
-        storeToXML(os, comment, "UTF-8"); //$NON-NLS-1$
+        storeToXML(os, comment, "UTF-8");
     }
 
     /**
@@ -766,7 +791,7 @@
                 "&quot;");
     }
 
-    // BEGIN android-added
+    // BEGIN android-added: our SAX parser still doesn't do this for us.
     private String getTextContent(Node node) {
         String result = (node instanceof Text ? ((Text) node).getData() : "");
 
diff --git a/luni/src/main/java/java/util/PropertyResourceBundle.java b/luni/src/main/java/java/util/PropertyResourceBundle.java
index 835e892..5d96ead 100644
--- a/luni/src/main/java/java/util/PropertyResourceBundle.java
+++ b/luni/src/main/java/java/util/PropertyResourceBundle.java
@@ -19,6 +19,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.Reader;
 
 /**
  * {@code PropertyResourceBundle} loads resources from an {@code InputStream}. All resources are
@@ -44,21 +45,35 @@
      *             {@code InputStream}.
      */
     public PropertyResourceBundle(InputStream stream) throws IOException {
+        if (stream == null) {
+            throw new NullPointerException();
+        }
         resources = new Properties();
         resources.load(stream);
     }
-
+    
+    /**
+     * Constructs a new resource bundle with properties read from {@code reader}.
+     * 
+     * @param reader the {@code Reader}
+     * @throws IOException
+     * @since 1.6
+     * @hide
+     */
+    public PropertyResourceBundle(Reader reader) throws IOException {
+        resources = new Properties();
+        resources.load(reader);
+    }
+    
+    protected Set<String> handleKeySet(){                
+        return resources.stringPropertyNames();
+    }
+    
     @SuppressWarnings("unchecked")
     private Enumeration<String> getLocalKeys() {
         return (Enumeration<String>) resources.propertyNames();
     }
 
-    /**
-     * Returns the names of the resources contained in this
-     * PropertyResourceBundle.
-     * 
-     * @return an Enumeration of the resource names
-     */
     @Override
     public Enumeration<String> getKeys() {
         if (parent == null) {
@@ -107,14 +122,6 @@
         };
     }
 
-    /**
-     * Returns the named resource from this PropertyResourceBundle, or null if
-     * the resource is not found.
-     * 
-     * @param key
-     *            the name of the resource
-     * @return the resource object
-     */
     @Override
     public Object handleGetObject(String key) {
         return resources.get(key);
diff --git a/luni/src/main/java/java/util/ResourceBundle.java b/luni/src/main/java/java/util/ResourceBundle.java
index ec669d6..dda89b9 100644
--- a/luni/src/main/java/java/util/ResourceBundle.java
+++ b/luni/src/main/java/java/util/ResourceBundle.java
@@ -17,17 +17,17 @@
 
 package java.util;
 
+import com.ibm.icu4jni.util.ICU;
+import dalvik.system.VMStack;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
-// BEGIN android-changed
-// import org.apache.harmony.kernel.vm.VM;
-import dalvik.system.VMStack;
-// END android-changed
-import org.apache.harmony.luni.util.Msg;
-
 /**
  * {@code ResourceBundle} is an abstract class which is the superclass of classes which
  * provide {@code Locale}-specific resources. A bundle contains a number of named
@@ -80,6 +80,10 @@
  */
 public abstract class ResourceBundle {
 
+    private static final String UNDER_SCORE = "_"; //$NON-NLS-1$
+
+    private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
     /**
      * The parent of this {@code ResourceBundle} that is used if this bundle doesn't
      * include the requested resource.
@@ -88,6 +92,8 @@
 
     private Locale locale;
 
+    private long lastLoadTime = 0;
+
     static class MissingBundle extends ResourceBundle {
         @Override
         public Enumeration<String> getKeys() {
@@ -106,10 +112,6 @@
 
     private static final WeakHashMap<Object, Hashtable<String, ResourceBundle>> cache = new WeakHashMap<Object, Hashtable<String, ResourceBundle>>();
 
-    // BEGIN android-added
-    private static Locale defaultLocale = Locale.getDefault();
-    // END android-added
-
     /**
      * Constructs a new instance of this class.
      */
@@ -120,25 +122,21 @@
     /**
      * Finds the named resource bundle for the default {@code Locale} and the caller's
      * {@code ClassLoader}.
-     *
+     * 
      * @param bundleName
      *            the name of the {@code ResourceBundle}.
      * @return the requested {@code ResourceBundle}.
      * @throws MissingResourceException
      *                if the {@code ResourceBundle} cannot be found.
      */
-    public static final ResourceBundle getBundle(String bundleName)
-            throws MissingResourceException {
-        // BEGIN android-changed
-        return getBundleImpl(bundleName, Locale.getDefault(), VMStack
-                .getCallingClassLoader());
-        // END android-changed
+    public static final ResourceBundle getBundle(String bundleName) throws MissingResourceException {
+        return getBundleImpl(bundleName, Locale.getDefault(), VMStack.getCallingClassLoader());
     }
 
     /**
      * Finds the named {@code ResourceBundle} for the specified {@code Locale} and the caller
      * {@code ClassLoader}.
-     *
+     * 
      * @param bundleName
      *            the name of the {@code ResourceBundle}.
      * @param locale
@@ -147,17 +145,13 @@
      * @throws MissingResourceException
      *                if the resource bundle cannot be found.
      */
-    public static final ResourceBundle getBundle(String bundleName,
-            Locale locale) {
-        // BEGIN android-changed
-        return getBundleImpl(bundleName, locale,
-                VMStack.getCallingClassLoader());
-        // END android-changed
+    public static final ResourceBundle getBundle(String bundleName, Locale locale) {
+        return getBundleImpl(bundleName, locale, VMStack.getCallingClassLoader());
     }
 
     /**
      * Finds the named resource bundle for the specified {@code Locale} and {@code ClassLoader}.
-     *
+     * 
      * The passed base name and {@code Locale} are used to create resource bundle names.
      * The first name is created by concatenating the base name with the result
      * of {@link Locale#toString()}. From this name all parent bundle names are
@@ -209,25 +203,215 @@
         if (loader == null) {
             throw new NullPointerException();
         }
-        // BEGIN android-changed
-        return getBundleImpl(bundleName, locale, loader);
-        // END android-changed
+        if (bundleName != null) {
+            ResourceBundle bundle;
+            if (!locale.equals(Locale.getDefault())) {
+                if ((bundle = handleGetBundle(bundleName, UNDER_SCORE + locale,
+                        false, loader)) != null) {
+                    return bundle;
+                }
+            }
+            if ((bundle = handleGetBundle(bundleName, UNDER_SCORE
+                    + Locale.getDefault(), true, loader)) != null) {
+                return bundle;
+            }
+            throw missingResourceException(bundleName + '_' + locale, "");
+        }
+        throw new NullPointerException();
+    }
+
+    private static MissingResourceException missingResourceException(String className, String key) {
+        String detail = "Can't find resource for bundle '" + className + "', key '" + key + "'";
+        throw new MissingResourceException(detail, className, key);
+    }
+
+    /**
+     * Finds the named resource bundle for the specified base name and control.
+     * 
+     * @param baseName
+     *            the base name of a resource bundle
+     * @param control
+     *            the control that control the access sequence
+     * @return the named resource bundle
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final ResourceBundle getBundle(String baseName, ResourceBundle.Control control) {
+        return getBundle(baseName, Locale.getDefault(), getLoader(), control);
+    }
+
+    /**
+     * Finds the named resource bundle for the specified base name and control.
+     * 
+     * @param baseName
+     *            the base name of a resource bundle
+     * @param targetLocale
+     *            the target locale of the resource bundle
+     * @param control
+     *            the control that control the access sequence
+     * @return the named resource bundle
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static final ResourceBundle getBundle(String baseName,
+            Locale targetLocale, ResourceBundle.Control control) {
+        return getBundle(baseName, targetLocale, getLoader(), control);
+    }
+
+    private static ClassLoader getLoader() {
+        return AccessController
+                .doPrivileged(new PrivilegedAction<ClassLoader>() {
+                    public ClassLoader run() {
+                        ClassLoader cl = this.getClass().getClassLoader();
+                        if (null == cl) {
+                            cl = ClassLoader.getSystemClassLoader();
+                        }
+                        return cl;
+                    }
+                });
+    }
+
+    /**
+     * Finds the named resource bundle for the specified base name and control.
+     * 
+     * @param baseName
+     *            the base name of a resource bundle
+     * @param targetLocale
+     *            the target locale of the resource bundle
+     * @param loader
+     *            the class loader to load resource
+     * @param control
+     *            the control that control the access sequence
+     * @return the named resource bundle
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static ResourceBundle getBundle(String baseName,
+            Locale targetLocale, ClassLoader loader,
+            ResourceBundle.Control control) {
+        boolean expired = false;
+        String bundleName = control.toBundleName(baseName, targetLocale);
+        Object cacheKey = loader != null ? (Object) loader : (Object) "null"; //$NON-NLS-1$
+        Hashtable<String, ResourceBundle> loaderCache;
+        // try to find in cache
+        synchronized (cache) {
+            loaderCache = cache.get(cacheKey);
+            if (loaderCache == null) {
+                loaderCache = new Hashtable<String, ResourceBundle>();
+                cache.put(cacheKey, loaderCache);
+            }
+        }
+        ResourceBundle result = loaderCache.get(bundleName);
+        if (result != null) {
+            long time = control.getTimeToLive(baseName, targetLocale);
+            if (time == 0 || time == Control.TTL_NO_EXPIRATION_CONTROL
+                    || time + result.lastLoadTime < System.currentTimeMillis()) {
+                if (MISSING == result) {
+                    throw new MissingResourceException(null, bundleName + '_'
+                            + targetLocale, EMPTY_STRING);
+                }
+                return result;
+            }
+            expired = true;
+        }
+        // try to load
+        ResourceBundle ret = processGetBundle(baseName, targetLocale, loader,
+                control, expired, result);
+
+        if (null != ret) {
+            loaderCache.put(bundleName, ret);
+            ret.lastLoadTime = System.currentTimeMillis();
+            return ret;
+        }
+        loaderCache.put(bundleName, MISSING);
+        throw new MissingResourceException(null, bundleName + '_'
+                + targetLocale, EMPTY_STRING);
+    }
+
+    private static ResourceBundle processGetBundle(String baseName,
+            Locale targetLocale, ClassLoader loader,
+            ResourceBundle.Control control, boolean expired,
+            ResourceBundle result) {
+        List<Locale> locales = control.getCandidateLocales(baseName,
+                targetLocale);
+        if (null == locales) {
+            throw new IllegalArgumentException();
+        }
+        List<String> formats = control.getFormats(baseName);
+        if (Control.FORMAT_CLASS == formats
+                || Control.FORMAT_PROPERTIES == formats
+                || Control.FORMAT_DEFAULT == formats) {
+            throw new IllegalArgumentException();
+        }
+        ResourceBundle ret = null;
+        ResourceBundle currentBundle = null;
+        ResourceBundle bundle = null;
+        for (Locale locale : locales) {
+            for (String format : formats) {
+                try {
+                    if (expired) {
+                        bundle = control.newBundle(baseName, locale, format,
+                                loader, control.needsReload(baseName, locale,
+                                        format, loader, result, System
+                                                .currentTimeMillis()));
+
+                    } else {
+                        try {
+                            bundle = control.newBundle(baseName, locale,
+                                    format, loader, false);
+                        } catch (IllegalArgumentException e) {
+                            // do nothing
+                        }
+                    }
+                } catch (IllegalAccessException e) {
+                    // do nothing
+                } catch (InstantiationException e) {
+                    // do nothing
+                } catch (IOException e) {
+                    // do nothing
+                }
+                if (null != bundle) {
+                    if (null != currentBundle) {
+                        currentBundle.setParent(bundle);
+                        currentBundle = bundle;
+                    } else {
+                        if (null == ret) {
+                            ret = bundle;
+                            currentBundle = ret;
+                        }
+                    }
+                }
+                if (null != bundle) {
+                    break;
+                }
+            }
+        }
+
+        if ((null == ret)
+                || (Locale.ROOT.equals(ret.getLocale()) && (!(locales.size() == 1 && locales
+                        .contains(Locale.ROOT))))) {
+            Locale nextLocale = control.getFallbackLocale(baseName,
+                    targetLocale);
+            if (null != nextLocale) {
+                ret = processGetBundle(baseName, nextLocale, loader, control,
+                        expired, result);
+            }
+        }
+
+        return ret;
     }
 
     private static ResourceBundle getBundleImpl(String bundleName,
             Locale locale, ClassLoader loader) throws MissingResourceException {
         if (bundleName != null) {
             ResourceBundle bundle;
-            // BEGIN android-added
-            if (!defaultLocale.equals(Locale.getDefault())) {
-                cache.clear();
-                defaultLocale = Locale.getDefault();
-            }
-            // END android-added
             if (!locale.equals(Locale.getDefault())) {
                 String localeName = locale.toString();
                 if (localeName.length() > 0) {
-                    localeName = "_" + localeName; //$NON-NLS-1$
+                    localeName = UNDER_SCORE + localeName;
                 }
                 if ((bundle = handleGetBundle(bundleName, localeName, false,
                         loader)) != null) {
@@ -236,20 +420,19 @@
             }
             String localeName = Locale.getDefault().toString();
             if (localeName.length() > 0) {
-                localeName = "_" + localeName; //$NON-NLS-1$
+                localeName = UNDER_SCORE + localeName;
             }
             if ((bundle = handleGetBundle(bundleName, localeName, true, loader)) != null) {
                 return bundle;
             }
-            throw new MissingResourceException(Msg.getString("KA029", bundleName, locale), bundleName + '_' + locale, //$NON-NLS-1$
-                    ""); //$NON-NLS-1$
+            throw missingResourceException(bundleName + '_' + locale, "");
         }
         throw new NullPointerException();
     }
 
     /**
      * Returns the names of the resources contained in this {@code ResourceBundle}.
-     *
+     * 
      * @return an {@code Enumeration} of the resource names.
      */
     public abstract Enumeration<String> getKeys();
@@ -258,7 +441,7 @@
      * Gets the {@code Locale} of this {@code ResourceBundle}. In case a bundle was not
      * found for the requested {@code Locale}, this will return the actual {@code Locale} of
      * this resource bundle that was found after doing a fallback.
-     *
+     * 
      * @return the {@code Locale} of this {@code ResourceBundle}.
      */
     public Locale getLocale() {
@@ -270,7 +453,7 @@
      * cannot be found in this bundle, it falls back to the parent bundle (if
      * it's not null) by calling the {@link #handleGetObject} method. If the resource still
      * can't be found it throws a {@code MissingResourceException}.
-     *
+     * 
      * @param key
      *            the name of the resource.
      * @return the resource object.
@@ -287,12 +470,12 @@
             last = theParent;
             theParent = theParent.parent;
         } while (theParent != null);
-        throw new MissingResourceException(Msg.getString("KA029", last.getClass().getName(), key), last.getClass().getName(), key); //$NON-NLS-1$
+        throw missingResourceException(last.getClass().getName(), key);
     }
 
     /**
      * Returns the named string resource from this {@code ResourceBundle}.
-     *
+     * 
      * @param key
      *            the name of the resource.
      * @return the resource string.
@@ -308,7 +491,7 @@
 
     /**
      * Returns the named resource from this {@code ResourceBundle}.
-     *
+     * 
      * @param key
      *            the name of the resource.
      * @return the resource string array.
@@ -355,7 +538,7 @@
 
         try {
             Class<?> bundleClass = Class.forName(bundleName, true, loader);
-            
+
             if (ResourceBundle.class.isAssignableFrom(bundleClass)) {
                 bundle = (ResourceBundle) bundleClass.newInstance();
             }
@@ -380,12 +563,13 @@
             if (stream != null) {
                 try {
                     try {
-                        bundle = new PropertyResourceBundle(stream);
+                        bundle = new PropertyResourceBundle(new InputStreamReader(stream));
                     } finally {
                         stream.close();
                     }
                     bundle.setLocale(locale);
                 } catch (IOException e) {
+                    // do nothing
                 }
             }
         }
@@ -417,7 +601,7 @@
     /**
      * Returns the named resource from this {@code ResourceBundle}, or null if the
      * resource is not found.
-     *
+     * 
      * @param key
      *            the name of the resource.
      * @return the resource object.
@@ -427,7 +611,7 @@
     /**
      * Sets the parent resource bundle of this {@code ResourceBundle}. The parent is
      * searched for resources which are not found in this {@code ResourceBundle}.
-     *
+     * 
      * @param bundle
      *            the parent {@code ResourceBundle}.
      */
@@ -443,26 +627,509 @@
         return null;
     }
 
+    private void setLocale(Locale locale) {
+        this.locale = locale;
+    }
+
     private void setLocale(String name) {
-        String language = "", country = "", variant = ""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
-        if (name.length() > 1) {
-            int nextIndex = name.indexOf('_', 1);
-            if (nextIndex == -1) {
-                nextIndex = name.length();
-            }
-            language = name.substring(1, nextIndex);
-            if (nextIndex + 1 < name.length()) {
-                int index = nextIndex;
-                nextIndex = name.indexOf('_', nextIndex + 1);
-                if (nextIndex == -1) {
-                    nextIndex = name.length();
-                }
-                country = name.substring(index + 1, nextIndex);
-                if (nextIndex + 1 < name.length()) {
-                    variant = name.substring(nextIndex + 1, name.length());
-                }
+        setLocale(ICU.localeFromString(name));
+    }
+
+    public static final void clearCache() {
+        cache.remove(ClassLoader.getSystemClassLoader());
+    }
+
+    public static final void clearCache(ClassLoader loader) {
+        if (null == loader) {
+            throw new NullPointerException();
+        }
+        cache.remove(loader);
+    }
+
+    public boolean containsKey(String key) {
+        if (null == key) {
+            throw new NullPointerException();
+        }
+        return keySet().contains(key);
+    }
+
+    public Set<String> keySet() {
+        Set<String> ret = new HashSet<String>();
+        Enumeration<String> keys = getKeys();
+        while (keys.hasMoreElements()) {
+            ret.add(keys.nextElement());
+        }
+        return ret;
+    }
+
+    protected Set<String> handleKeySet() {
+        Set<String> set = keySet();
+        Set<String> ret = new HashSet<String>();
+        for (String key : set) {
+            if (null != handleGetObject(key)) {
+                ret.add(key);
             }
         }
-        locale = new Locale(language, country, variant);
+        return ret;
+    }
+
+    private static class NoFallbackControl extends Control {
+
+        static final Control NOFALLBACK_FORMAT_PROPERTIES_CONTROL = new NoFallbackControl(
+                JAVAPROPERTIES);
+
+        static final Control NOFALLBACK_FORMAT_CLASS_CONTROL = new NoFallbackControl(
+                JAVACLASS);
+
+        static final Control NOFALLBACK_FORMAT_DEFAULT_CONTROL = new NoFallbackControl(
+                listDefault);
+
+        public NoFallbackControl(String format) {
+            super();
+            listClass = new ArrayList<String>();
+            listClass.add(format);
+            super.format = Collections.unmodifiableList(listClass);
+        }
+
+        public NoFallbackControl(List<String> list) {
+            super();
+            super.format = list;
+        }
+
+        @Override
+        public Locale getFallbackLocale(String baseName, Locale locale) {
+            if (null == baseName || null == locale) {
+                throw new NullPointerException();
+            }
+            return null;
+        }
+    }
+
+    private static class SimpleControl extends Control {
+        public SimpleControl(String format) {
+            super();
+            listClass = new ArrayList<String>();
+            listClass.add(format);
+            super.format = Collections.unmodifiableList(listClass);
+        }
+    }
+
+    @SuppressWarnings("nls")
+    /**
+     * ResourceBundle.Control is a static utility class defines ResourceBundle
+     * load access methods, its default access order is as the same as before.
+     * However users can implement their own control.
+     * 
+     * @since 1.6
+     * @hide
+     */
+    public static class Control {
+        static List<String> listDefault = new ArrayList<String>();
+
+        static List<String> listClass = new ArrayList<String>();
+
+        static List<String> listProperties = new ArrayList<String>();
+
+        static String JAVACLASS = "java.class";
+
+        static String JAVAPROPERTIES = "java.properties";
+
+        static {
+            listDefault.add(JAVACLASS);
+            listDefault.add(JAVAPROPERTIES);
+            listClass.add(JAVACLASS);
+            listProperties.add(JAVAPROPERTIES);
+        }
+
+        /**
+         * a list defines default format
+         */
+        public static final List<String> FORMAT_DEFAULT = Collections
+                .unmodifiableList(listDefault);
+
+        /**
+         * a list defines java class format
+         */
+        public static final List<String> FORMAT_CLASS = Collections
+                .unmodifiableList(listClass);
+
+        /**
+         * a list defines property format
+         */
+        public static final List<String> FORMAT_PROPERTIES = Collections
+                .unmodifiableList(listProperties);
+
+        /**
+         * a constant that indicates cache will not be used.
+         */
+        public static final long TTL_DONT_CACHE = -1L;
+
+        /**
+         * a constant that indicates cache will not be expired.
+         */
+        public static final long TTL_NO_EXPIRATION_CONTROL = -2L;
+
+        private static final Control FORMAT_PROPERTIES_CONTROL = new SimpleControl(
+                JAVAPROPERTIES);
+
+        private static final Control FORMAT_CLASS_CONTROL = new SimpleControl(
+                JAVACLASS);
+
+        private static final Control FORMAT_DEFAULT_CONTROL = new Control();
+
+        List<String> format;
+
+        /**
+         * default constructor
+         * 
+         */
+        protected Control() {
+            super();
+            listClass = new ArrayList<String>();
+            listClass.add(JAVACLASS);
+            listClass.add(JAVAPROPERTIES);
+            format = Collections.unmodifiableList(listClass);
+        }
+
+        /**
+         * Answers a control according to the given format list
+         * 
+         * @param formats
+         *            a format to use
+         * @return a control according to the given format list
+         */
+        public static final Control getControl(List<String> formats) {
+            switch (formats.size()) {
+            case 1:
+                if (formats.contains(JAVACLASS)) {
+                    return FORMAT_CLASS_CONTROL;
+                }
+                if (formats.contains(JAVAPROPERTIES)) {
+                    return FORMAT_PROPERTIES_CONTROL;
+                }
+                break;
+            case 2:
+                if (formats.equals(FORMAT_DEFAULT)) {
+                    return FORMAT_DEFAULT_CONTROL;
+                }
+                break;
+            }
+            throw new IllegalArgumentException();
+        }
+
+        /**
+         * Answers a control according to the given format list whose fallback
+         * locale is null
+         * 
+         * @param formats
+         *            a format to use
+         * @return a control according to the given format list whose fallback
+         *         locale is null
+         */
+        public static final Control getNoFallbackControl(List<String> formats) {
+            switch (formats.size()) {
+            case 1:
+                if (formats.contains(JAVACLASS)) {
+                    return NoFallbackControl.NOFALLBACK_FORMAT_CLASS_CONTROL;
+                }
+                if (formats.contains(JAVAPROPERTIES)) {
+                    return NoFallbackControl.NOFALLBACK_FORMAT_PROPERTIES_CONTROL;
+                }
+                break;
+            case 2:
+                if (formats.equals(FORMAT_DEFAULT)) {
+                    return NoFallbackControl.NOFALLBACK_FORMAT_DEFAULT_CONTROL;
+                }
+                break;
+            }
+            throw new IllegalArgumentException();
+        }
+
+        /**
+         * Answers a list of candidate locales according to the base name and
+         * locale
+         * 
+         * @param baseName
+         *            the base name to use
+         * @param locale
+         *            the locale
+         * @return the candidate locales according to the base name and locale
+         */
+        public List<Locale> getCandidateLocales(String baseName, Locale locale) {
+            if (null == baseName || null == locale) {
+                throw new NullPointerException();
+            }
+            List<Locale> retList = new ArrayList<Locale>();
+            String language = locale.getLanguage();
+            String country = locale.getCountry();
+            String variant = locale.getVariant();
+            if (!EMPTY_STRING.equals(variant)) {
+                retList.add(new Locale(language, country, variant));
+            }
+            if (!EMPTY_STRING.equals(country)) {
+                retList.add(new Locale(language, country));
+            }
+            if (!EMPTY_STRING.equals(language)) {
+                retList.add(new Locale(language));
+            }
+            retList.add(Locale.ROOT);
+            return retList;
+        }
+
+        /**
+         * Answers a list of strings of formats according to the base name
+         * 
+         * @param baseName
+         *            the base name to use
+         * @return a list of strings of formats according to the base name
+         */
+        public List<String> getFormats(String baseName) {
+            if (null == baseName) {
+                throw new NullPointerException();
+            }
+            return format;
+        }
+
+        /**
+         * Answers a list of strings of locales according to the base name
+         * 
+         * @param baseName
+         *            the base name to use
+         * @return a list of strings of locales according to the base name
+         */
+        public Locale getFallbackLocale(String baseName, Locale locale) {
+            if (null == baseName || null == locale) {
+                throw new NullPointerException();
+            }
+            if (Locale.getDefault() != locale) {
+                return Locale.getDefault();
+            }
+            return null;
+        }
+
+        /**
+         * Answers a new ResourceBundle according to the give parameters
+         * 
+         * @param baseName
+         *            the base name to use
+         * @param locale
+         *            the given locale
+         * @param format
+         *            the format, default is "java.class" or "java.properities"
+         * @param loader
+         *            the classloader to use
+         * @param reload
+         *            if reload the resource
+         * @return a new ResourceBundle according to the give parameters
+         * @throws IllegalAccessException
+         *             if can not access resources
+         * @throws InstantiationException
+         *             if can not instante a resource class
+         * @throws IOException
+         *             if other I/O exception happens
+         */
+        public ResourceBundle newBundle(String baseName, Locale locale,
+                String format, ClassLoader loader, boolean reload)
+                throws IllegalAccessException, InstantiationException,
+                IOException {
+            if (null == format || null == loader) {
+                throw new NullPointerException();
+            }
+            InputStream streams = null;
+            final String bundleName = toBundleName(baseName, locale);
+            final ClassLoader clsloader = loader;
+            ResourceBundle ret;
+            Class<?> cls = null;
+            if (JAVACLASS == format) {
+                cls = AccessController
+                        .doPrivileged(new PrivilegedAction<Class<?>>() {
+                            public Class<?> run() {
+                                try {
+                                    return clsloader.loadClass(bundleName);
+                                } catch (Exception e) {
+                                    return null;
+                                } catch (NoClassDefFoundError e) {
+                                    return null;
+                                }
+                            }
+                        });
+                if (null == cls) {
+                    return null;
+                }
+                try {
+                    ResourceBundle bundle = (ResourceBundle) cls.newInstance();
+                    bundle.setLocale(locale);
+                    return bundle;
+                } catch (NullPointerException e) {
+                    return null;
+                }
+            }
+            if (JAVAPROPERTIES == format) {
+                final String resourceName = toResourceName(bundleName,
+                        "properties");
+                if (reload) {
+                    URL url = null;
+                    try {
+                        url = loader.getResource(resourceName);
+                    } catch (NullPointerException e) {
+                        // do nothing
+                    }
+                    if (null != url) {
+                        URLConnection con = url.openConnection();
+                        con.setUseCaches(false);
+                        streams = con.getInputStream();
+                    }
+                } else {
+                    try {
+                        streams = AccessController
+                                .doPrivileged(new PrivilegedAction<InputStream>() {
+                                    public InputStream run() {
+                                        return clsloader
+                                                .getResourceAsStream(resourceName);
+                                    }
+                                });
+                    } catch (NullPointerException e) {
+                        // do nothing
+                    }
+                }
+                if (streams != null) {
+                    try {
+                        ret = new PropertyResourceBundle(new InputStreamReader(streams));
+                        ret.setLocale(locale);
+                        streams.close();
+                    } catch (IOException e) {
+                        return null;
+                    }
+                    return ret;
+                }
+                return null;
+            }
+            throw new IllegalArgumentException();
+        }
+
+        /**
+         * Answers the time to live of the ResourceBundle, default is
+         * TTL_NO_EXPIRATION_CONTROL
+         * 
+         * @param baseName
+         *            the base name to use
+         * @param locale
+         *            the locale to use
+         * @return TTL_NO_EXPIRATION_CONTROL
+         */
+        public long getTimeToLive(String baseName, Locale locale) {
+            if (null == baseName || null == locale) {
+                throw new NullPointerException();
+            }
+            return TTL_NO_EXPIRATION_CONTROL;
+        }
+
+        /**
+         * Answers if the ResourceBundle needs to reload
+         * 
+         * @param baseName
+         *            the base name of the ResourceBundle
+         * @param locale
+         *            the locale of the ResourceBundle
+         * @param format
+         *            the format to load
+         * @param loader
+         *            the ClassLoader to load resource
+         * @param bundle
+         *            the ResourceBundle
+         * @param loadTime
+         *            the expired time
+         * @return if the ResourceBundle needs to reload
+         */
+        public boolean needsReload(String baseName, Locale locale,
+                String format, ClassLoader loader, ResourceBundle bundle,
+                long loadTime) {
+            if (null == bundle) {
+                // FIXME what's the use of bundle?
+                throw new NullPointerException();
+            }
+            String bundleName = toBundleName(baseName, locale);
+            String suffix = format;
+            if (JAVACLASS == format) {
+                suffix = "class";
+            }
+            if (JAVAPROPERTIES == format) {
+                suffix = "properties";
+            }
+            String urlname = toResourceName(bundleName, suffix);
+            URL url = loader.getResource(urlname);
+            if (null != url) {
+                String fileName = url.getFile();
+                long lastModified = new File(fileName).lastModified();
+                if (lastModified > loadTime) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * a utility method to answer the name of a resource bundle according to
+         * the given base name and locale
+         * 
+         * @param baseName
+         *            the given base name
+         * @param locale
+         *            the locale to use
+         * @return the name of a resource bundle according to the given base
+         *         name and locale
+         */
+        public String toBundleName(String baseName, Locale locale) {
+            final String emptyString = EMPTY_STRING;
+            final String preString = UNDER_SCORE;
+            final String underline = UNDER_SCORE;
+            if (null == baseName) {
+                throw new NullPointerException();
+            }
+            StringBuilder ret = new StringBuilder();
+            StringBuilder prefix = new StringBuilder();
+            ret.append(baseName);
+            if (!locale.getLanguage().equals(emptyString)) {
+                ret.append(underline);
+                ret.append(locale.getLanguage());
+            } else {
+                prefix.append(preString);
+            }
+            if (!locale.getCountry().equals(emptyString)) {
+                ret.append((CharSequence) prefix);
+                ret.append(underline);
+                ret.append(locale.getCountry());
+                prefix = new StringBuilder();
+            } else {
+                prefix.append(preString);
+            }
+            if (!locale.getVariant().equals(emptyString)) {
+                ret.append((CharSequence) prefix);
+                ret.append(underline);
+                ret.append(locale.getVariant());
+            }
+            return ret.toString();
+        }
+
+        /**
+         * a utility method to answer the name of a resource according to the
+         * given bundleName and suffix
+         * 
+         * @param bundleName
+         *            the given bundle name
+         * @param suffix
+         *            the suffix
+         * @return the name of a resource according to the given bundleName and
+         *         suffix
+         */
+        public final String toResourceName(String bundleName, String suffix) {
+            if (null == suffix) {
+                throw new NullPointerException();
+            }
+            StringBuilder ret = new StringBuilder(bundleName.replace('.', '/'));
+            ret.append('.');
+            ret.append(suffix);
+            return ret.toString();
+        }
     }
 }
diff --git a/luni/src/main/java/java/util/Scanner.java b/luni/src/main/java/java/util/Scanner.java
index f1ca423..fbbf666 100644
--- a/luni/src/main/java/java/util/Scanner.java
+++ b/luni/src/main/java/java/util/Scanner.java
@@ -1642,14 +1642,12 @@
      */
     @Override
     public String toString() {
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append(this.getClass()).append(": ") //$NON-NLS-1$
-                .append("{(delimiter:") //$NON-NLS-1$
-                .append(delimiter).append(")(findStartIndex=") //$NON-NLS-1$
-                .append(findStartIndex).append(")(match succeed=") //$NON-NLS-1$
-                .append(matchSuccessful).append(")(closed=") //$NON-NLS-1$
-                .append(closed).append(")}"); //$NON-NLS-1$
-        return stringBuilder.toString();
+        return getClass().getName() +
+                "[delimiter=" + delimiter +
+                ",findStartIndex=" + findStartIndex +
+                ",matchSuccessful=" + matchSuccessful +
+                ",closed=" + closed +
+                "]";
     }
 
     /**
@@ -2195,4 +2193,18 @@
         buffer.position(oldPosition);
         buffer.limit(oldLimit);
     }
+
+    /**
+     * Resets this scanner's delimiter, locale, and radix.
+     * 
+     * @return this scanner
+     * @since 1.6
+     * @hide
+     */
+    public Scanner reset() {
+        delimiter = DEFAULT_DELIMITER;
+        locale = Locale.getDefault();
+        integerRadix = 10;
+        return this;
+    }
 }
diff --git a/luni/src/main/java/java/util/ServiceConfigurationError.java b/luni/src/main/java/java/util/ServiceConfigurationError.java
new file mode 100644
index 0000000..81cd36e
--- /dev/null
+++ b/luni/src/main/java/java/util/ServiceConfigurationError.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package java.util;
+
+/**
+ * Thrown when a service provider can't be loaded by {@link ServiceLoader}.
+ * @since 1.6
+ * @hide
+ */
+public class ServiceConfigurationError extends Error {
+    private static final long serialVersionUID = 74132770414881L;
+
+    /**
+     * Constructs a new error with the given detail message.
+     * @param msg the detail message, or null
+     */
+    public ServiceConfigurationError(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new error with the given detail message and cause.
+     * @param msg the detail message, or null
+     * @param cause the cause, null
+     */
+    public ServiceConfigurationError(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/luni/src/main/java/java/util/ServiceLoader.java b/luni/src/main/java/java/util/ServiceLoader.java
new file mode 100644
index 0000000..a8e16d5
--- /dev/null
+++ b/luni/src/main/java/java/util/ServiceLoader.java
@@ -0,0 +1,276 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package java.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * A service-provider loader.
+ * 
+ * <p>A service provider is a factory for creating all known implementations of a particular
+ * class or interface {@code S}. The known implementations are read from a configuration file in
+ * {@code META-INF/services/}. The file's name should match the class' binary name (such as
+ * {@code java.util.Outer$Inner}).
+ * 
+ * <p>The file format is as follows.
+ * The file's character encoding must be UTF-8.
+ * Whitespace is ignored, and {@code #} is used to begin a comment that continues to the
+ * next newline.
+ * Lines that are empty after comment removal and whitespace trimming are ignored.
+ * Otherwise, each line contains the binary name of one implementation class.
+ * Duplicate entries are ignored, but entries are otherwise returned in order (that is, the file
+ * is treated as an ordered set).
+ * 
+ * <p>Given these classes:
+ * <pre>
+ * package a.b.c;
+ * public interface MyService { ... }
+ * public class MyImpl1 implements MyService { ... }
+ * public class MyImpl2 implements MyService { ... }
+ * </pre>
+ * And this configuration file (stored as {@code META-INF/services/a.b.c.MyService}):
+ * <pre>
+ * # Known MyService providers.
+ * a.b.c.MyImpl1  # The original implementation for handling "bar"s.
+ * a.b.c.MyImpl2  # A later implementation for "foo"s.
+ * </pre>
+ * You might use {@code ServiceProvider} something like this:
+ * <pre>
+ *   for (MyService service : ServiceLoader<MyService>.load(MyService.class)) {
+ *     if (service.supports(o)) {
+ *       return service.handle(o);
+ *     }
+ *   }
+ * </pre>
+ * 
+ * <p>Note that each iteration creates new instances of the various service implementations, so
+ * any heavily-used code will likely want to cache the known implementations itself and reuse them.
+ * Note also that the candidate classes are instantiated lazily as you call {@code next} on the
+ * iterator: construction of the iterator itself does not instantiate any of the providers.
+ * 
+ * @param <S> the service class or interface
+ * @since 1.6
+ * @hide
+ */
+public final class ServiceLoader<S> implements Iterable<S> {
+    private final Class<S> service;
+    private final ClassLoader classLoader;
+    private final Set<URL> services;
+
+    private ServiceLoader(Class<S> service, ClassLoader classLoader) {
+        // It makes no sense for service to be null.
+        // classLoader is null if you want the system class loader.
+        if (service == null) {
+            throw new NullPointerException();
+        }
+        this.service = service;
+        this.classLoader = classLoader;
+        this.services = new HashSet<URL>();
+        reload();
+    }
+
+    /**
+     * Invalidates the cache of known service provider class names.
+     */
+    public void reload() {
+        internalLoad();
+    }
+
+    /**
+     * Returns an iterator over all the service providers offered by this service loader.
+     * Note that {@code hasNext} and {@code next} may throw if the configuration is invalid.
+     * 
+     * <p>Each iterator will return new instances of the classes it iterates over, so callers
+     * may want to cache the results of a single call to this method rather than call it
+     * repeatedly.
+     * 
+     * <p>The returned iterator does not support {@code remove}.
+     */
+    public Iterator<S> iterator() {
+        return new ServiceIterator(this);
+    }
+
+    /**
+     * Constructs a service loader. If {@code classLoader} is null, the system class loader
+     * is used.
+     * 
+     * @param service the service class or interface
+     * @param classLoader the class loader
+     * @return a new ServiceLoader
+     */
+    public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader classLoader) {
+        if (classLoader == null) {
+            classLoader = ClassLoader.getSystemClassLoader();
+        }
+        return new ServiceLoader<S>(service, classLoader);
+    }
+
+    private void internalLoad() {
+        services.clear();
+        try {
+            String name = "META-INF/services/" + service.getName();
+            services.addAll(Collections.list(classLoader.getResources(name)));
+        } catch (IOException e) {
+            return;
+        }
+    }
+
+    /**
+     * Constructs a service loader, using the current thread's context class loader.
+     * 
+     * @param service the service class or interface
+     * @return a new ServiceLoader
+     */
+    public static <S> ServiceLoader<S> load(Class<S> service) {
+        return ServiceLoader.load(service, Thread.currentThread().getContextClassLoader());
+    }
+
+    /**
+     * Constructs a service loader, using the extension class loader.
+     * 
+     * @param service the service class or interface
+     * @return a new ServiceLoader
+     */
+    public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
+        ClassLoader cl = ClassLoader.getSystemClassLoader();
+        if (cl != null) {
+            while (cl.getParent() != null) {
+                cl = cl.getParent();
+            }
+        }
+        return ServiceLoader.load(service, cl);
+    }
+
+    /**
+     * Internal API to support built-in SPIs that check a system property first.
+     * Returns an instance specified by a property with the class' binary name, or null if
+     * no such property is set.
+     * @hide
+     */
+    public static <S> S loadFromSystemProperty(final Class<S> service) {
+        return AccessController.doPrivileged(new PrivilegedAction<S>() {
+            public S run() {
+                try {
+                    final String className = System.getProperty(service.getName());
+                    if (className != null) {
+                        Class<?> c = ClassLoader.getSystemClassLoader().loadClass(className);
+                        return (S) c.newInstance();
+                    }
+                    return null;
+                } catch (Exception e) {
+                    throw new Error(e);
+                }
+            }
+        });
+    }
+
+    @Override
+    public String toString() {
+        return "ServiceLoader for " + service.getName();
+    }
+
+    private class ServiceIterator implements Iterator<S> {
+        private final ClassLoader classLoader;
+        private final Class<S> service;
+        private final Set<URL> services;
+
+        private boolean isRead = false;
+
+        private LinkedList<String> queue = new LinkedList<String>();
+
+        public ServiceIterator(ServiceLoader<S> sl) {
+            this.classLoader = sl.classLoader;
+            this.service = sl.service;
+            this.services = sl.services;
+        }
+
+        public boolean hasNext() {
+            if (!isRead) {
+                readClass();
+            }
+            return (queue != null && !queue.isEmpty());
+        }
+
+        @SuppressWarnings("unchecked")
+        public S next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            String className = queue.remove();
+            try {
+                return service.cast(classLoader.loadClass(className).newInstance());
+            } catch (Exception e) {
+                throw new ServiceConfigurationError("Couldn't instantiate class " + className, e);
+            }
+        }
+
+        private void readClass() {
+            for (URL url : services) {
+                BufferedReader reader = null;
+                try {
+                    reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        // Strip comments and whitespace...
+                        int commentStart = line.indexOf('#');
+                        if (commentStart != -1) {
+                            line = line.substring(0, commentStart);
+                        }
+                        line = line.trim();
+                        // Ignore empty lines.
+                        if (line.isEmpty()) {
+                            continue;
+                        }
+                        String className = line;
+                        checkValidJavaClassName(className);
+                        if (!queue.contains(className)) {
+                            queue.add(className);
+                        }
+                    }
+                    isRead = true;
+                } catch (Exception e) {
+                    throw new ServiceConfigurationError("Couldn't read " + url, e);
+                } finally {
+                    try {
+                        if (reader != null) {
+                            reader.close();
+                        }
+                    } catch (IOException ex) {
+                    }
+                }
+            }
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        private void checkValidJavaClassName(String className) {
+            for (int i = 0; i < className.length(); ++i) {
+                char ch = className.charAt(i);
+                if (!Character.isJavaIdentifierPart(ch) && ch != '.') {
+                    throw new ServiceConfigurationError("Bad character '" + ch + "' in class name");
+                }
+            }
+        }
+    }
+}
diff --git a/luni/src/main/java/java/util/SimpleTimeZone.java b/luni/src/main/java/java/util/SimpleTimeZone.java
index 702b6ef..61d31fc 100644
--- a/luni/src/main/java/java/util/SimpleTimeZone.java
+++ b/luni/src/main/java/java/util/SimpleTimeZone.java
@@ -94,8 +94,6 @@
 
     private boolean useDaylight;
 
-    private GregorianCalendar daylightSavings;
-
     private int dstSavings = 3600000;
 
     // BEGIN android-removed
@@ -349,9 +347,6 @@
     @Override
     public Object clone() {
         SimpleTimeZone zone = (SimpleTimeZone) super.clone();
-        if (daylightSavings != null) {
-            zone.daylightSavings = (GregorianCalendar) daylightSavings.clone();
-        }
         return zone;
     }
 
@@ -530,15 +525,13 @@
 
     @Override
     public int getOffset(long time) {
-        // BEGIN android-changed
-        // return icuTZ.getOffset(time);
+        // BEGIN android-changed: simplified variant of the ICU4J code.
         if (!useDaylightTime()) {
             return rawOffset;
         }
-        if (daylightSavings == null) {
-            daylightSavings = new GregorianCalendar(this);
-        }
-        return daylightSavings.getOffset(time + rawOffset);
+        int[] fields = Grego.timeToFields(time + rawOffset, null);
+        return getOffset(GregorianCalendar.AD, fields[0], fields[1], fields[2],
+                fields[3], fields[5]);
         // END android-changed
     }
 
@@ -588,17 +581,8 @@
 
     @Override
     public boolean inDaylightTime(Date time) {
-        // BEGIN android-changed
-        // return icuTZ.inDaylightTime(time);
-        // check for null pointer
-        long millis = time.getTime();
-        if (!useDaylightTime()) {
-            return false;
-        }
-        if (daylightSavings == null) {
-            daylightSavings = new GregorianCalendar(this);
-        }
-        return daylightSavings.getOffset(millis + rawOffset) != rawOffset;
+        // BEGIN android-changed: reuse getOffset.
+        return useDaylightTime() && getOffset(time.getTime()) != rawOffset;
         // END android-changed
     }
 
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index 2b35e61..0b6252d 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -17,13 +17,10 @@
 
 package java.util;
 
+import com.ibm.icu4jni.util.ICU;
 import java.io.Serializable;
-
-// BEGIN android-added
 import org.apache.harmony.luni.internal.util.ZoneInfo;
 import org.apache.harmony.luni.internal.util.ZoneInfoDB;
-import com.ibm.icu4jni.util.Resources;
-// END android-added
 
 /**
  * {@code TimeZone} represents a time zone offset, taking into account
@@ -79,281 +76,174 @@
     private static final long serialVersionUID = 3581463369166924961L;
 
     /**
-     * The SHORT display name style.
+     * The short display name style, such as {@code PDT}. Requests for this
+     * style may yield GMT offsets like {@code GMT-08:00}.
      */
     public static final int SHORT = 0;
 
     /**
-     * The LONG display name style.
+     * The long display name style, such as {@code Pacific Daylight Time}.
+     * Requests for this style may yield GMT offsets like {@code GMT-08:00}.
      */
     public static final int LONG = 1;
 
-    // BEGIN android-removed
-    // private static HashMap<String, TimeZone> AvailableZones;
-    // END android-removed
+    static final TimeZone GMT = new SimpleTimeZone(0, "GMT"); // Greenwich Mean Time
 
-    private static TimeZone Default;
-
-    static TimeZone GMT = new SimpleTimeZone(0, "GMT"); // Greenwich Mean Time
+    private static TimeZone defaultTimeZone;
 
     private String ID;
 
-    // BEGIN android-removed
-    // private com.ibm.icu.util.TimeZone icuTimeZone = null;
-    //
-    // private static void initializeAvailable() {
-    //     TimeZone[] zones = TimeZones.getTimeZones();
-    //     AvailableZones = new HashMap<String, TimeZone>(
-    //             (zones.length + 1) * 4 / 3);
-    //     AvailableZones.put(GMT.getID(), GMT);
-    //     for (int i = 0; i < zones.length; i++) {
-    //         AvailableZones.put(zones[i].getID(), zones[i]);
-    //     }
-    //}
-    //
-    // private static boolean isAvailableIDInICU(String name) {
-    //     String[] availableIDs = com.ibm.icu.util.TimeZone.getAvailableIDs();
-    //     for (int i = 0; i < availableIDs.length; i++) {
-    //         if (availableIDs[i].equals(name)) {
-    //             return true;
-    //         }
-    //     }
-    //     return false;
-    // }
-    //
-    // private static void appendAvailableZones(String name) {
-    //     com.ibm.icu.util.TimeZone icuTZ = com.ibm.icu.util.TimeZone
-    //             .getTimeZone(name);
-    //     int raw = icuTZ.getRawOffset();
-    //     TimeZone zone = new SimpleTimeZone(raw, name);
-    //     AvailableZones.put(name, zone);
-    // }
-    // END android-removed
+    public TimeZone() {}
 
     /**
-     * Constructs a new instance of this class.
+     * Returns a new time zone with the same ID, raw offset, and daylight
+     * savings time rules as this time zone.
      */
-    public TimeZone() {
-    }
-
-    /**
-     * Returns a new {@code TimeZone} with the same ID, {@code rawOffset} and daylight savings
-     * time rules as this {@code TimeZone}.
-     *
-     * @return a shallow copy of this {@code TimeZone}.
-     * @see java.lang.Cloneable
-     */
-    @Override
-    public Object clone() {
+    @Override public Object clone() {
         try {
-            TimeZone zone = (TimeZone) super.clone();
-            return zone;
+            return super.clone();
         } catch (CloneNotSupportedException e) {
-            throw new AssertionError(e); // android-changed
+            throw new AssertionError(e);
         }
     }
 
     /**
-     * Gets the available time zone IDs. Any one of these IDs can be passed to
-     * {@code get()} to create the corresponding {@code TimeZone} instance.
-     *
-     * @return an array of time zone ID strings.
+     * Returns the system's installed time zone IDs. Any of these IDs can be
+     * passed to {@link #getTimeZone} to lookup the corresponding time zone
+     * instance.
      */
     public static synchronized String[] getAvailableIDs() {
-        // BEGIN android-changed
-        // return com.ibm.icu.util.TimeZone.getAvailableIDs();
         return ZoneInfoDB.getAvailableIDs();
-        // END android-changed
     }
 
     /**
-     * Gets the available time zone IDs which match the specified offset from
-     * GMT. Any one of these IDs can be passed to {@code get()} to create the corresponding
-     * {@code TimeZone} instance.
+     * Returns the IDs of the time zones whose offset from UTC is {@code
+     * offsetMillis}. Any of these IDs can be passed to {@link #getTimeZone} to
+     * lookup the corresponding time zone instance.
      *
-     * @param offset
-     *            the offset from GMT in milliseconds.
-     * @return an array of time zone ID strings.
+     * @return a possibly-empty array.
      */
-    public static synchronized String[] getAvailableIDs(int offset) {
-        // BEGIN android-changed
-        // String[] availableIDs = com.ibm.icu.util.TimeZone.getAvailableIDs();
-        // int count = 0;
-        // int length = availableIDs.length;
-        // String[] all = new String[length];
-        // for (int i = 0; i < length; i++) {
-        //     com.ibm.icu.util.TimeZone tz = com.ibm.icu.util.TimeZone
-        //             .getTimeZone(availableIDs[i]);
-        //     if (tz.getRawOffset() == offset) {
-        //         all[count++] = tz.getID();
-        //     }
-        // }
-        // String[] answer = new String[count];
-        // System.arraycopy(all, 0, answer, 0, count);
-        // return answer;
-        return ZoneInfoDB.getAvailableIDs(offset);
-        // END android-changed
+    public static synchronized String[] getAvailableIDs(int offsetMillis) {
+        return ZoneInfoDB.getAvailableIDs(offsetMillis);
     }
 
     /**
-     * Gets the default time zone.
+     * Returns the user's preferred time zone. This may have been overridden for
+     * this process with {@link #setDefault}.
      *
-     * @return the default time zone.
+     * <p>Since the user's time zone changes dynamically, avoid caching this
+     * value. Instead, use this method to look it up for each use.
      */
     public static synchronized TimeZone getDefault() {
-        if (Default == null) {
-            // BEGIN android-changed
-            // setDefault(null);
-            Default = ZoneInfoDB.getDefault();
-            // END android-changed
+        if (defaultTimeZone == null) {
+            defaultTimeZone = ZoneInfoDB.getSystemDefault();
         }
-        return (TimeZone) Default.clone();
+        return (TimeZone) defaultTimeZone.clone();
     }
 
     /**
-     * Gets the LONG name for this {@code TimeZone} for the default {@code Locale} in standard
-     * time. If the name is not available, the result is in the format
-     * {@code GMT[+-]hh:mm}.
-     *
-     * @return the {@code TimeZone} name.
+     * Equivalent to {@code getDisplayName(false, TimeZone.LONG, Locale.getDefault())}.
+     * <a href="../util/Locale.html#default_locale">Be wary of the default locale</a>.
      */
     public final String getDisplayName() {
         return getDisplayName(false, LONG, Locale.getDefault());
     }
 
     /**
-     * Gets the LONG name for this {@code TimeZone} for the specified {@code Locale} in standard
-     * time. If the name is not available, the result is in the format
-     * {@code GMT[+-]hh:mm}.
-     *
-     * @param locale
-     *            the {@code Locale}.
-     * @return the {@code TimeZone} name.
+     * Equivalent to {@code getDisplayName(false, TimeZone.LONG, locale)}.
      */
     public final String getDisplayName(Locale locale) {
         return getDisplayName(false, LONG, locale);
     }
 
     /**
-     * Gets the specified style of name ({@code LONG} or {@code SHORT}) for this {@code TimeZone} for
-     * the default {@code Locale} in either standard or daylight time as specified. If
-     * the name is not available, the result is in the format {@code GMT[+-]hh:mm}.
-     *
-     * @param daylightTime
-     *            {@code true} for daylight time, {@code false} for standard
-     *            time.
-     * @param style
-     *            either {@code LONG} or {@code SHORT}.
-     * @return the {@code TimeZone} name.
+     * Equivalent to {@code getDisplayName(daylightTime, style, Locale.getDefault())}.
+     * <a href="../util/Locale.html#default_locale">Be wary of the default locale</a>.
      */
     public final String getDisplayName(boolean daylightTime, int style) {
         return getDisplayName(daylightTime, style, Locale.getDefault());
     }
 
     /**
-     * Gets the specified style of name ({@code LONG} or {@code SHORT}) for this {@code TimeZone} for
-     * the specified {@code Locale} in either standard or daylight time as specified. If
-     * the name is not available, the result is in the format {@code GMT[+-]hh:mm}.
+     * Returns the {@link #SHORT short} or {@link #LONG long} name of this time
+     * zone with either standard or daylight time, as written in {@code locale}.
+     * If the name is not available, the result is in the format
+     * {@code GMT[+-]hh:mm}.
      *
-     * @param daylightTime
-     *            {@code true} for daylight time, {@code false} for standard
-     *            time.
-     * @param style
-     *            either LONG or SHORT.
-     * @param locale
-     *            either {@code LONG} or {@code SHORT}.
-     * @return the {@code TimeZone} name.
+     * @param daylightTime true for daylight time, false for standard time.
+     * @param style either {@link TimeZone#LONG} or {@link TimeZone#SHORT}.
+     * @param locale the display locale.
      */
     public String getDisplayName(boolean daylightTime, int style, Locale locale) {
-        // BEGIN android-changed
-        // if(icuTimeZone == null || !ID.equals(icuTimeZone.getID())){
-        //     icuTimeZone = com.ibm.icu.util.TimeZone.getTimeZone(ID);
-        // }
-        // return icuTimeZone.getDisplayName(
-        //         daylightTime, style, locale);
-        if (style == SHORT || style == LONG) {
-            boolean useDaylight = daylightTime && useDaylightTime();
-
-            String result = Resources.getDisplayTimeZone(getID(), daylightTime, style, locale.toString());
-            if (result != null) {
-                return result;
-            }
-
-            int offset = getRawOffset();
-            if (useDaylight && this instanceof SimpleTimeZone) {
-                offset += ((SimpleTimeZone) this).getDSTSavings();
-            }
-            offset /= 60000;
-            char sign = '+';
-            if (offset < 0) {
-                sign = '-';
-                offset = -offset;
-            }
-            StringBuffer buffer = new StringBuffer(9);
-            buffer.append("GMT");
-            buffer.append(sign);
-            appendNumber(buffer, 2, offset / 60);
-            buffer.append(':');
-            appendNumber(buffer, 2, offset % 60);
-            return buffer.toString();
+        if (style != SHORT && style != LONG) {
+            throw new IllegalArgumentException();
         }
-        throw new IllegalArgumentException();
-        // END android-changed
+
+        boolean useDaylight = daylightTime && useDaylightTime();
+
+        String result = ICU.getDisplayTimeZone(getID(), daylightTime, style,
+                locale.toString());
+        if (result != null) {
+            return result;
+        }
+
+        int offset = getRawOffset();
+        if (useDaylight && this instanceof SimpleTimeZone) {
+            offset += getDSTSavings();
+        }
+        offset /= 60000;
+        char sign = '+';
+        if (offset < 0) {
+            sign = '-';
+            offset = -offset;
+        }
+        StringBuilder builder = new StringBuilder(9);
+        builder.append("GMT");
+        builder.append(sign);
+        appendNumber(builder, 2, offset / 60);
+        builder.append(':');
+        appendNumber(builder, 2, offset % 60);
+        return builder.toString();
     }
 
-    // BEGIN android-added
-    private void appendNumber(StringBuffer buffer, int count, int value) {
+    private void appendNumber(StringBuilder builder, int count, int value) {
         String string = Integer.toString(value);
-        if (count > string.length()) {
-            for (int i = 0; i < count - string.length(); i++) {
-                buffer.append('0');
-            }
+        for (int i = 0; i < count - string.length(); i++) {
+            builder.append('0');
         }
-        buffer.append(string);
+        builder.append(string);
     }
-    // END android-added
 
     /**
-     * Gets the ID of this {@code TimeZone}.
-     *
-     * @return the time zone ID string.
+     * Returns the ID of this {@code TimeZone}, such as
+     * {@code America/Los_Angeles}, {@code GMT-08:00} or {@code UTC}.
      */
     public String getID() {
         return ID;
     }
 
     /**
-     * Gets the daylight savings offset in milliseconds for this {@code TimeZone}.
-     * <p>
-     * This implementation returns 3600000 (1 hour), or 0 if the time zone does
-     * not observe daylight savings.
-     * <p>
-     * Subclasses may override to return daylight savings values other than 1
-     * hour.
-     * <p>
-     * Note that this method doesn't tell you whether or not to apply the offset: you
-     * need to call {@code inDaylightTime} for the specific time you're interested in.
-     * If this method returns a non-zero offset, that only tells you that this
-     * {@code TimeZone} sometimes observes daylight savings.
+     * Returns the daylight savings offset in milliseconds for this time zone.
+     * The base implementation returns {@code 3600000} (1 hour) for time zones
+     * that use daylight savings time and {@code 0} for timezones that do not.
+     * Subclasses should override this method for other daylight savings
+     * offsets.
      *
-     * @return the daylight savings offset in milliseconds if this {@code TimeZone}
-     *         observes daylight savings, zero otherwise.
+     * <p>Note that this method doesn't tell you whether or not to apply the
+     * offset: you need to call {@code inDaylightTime} for the specific time
+     * you're interested in. If this method returns a non-zero offset, that only
+     * tells you that this {@code TimeZone} sometimes observes daylight savings.
      */
     public int getDSTSavings() {
-        if (useDaylightTime()) {
-            return 3600000;
-        }
-        return 0;
+        return useDaylightTime() ? 3600000 : 0;
     }
 
     /**
-     * Gets the offset from GMT of this {@code TimeZone} for the specified date. The
-     * offset includes daylight savings time if the specified date is within the
-     * daylight savings time period.
+     * Returns the offset in milliseconds from UTC for this time zone at {@code
+     * time}. The offset includes daylight savings time if the specified
+     * date is within the daylight savings time period.
      *
-     * @param time
-     *            the date in milliseconds since January 1, 1970 00:00:00 GMT
-     * @return the offset from GMT in milliseconds.
+     * @param time the date in milliseconds since January 1, 1970 00:00:00 UTC
      */
     public int getOffset(long time) {
         if (inDaylightTime(new Date(time))) {
@@ -363,90 +253,72 @@
     }
 
     /**
-     * Gets the offset from GMT of this {@code TimeZone} for the specified date and
-     * time. The offset includes daylight savings time if the specified date and
-     * time are within the daylight savings time period.
+     * Returns this time zone's offset in milliseconds from UTC at the specified
+     * date and time. The offset includes daylight savings time if the date
+     * and time is within the daylight savings time period.
      *
-     * @param era
-     *            the {@code GregorianCalendar} era, either {@code GregorianCalendar.BC} or
-     *            {@code GregorianCalendar.AD}.
-     * @param year
-     *            the year.
-     * @param month
-     *            the {@code Calendar} month.
-     * @param day
-     *            the day of the month.
-     * @param dayOfWeek
-     *            the {@code Calendar} day of the week.
-     * @param time
-     *            the time of day in milliseconds.
-     * @return the offset from GMT in milliseconds.
+     * <p>This method is intended to be used by {@link Calendar} to compute
+     * {@link Calendar#DST_OFFSET} and {@link Calendar#ZONE_OFFSET}. Application
+     * code should have no reason to call this method directly. Each parameter
+     * is interpreted in the same way as the corresponding {@code Calendar}
+     * field. Refer to {@link Calendar} for specific definitions of this
+     * method's parameters.
      */
-    abstract public int getOffset(int era, int year, int month, int day,
-            int dayOfWeek, int time);
+    public abstract int getOffset(int era, int year, int month, int day,
+            int dayOfWeek, int timeOfDayMillis);
 
     /**
-     * Gets the offset for standard time from GMT for this {@code TimeZone}.
-     *
-     * @return the offset from GMT in milliseconds.
+     * Returns the offset in milliseconds from UTC of this time zone's standard
+     * time.
      */
-    abstract public int getRawOffset();
+    public abstract int getRawOffset();
 
     /**
-     * Gets the {@code TimeZone} with the specified ID.
+     * Returns a time zone whose ID is {@code id}. Time zone IDs are typically
+     * named by geographic identifiers like {@code America/Los_Angeles} or GMT
+     * offsets like {@code GMT-8:00}. Three letter IDs like {@code PST} are
+     * supported but should not be used because they is often ambiguous.
      *
-     * @param name
-     *            a time zone string ID.
-     * @return the {@code TimeZone} with the specified ID or null if no {@code TimeZone} with
-     *         the specified ID exists.
+     * @return a time zone with the specified ID, or {@code GMT} if the ID
+     *     is not recognized and cannot be parsed.
      */
-    public static synchronized TimeZone getTimeZone(String name) {
-        // BEGIN android-changed
-        // if (AvailableZones == null) {
-        //     initializeAvailable();
-        // }
-        //
-        // TimeZone zone = AvailableZones.get(name);
-        // if(zone == null && isAvailableIDInICU(name)){
-        //     appendAvailableZones(name);
-        //     zone = AvailableZones.get(name);
-        // }
-        TimeZone zone = ZoneInfo.getTimeZone(name);
-        // END android-changed
-        if (zone == null) {
-            if (name.startsWith("GMT") && name.length() > 3) {
-                char sign = name.charAt(3);
-                if (sign == '+' || sign == '-') {
-                    int[] position = new int[1];
-                    String formattedName = formatTimeZoneName(name, 4);
-                    int hour = parseNumber(formattedName, 4, position);
-                    if (hour < 0 || hour > 23) {
-                        return (TimeZone) GMT.clone();
-                    }
-                    int index = position[0];
-                    if (index != -1) {
-                        int raw = hour * 3600000;
-                        if (index < formattedName.length()
-                                && formattedName.charAt(index) == ':') {
-                            int minute = parseNumber(formattedName, index + 1,
-                                    position);
-                            if (position[0] == -1 || minute < 0 || minute > 59) {
-                                return (TimeZone) GMT.clone();
-                            }
-                            raw += minute * 60000;
-                        } else if (hour >= 30 || index > 6) {
-                            raw = (hour / 100 * 3600000) + (hour % 100 * 60000);
-                        }
-                        if (sign == '-') {
-                            raw = -raw;
-                        }
-                        return new SimpleTimeZone(raw, formattedName);
-                    }
-                }
-            }
-            zone = GMT;
+    public static synchronized TimeZone getTimeZone(String id) {
+        TimeZone zone = ZoneInfo.getTimeZone(id);
+        if (zone != null) {
+            return (TimeZone) zone.clone();
         }
-        return (TimeZone) zone.clone();
+
+        if (!id.startsWith("GMT") || id.length() <= 3) {
+            return (TimeZone) GMT.clone();
+        }
+        char sign = id.charAt(3);
+        if (sign != '+' && sign != '-') {
+            return (TimeZone) GMT.clone();
+        }
+        int[] position = new int[1];
+        String formattedName = formatTimeZoneName(id, 4);
+        int hour = parseNumber(formattedName, 4, position);
+        if (hour < 0 || hour > 23) {
+            return (TimeZone) GMT.clone();
+        }
+        int index = position[0];
+        if (index == -1) {
+            return (TimeZone) GMT.clone();
+        }
+        int raw = hour * 3600000;
+        if (index < formattedName.length() && formattedName.charAt(index) == ':') {
+            int minute = parseNumber(formattedName, index + 1, position);
+            if (position[0] == -1 || minute < 0 || minute > 59) {
+                return (TimeZone) GMT.clone();
+            }
+            raw += minute * 60000;
+        } else if (hour >= 30 || index > 6) {
+            raw = (hour / 100 * 3600000) + (hour % 100 * 60000);
+        }
+        if (sign == '-') {
+            raw = -raw;
+        }
+        return new SimpleTimeZone(raw, formattedName);
     }
 
     private static String formatTimeZoneName(String name, int offset) {
@@ -479,31 +351,23 @@
     }
 
     /**
-     * Returns whether the specified {@code TimeZone} has the same raw offset as this
-     * {@code TimeZone}.
+     * Returns true if {@code timeZone} has the same rules as this time zone.
      *
-     * @param zone
-     *            a {@code TimeZone}.
-     * @return {@code true} when the {@code TimeZone} have the same raw offset, {@code false}
-     *         otherwise.
+     * <p>The base implementation returns true if both time zones have the same
+     * raw offset.
      */
-    public boolean hasSameRules(TimeZone zone) {
-        if (zone == null) {
+    public boolean hasSameRules(TimeZone timeZone) {
+        if (timeZone == null) {
             return false;
         }
-        return getRawOffset() == zone.getRawOffset();
+        return getRawOffset() == timeZone.getRawOffset();
     }
 
     /**
-     * Returns whether the specified {@code Date} is in the daylight savings time period for
-     * this {@code TimeZone}.
-     *
-     * @param time
-     *            a {@code Date}.
-     * @return {@code true} when the {@code Date} is in the daylight savings time period, {@code false}
-     *         otherwise.
+     * Returns true if {@code time} is in a daylight savings time period for
+     * this time zone.
      */
-    abstract public boolean inDaylightTime(Date time);
+    public abstract boolean inDaylightTime(Date time);
 
     private static int parseNumber(String string, int offset, int[] position) {
         int index = offset, length = string.length(), digit, result = 0;
@@ -517,154 +381,47 @@
     }
 
     /**
-     * Sets the default time zone. If passed {@code null}, then the next
-     * time {@link #getDefault} is called, the default time zone will be
-     * determined. This behavior is slightly different than the canonical
-     * description of this method, but it follows the spirit of it.
+     * Overrides the default time zone for the current process only.
      *
-     * @param timezone
-     *            a {@code TimeZone} object.
+     * <p><strong>Warning</strong>: avoid using this method to use a custom time
+     * zone in your process. This value may be cleared or overwritten at any
+     * time, which can cause unexpected behavior. Instead, manually supply a
+     * custom time zone as needed.
+     *
+     * @param timeZone a custom time zone, or {@code null} to set the default to
+     *     the user's preferred value.
      */
-    public static synchronized void setDefault(TimeZone timezone) {
-        // BEGIN android-removed
-        // if (timezone != null) {
-        //     setICUDefaultTimeZone(timezone);
-        //     Default = timezone;
-        //     return;
-        // }
-        //
-        // String zone = AccessController.doPrivileged(new PriviAction<String>(
-        //         "user.timezone"));
-        //
-        // // sometimes DRLVM incorrectly adds "\n" to the end of timezone ID
-        // if (zone != null && zone.contains("\n")) {
-        //     zone = zone.substring(0, zone.indexOf("\n"));
-        // }
-        //
-        // // if property user.timezone is not set, we call the native method
-        // // getCustomTimeZone
-        // if (zone == null || zone.length() == 0) {
-        //     int[] tzinfo = new int[10];
-        //     boolean[] isCustomTimeZone = new boolean[1];
-        //
-        //     String zoneId = getCustomTimeZone(tzinfo, isCustomTimeZone);
-        //
-        //     // if returned TimeZone is a user customized TimeZone
-        //     if (isCustomTimeZone[0]) {
-        //         // build a new SimpleTimeZone
-        //         switch (tzinfo[1]) {
-        //         case 0:
-        //             // does not observe DST
-        //             Default = new SimpleTimeZone(tzinfo[0], zoneId);
-        //             break;
-        //         default:
-        //             // observes DST
-        //             Default = new SimpleTimeZone(tzinfo[0], zoneId, tzinfo[5],
-        //                     tzinfo[4], tzinfo[3], tzinfo[2], tzinfo[9],
-        //                     tzinfo[8], tzinfo[7], tzinfo[6], tzinfo[1]);
-        //         }
-        //     } else {
-        //         // get TimeZone
-        //         Default = getTimeZone(zoneId);
-        //     }
-        // } else {
-        //     // if property user.timezone is set in command line (with -D option)
-        //     Default = getTimeZone(zone);
-        // }
-        // setICUDefaultTimeZone(Default);
-        // END android-removed
-
-        // BEGIN android-added
-        Default = timezone;
-
-        // TODO Not sure if this is spec-compliant. Shouldn't be persistent.
-        ZoneInfoDB.setDefault(timezone);
-        // END android-added
+    public static synchronized void setDefault(TimeZone timeZone) {
+        defaultTimeZone = timeZone != null ? (TimeZone) timeZone.clone() : null;
     }
 
-    // BEGIN android-removed
-    // private static void setICUDefaultTimeZone(TimeZone timezone) {
-    //     final com.ibm.icu.util.TimeZone icuTZ = com.ibm.icu.util.TimeZone
-    //             .getTimeZone(timezone.getID());
-    //
-    //     AccessController
-    //             .doPrivileged(new PrivilegedAction<java.lang.reflect.Field>() {
-    //                 public java.lang.reflect.Field run() {
-    //                     java.lang.reflect.Field field = null;
-    //                     try {
-    //                         field = com.ibm.icu.util.TimeZone.class
-    //                                 .getDeclaredField("defaultZone");
-    //                         field.setAccessible(true);
-    //                         field.set("defaultZone", icuTZ);
-    //                     } catch (Exception e) {
-    //                         return null;
-    //                     }
-    //                     return field;
-    //                 }
-    //             });
-    // }
-    // END android-removed
-
     /**
      * Sets the ID of this {@code TimeZone}.
-     *
-     * @param name
-     *            a string which is the time zone ID.
      */
-    public void setID(String name) {
-        if (name == null) {
+    public void setID(String id) {
+        if (id == null) {
             throw new NullPointerException();
         }
-        ID = name;
+        ID = id;
     }
 
     /**
-     * Sets the offset for standard time from GMT for this {@code TimeZone}.
-     *
-     * @param offset
-     *            the offset from GMT in milliseconds.
+     * Sets the offset in milliseconds from UTC of this time zone's standard
+     * time.
      */
-    abstract public void setRawOffset(int offset);
+    public abstract void setRawOffset(int offsetMillis);
 
     /**
-     * Returns whether this {@code TimeZone} has a daylight savings time period.
-     * 
+     * Returns true if this time zone has a daylight savings time period. More
+     * specifically, this method returns true to indicate that there's at least
+     * one known future transition to or from daylight savings. This means that,
+     * say, Taiwan will return false because its historical use of daylight
+     * savings doesn't count. A hypothetical country that has never observed
+     * daylight savings before but plans to start next year would return true.
+     *
      * <p>If this method returns true, that only tells you that this
      * {@code TimeZone} sometimes observes daylight savings. You need to call
      * {@code inDaylightTime} to find out whether daylight savings is in effect.
-     *
-     * <p>More specifically, this method returns true to indicate that there's
-     * at least one known future transition to or from daylight savings. This
-     * means that, say, Taiwan will return false because its historical use of
-     * daylight savings doesn't count. A hypothetical country that has never
-     * observed daylight savings before but plans to start next year would return
-     * true.
-     * 
-     * @return {@code true} if this {@code TimeZone} has a daylight savings time period, {@code false}
-     *         otherwise.
      */
-    abstract public boolean useDaylightTime();
-
-    /**
-     * Gets the name and the details of the user-selected TimeZone on the
-     * device.
-     *
-     * @param tzinfo
-     *            int array of 10 elements to be filled with the TimeZone
-     *            information. Once filled, the contents of the array are
-     *            formatted as follows: tzinfo[0] -> the timezone offset;
-     *            tzinfo[1] -> the dst adjustment; tzinfo[2] -> the dst start
-     *            hour; tzinfo[3] -> the dst start day of week; tzinfo[4] -> the
-     *            dst start week of month; tzinfo[5] -> the dst start month;
-     *            tzinfo[6] -> the dst end hour; tzinfo[7] -> the dst end day of
-     *            week; tzinfo[8] -> the dst end week of month; tzinfo[9] -> the
-     *            dst end month;
-     * @param isCustomTimeZone
-     *            boolean array of size 1 that indicates if a timezone match is
-     *            found
-     * @return the name of the TimeZone or null if error occurs in native
-     *         method.
-     */
-    private static native String getCustomTimeZone(int[] tzinfo,
-            boolean[] isCustomTimeZone);
+    public abstract boolean useDaylightTime();
 }
diff --git a/luni/src/main/java/java/util/TreeMap.java b/luni/src/main/java/java/util/TreeMap.java
index bfacc38..7075cec 100644
--- a/luni/src/main/java/java/util/TreeMap.java
+++ b/luni/src/main/java/java/util/TreeMap.java
@@ -1,2410 +1,1664 @@
 /*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
+ * Copyright (C) 2010 The Android Open Source Project
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package java.util;
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
 import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
 import java.io.Serializable;
+import static java.util.TreeMap.Bound.EXCLUSIVE;
+import static java.util.TreeMap.Bound.INCLUSIVE;
+import static java.util.TreeMap.Bound.NO_BOUND;
+import static java.util.TreeMap.Relation.CEILING;
+import static java.util.TreeMap.Relation.EQUAL;
+import static java.util.TreeMap.Relation.FLOOR;
+import static java.util.TreeMap.Relation.HIGHER;
+import static java.util.TreeMap.Relation.LOWER;
 
 /**
- * TreeMap is an implementation of SortedMap. All optional operations (adding
- * and removing) are supported. The values can be any objects. The keys can be
- * any objects which are comparable to each other either using their natural
- * order or a specified Comparator.
+ * A map whose entries are sorted by their keys. All optional operations such as
+ * {@link #put} and {@link #remove} are supported.
+ *
+ * <p>This map sorts keys using either a user-supplied comparator or the key's
+ * natural order:
+ * <ul>
+ *   <li>User supplied comparators must be able to compare any pair of keys in
+ *       this map. If a user-supplied comparator is in use, it will be returned
+ *       by {@link #comparator}.
+ *   <li>If no user-supplied comparator is supplied, keys will be sorted by
+ *       their natural order. Keys must be <i>mutually comparable</i>: they must
+ *       implement {@link Comparable} and {@link Comparable#compareTo
+ *       compareTo()} must be able to compare each key with any other key in
+ *       this map. In this case {@link #comparator} will return null.
+ * </ul>
+ * With either a comparator or a natural ordering, comparisons should be
+ * <i>consistent with equals</i>. An ordering is consistent with equals if for
+ * every pair of keys {@code a} and {@code b}, {@code a.equals(b)} if and only
+ * if {@code compare(a, b) == 0}.
+ *
+ * <p>When the ordering is not consistent with equals the behavior of this
+ * class is well defined but does not honor the contract specified by {@link
+ * Map}. Consider a tree map of case-insensitive strings, an ordering that is
+ * not consistent with equals: <pre>   {@code
+ *   TreeMap<String, String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+ *   map.put("a", "android");
+ *
+ *   // The Map API specifies that the next line should print "null" because
+ *   // "a".equals("A") is false and there is no mapping for upper case "A".
+ *   // But the case insensitive ordering says compare("a", "A") == 0. TreeMap
+ *   // uses only comparators/comparable on keys and so this prints "android".
+ *   System.out.println(map.get("A"));
+ * }</pre>
  *
  * @since 1.2
  */
-public class TreeMap <K, V> extends AbstractMap<K, V> implements SortedMap<K, V>,
-                                                        Cloneable, Serializable {
-    private static final long serialVersionUID = 919286545866124006L;
+public class TreeMap<K, V> extends AbstractMap<K, V>
+        implements SortedMap<K, V>, NavigableMap<K, V>, Cloneable, Serializable {
 
-    transient int size;
-
-    private Comparator<? super K> comparator;
-
-    transient int modCount;
-
-    transient Set<Map.Entry<K, V>> entrySet;
-
-    transient Node<K, V> root;
-    
-class MapEntry implements Map.Entry<K, V>, Cloneable {
-		
-		final int offset;
-		final Node<K, V> node;
-		final K key;
-		
-	    MapEntry(Node<K, V> node, int offset) {
-	    	this.node = node;
-	    	this.offset = offset;
-	    	key = node.keys[offset];
-	    }
-
-	    @Override
-	    public Object clone() {
-	        try {
-	            return super.clone();
-	        } catch (CloneNotSupportedException e) {
-                throw new AssertionError(e); // android-changed
-	        }
-	    }
-
-	    @Override
-	    public boolean equals(Object object) {
-	        if (this == object) {
-	            return true;
-	        }
-	        if (object instanceof Map.Entry) {
-	            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;	            
-	            V value = getValue();
-	            return (key == null ? entry.getKey() == null : key.equals(entry
-	                    .getKey()))
-	                    && (value == null ? entry.getValue() == null : value
-	                            .equals(entry.getValue()));
-	        }
-	        return false;
-	    }
-
-	    public K getKey() {
-	        return key;
-	    }
-
-	    public V getValue() {
-	    	if (node.keys[offset] == key) {
-	    		return node.values[offset];
-	    	}
-	    	if (containsKey(key)) {
-	    		return get(key);
-	    	}
-	    	throw new IllegalStateException();
-	    }
-
-	    @Override
-	    public int hashCode() {
-	    	V value = getValue();
-	        return (key == null ? 0 : key.hashCode())
-	                ^ (value == null ? 0 : value.hashCode());
-	    }
-
-	    public V setValue(V object) {
-	    	if (node.keys[offset] == key) {
-	    		V res = node.values[offset];
-	    		node.values[offset] = object;
-	    		return res;
-	    	}
-	    	if (containsKey(key)) {
-	    		return put(key, object);
-	    	}
-	    	throw new IllegalStateException();
-	    }
-
-	    @Override
-	    public String toString() {
-	        return key + "=" + getValue();
-	    }
-	}
-
-    static class Node <K,V> implements Cloneable {
-        static final int NODE_SIZE = 64;
-        Node<K, V> prev, next;
-        Node<K, V> parent, left, right;
-        V[] values;
-        K[] keys;
-        int left_idx = 0;
-        int right_idx = -1;
-        int size = 0;
-        boolean color;
-
-        public Node() {
-            keys = (K[]) new Object[NODE_SIZE];
-            values = (V[]) new Object[NODE_SIZE];
+    @SuppressWarnings("unchecked") // to avoid Comparable<Comparable<Comparable<...>>>
+    private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
+        public int compare(Comparable a, Comparable b) {
+            return a.compareTo(b);
         }
+    };
 
-        @SuppressWarnings("unchecked")
-        Node<K, V> clone(Node<K, V> parent) throws CloneNotSupportedException {
-            Node<K, V> clone = (Node<K, V>) super.clone();
-            clone.keys   = (K[]) new Object[NODE_SIZE];
-            clone.values = (V[]) new Object[NODE_SIZE];
-            System.arraycopy(keys,   0, clone.keys,   0, keys.length);
-            System.arraycopy(values, 0, clone.values, 0, values.length);
-            clone.left_idx  = left_idx;
-            clone.right_idx = right_idx;
-            clone.parent = parent;
-            if (left != null) {
-                clone.left = left.clone(clone);
-            }
-            if (right != null) {
-                clone.right = right.clone(clone);
-            }
-            clone.prev = null;
-            clone.next = null;
-            return clone;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-     private static <T> Comparable<T> toComparable(T obj) {
-        if (obj == null) {
-            throw new NullPointerException();
-        }
-        return (Comparable) obj;
-    }
-
-    static class AbstractMapIterator <K,V> {
-        TreeMap<K, V> backingMap;
-        int expectedModCount;
-        Node<K, V> node;
-        Node<K, V> lastNode;
-        int offset;
-        int lastOffset;
-
-        AbstractMapIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
-            backingMap = map;
-            expectedModCount = map.modCount;
-            node = startNode;
-            offset = startOffset;
-        }
-
-        AbstractMapIterator(TreeMap<K, V> map, Node<K, V> startNode) {
-            this(map, startNode, startNode != null ?
-                                 startNode.right_idx - startNode.left_idx : 0);
-        }
-
-        AbstractMapIterator(TreeMap<K, V> map) {
-            this(map, minimum(map.root));
-        }
-
-        public boolean hasNext() {
-            return node != null;
-        }
-
-        final void makeNext() {
-            if (expectedModCount != backingMap.modCount) {
-                throw new ConcurrentModificationException();
-            } else if (node == null) {
-                throw new NoSuchElementException();
-            }
-            lastNode = node;
-            lastOffset = offset;
-            if (offset != 0) {
-                offset--;
-            } else {
-                node = node.next;
-                if (node != null) {
-                    offset = node.right_idx - node.left_idx;
-                }
-            }
-        }
-
-        final public void remove() {
-            if (expectedModCount == backingMap.modCount) {
-                if (lastNode != null) {
-                    int idx = lastNode.right_idx - lastOffset;
-                    backingMap.removeFromIterator(lastNode, idx);
-                    lastNode = null;
-                    expectedModCount++;
-                } else {
-                    throw new IllegalStateException();
-                }
-            } else {
-                throw new ConcurrentModificationException();
-            }
-        }
-    }
-
-    static class UnboundedEntryIterator <K, V> extends AbstractMapIterator<K, V>
-                                            implements Iterator<Map.Entry<K, V>> {
-
-        UnboundedEntryIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
-            super(map, startNode, startOffset);
-        }
-
-        UnboundedEntryIterator(TreeMap<K, V> map) {
-            super(map);
-        }
-
-        public Map.Entry<K, V> next() {
-            makeNext();
-            int idx = lastNode.right_idx - lastOffset;
-            return backingMap.new MapEntry(lastNode, idx);
-        }
-    }
-
-    static class UnboundedKeyIterator <K, V> extends AbstractMapIterator<K, V>
-                                                          implements Iterator<K> {
-
-        UnboundedKeyIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
-            super(map, startNode, startOffset);
-        }
-
-        UnboundedKeyIterator(TreeMap<K, V> map) {
-            super(map);
-        }
-
-        public K next() {
-            makeNext();
-            return lastNode.keys[lastNode.right_idx - lastOffset];
-        }
-    }
-
-    static class UnboundedValueIterator <K, V> extends AbstractMapIterator<K, V>
-                                                          implements Iterator<V> {
-
-        UnboundedValueIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
-            super(map, startNode, startOffset);
-        }
-
-        UnboundedValueIterator(TreeMap<K, V> map) {
-            super(map);
-        }
-
-        public V next() {
-            makeNext();
-            return lastNode.values[lastNode.right_idx - lastOffset];
-        }
-    }
-
-    static class BoundedMapIterator <K, V> extends AbstractMapIterator<K, V> {
-
-        Node<K, V> finalNode;
-        int finalOffset;
-
-        BoundedMapIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
-                           Node<K, V> finalNode, int finalOffset) {
-            super(map, finalNode==null? null : startNode, startOffset);
-            this.finalNode = finalNode;
-            this.finalOffset = finalOffset;
-        }
-
-        BoundedMapIterator(Node<K, V> startNode, TreeMap<K, V> map,
-                           Node<K, V> finalNode, int finalOffset) {
-            this(startNode, startNode != null ?
-                            startNode.right_idx - startNode.left_idx : 0,
-                            map, finalNode, finalOffset);
-        }
-
-        BoundedMapIterator(Node<K, V> startNode, int startOffset,
-                           TreeMap<K, V> map, Node<K, V> finalNode) {
-            this(startNode, startOffset, map, finalNode,
-                         finalNode.right_idx - finalNode.left_idx);
-        }
-
-        void makeBoundedNext() {
-            makeNext();
-            if (lastNode == finalNode && lastOffset == finalOffset) {
-                node = null;
-            }
-        }
-    }
-
-    static class BoundedEntryIterator <K, V> extends BoundedMapIterator<K, V>
-                                          implements Iterator<Map.Entry<K, V>> {
-
-        public BoundedEntryIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
-                                    Node<K, V> finalNode, int finalOffset) {
-            super(startNode, startOffset, map, finalNode, finalOffset);
-        }
-
-        public Map.Entry<K, V> next() {
-            makeBoundedNext();
-            int idx = lastNode.right_idx - lastOffset;
-            return backingMap.new MapEntry(lastNode, idx);
-        }
-    }
-
-    static class BoundedKeyIterator <K, V> extends BoundedMapIterator<K, V>
-                                                     implements Iterator<K> {
-
-        public BoundedKeyIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
-                                  Node<K, V> finalNode, int finalOffset) {
-            super(startNode, startOffset, map, finalNode, finalOffset);
-        }
-
-        public K next() {
-            makeBoundedNext();
-            return lastNode.keys[lastNode.right_idx - lastOffset];
-        }
-    }
-
-    static class BoundedValueIterator <K, V> extends BoundedMapIterator<K, V>
-                                                       implements Iterator<V> {
-
-        public BoundedValueIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
-                                    Node<K, V> finalNode, int finalOffset) {
-            super(startNode, startOffset, map, finalNode, finalOffset);
-        }
-
-        public V next() {
-            makeBoundedNext();
-            return lastNode.values[lastNode.right_idx - lastOffset];
-        }
-    }
-
-    static final class SubMap <K,V> extends AbstractMap<K, V>
-                                 implements SortedMap<K, V>, Serializable {
-        private static final long serialVersionUID = -6520786458950516097L;
-
-        private TreeMap<K, V> backingMap;
-
-        boolean hasStart, hasEnd;
-        K startKey, endKey;
-        transient Set<Map.Entry<K, V>> entrySet = null;
-        transient int firstKeyModCount = -1;
-        transient int lastKeyModCount = -1;
-        transient Node<K, V> firstKeyNode;
-        transient int firstKeyIndex;
-        transient Node<K, V> lastKeyNode;
-        transient int lastKeyIndex;
-
-        SubMap(K start, TreeMap<K, V> map) {
-            backingMap = map;
-            hasStart = true;
-            startKey = start;
-        }
-
-        SubMap(K start, TreeMap<K, V> map, K end) {
-            backingMap = map;
-            hasStart = hasEnd = true;
-            startKey = start;
-            endKey = end;
-        }
-
-        SubMap(TreeMap<K, V> map, K end) {
-            backingMap = map;
-            hasEnd = true;
-            endKey = end;
-        }
-
-        private void checkRange(K key) {
-            Comparator<? super K> cmp = backingMap.comparator;
-            if (cmp == null) {
-                Comparable<K> object = toComparable(key);
-                if (hasStart && object.compareTo(startKey) < 0) {
-                    throw new IllegalArgumentException();
-                }
-                if (hasEnd && object.compareTo(endKey) > 0) {
-                    throw new IllegalArgumentException();
-                }
-            } else {
-                if (hasStart
-                    && backingMap.comparator().compare(key, startKey) < 0) {
-                    throw new IllegalArgumentException();
-                }
-                if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) {
-                    throw new IllegalArgumentException();
-                }
-            }
-        }
-
-        private boolean isInRange(K key) {
-            Comparator<? super K> cmp = backingMap.comparator;
-            if (cmp == null) {
-                Comparable<K> object = toComparable(key);
-                if (hasStart && object.compareTo(startKey) < 0) {
-                    return false;
-                }
-                if (hasEnd && object.compareTo(endKey) >= 0) {
-                    return false;
-                }
-            } else {
-                if (hasStart && cmp.compare(key, startKey) < 0) {
-                    return false;
-                }
-                if (hasEnd && cmp.compare(key, endKey) >= 0) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private boolean checkUpperBound(K key) {
-            if (hasEnd) {
-                Comparator<? super K> cmp = backingMap.comparator;
-                if (cmp == null) {
-                    return (toComparable(key).compareTo(endKey) < 0);
-                }
-                return (cmp.compare(key, endKey) < 0);
-            }
-            return true;
-        }
-
-        private boolean checkLowerBound(K key) {
-            if (hasStart) {
-                Comparator<? super K> cmp = backingMap.comparator;
-                if (cmp == null) {
-                    return (toComparable(key).compareTo(startKey) >= 0);
-                }
-                return (cmp.compare(key, startKey) >= 0);
-            }
-            return true;
-        }
-
-        public Comparator<? super K> comparator() {
-            return backingMap.comparator();
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public boolean containsKey(Object key) {
-            if (isInRange((K) key)) {
-                return backingMap.containsKey(key);
-            }
-            return false;
-        }
-
-        @Override
-         public void clear() {
-            keySet().clear();
-        }
-
-        @Override
-         public boolean containsValue(Object value) {
-            Iterator<V> it = values().iterator();
-            if (value != null) {
-                while (it.hasNext()) {
-                    if (value.equals(it.next())) {
-                        return true;
-                    }
-                }
-            } else {
-                while (it.hasNext()) {
-                    if (it.next() == null) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public Set<Map.Entry<K, V>> entrySet() {
-            if (entrySet == null) {
-                entrySet = new SubMapEntrySet<K, V>(this);
-            }
-            return entrySet;
-        }
-
-        private void setFirstKey() {
-            if (firstKeyModCount == backingMap.modCount) {
-                return;
-            }
-            Comparable<K> object = backingMap.comparator == null ?
-                                   toComparable((K) startKey) : null;
-            K key = (K) startKey;
-            Node<K, V> node = backingMap.root;
-            Node<K, V> foundNode = null;
-            int foundIndex = -1;
-            TOP_LOOP:
-            while (node != null) {
-                K[] keys = node.keys;
-                int left_idx = node.left_idx;
-                int result = backingMap.cmp(object, key, keys[left_idx]);
-                if (result < 0) {
-                    foundNode = node;
-                    foundIndex = left_idx;
-                    node = node.left;
-                } else if (result == 0) {
-                    foundNode = node;
-                    foundIndex = left_idx;
-                    break;
-                } else {
-                    int right_idx = node.right_idx;
-                    if (left_idx != right_idx) {
-                        result = backingMap.cmp(object, key, keys[right_idx]);
-                    }
-                    if (result > 0) {
-                        node = node.right;
-                    } else if (result == 0) {
-                        foundNode = node;
-                        foundIndex = right_idx;
-                        break;
-                    } else { /*search in node*/
-                        foundNode = node;
-                        foundIndex = right_idx;
-                        int low = left_idx + 1, mid = 0, high = right_idx - 1;
-                        while (low <= high) {
-                            mid = (low + high) >>> 1;
-                            result = backingMap.cmp(object, key, keys[mid]);
-                            if (result > 0) {
-                                low = mid + 1;
-                            } else if (result == 0) {
-                                foundNode = node;
-                                foundIndex = mid;
-                                break TOP_LOOP;
-                            } else {
-                                foundNode = node;
-                                foundIndex = mid;
-                                high = mid - 1;
-                            }
-                        }
-                        break TOP_LOOP;
-                    }
-                }
-            }
-            if (foundNode != null && !checkUpperBound(foundNode.keys[foundIndex])) {
-                foundNode = null;
-            }
-            firstKeyNode = foundNode;
-            firstKeyIndex = foundIndex;
-            firstKeyModCount = backingMap.modCount;
-        }
-
-        public K firstKey() {
-            if (backingMap.size > 0) {
-                if (!hasStart) {
-                    Node<K, V> node = minimum(backingMap.root);
-                    if (node != null && checkUpperBound(node.keys[node.left_idx])) {
-                        return node.keys[node.left_idx];
-                    }
-                } else {
-                    setFirstKey();
-                    if (firstKeyNode != null) {
-                        return firstKeyNode.keys[firstKeyIndex];
-                    }
-                }
-            }
-            throw new NoSuchElementException();
-        }
-
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public V get(Object key) {
-            if (isInRange((K) key)) {
-                return backingMap.get(key);
-            }
-            return null;
-        }
-
-        public SortedMap<K, V> headMap(K endKey) {
-            checkRange(endKey);
-            if (hasStart) {
-                return new SubMap<K, V>(startKey, backingMap, endKey);
-            }
-            return new SubMap<K, V>(backingMap, endKey);
-        }
-
-        @Override
-        public boolean isEmpty() {
-            if (hasStart) {
-                setFirstKey();
-                return firstKeyNode == null;
-            } else {
-                setLastKey();
-                return lastKeyNode == null;
-            }
-        }
-
-        @Override
-        public Set<K> keySet() {
-            if (keySet == null) {
-                keySet = new SubMapKeySet<K, V>(this);
-            }
-            return keySet;
-        }
-
-        private void setLastKey() {
-            if (lastKeyModCount == backingMap.modCount) {
-                return;
-            }
-            Comparable<K> object = backingMap.comparator == null ?
-                                   toComparable((K) endKey) : null;
-            K key = (K) endKey;
-            Node<K, V> node = backingMap.root;
-            Node<K, V> foundNode = null;
-            int foundIndex = -1;
-            TOP_LOOP:
-            while (node != null) {
-                K[] keys = node.keys;
-                int left_idx = node.left_idx;
-                int result = backingMap.cmp(object, key, keys[left_idx]);
-                if (result <= 0) {
-                    node = node.left;
-                } else {
-                    int right_idx = node.right_idx;
-                    if (left_idx != right_idx) {
-                        result = backingMap.cmp(object, key, keys[right_idx]);
-                    }
-                    if (result > 0) {
-                        foundNode = node;
-                        foundIndex = right_idx;
-                        node = node.right;
-                    } else if (result == 0) {
-                        if (node.left_idx == node.right_idx) {
-                            foundNode = node.prev;
-                            if (foundNode != null) {
-                                foundIndex = foundNode.right_idx - 1;
-                            }
-                        } else {
-                            foundNode = node;
-                            foundIndex = right_idx - 1;
-                        }
-                        break;
-                    } else { /*search in node*/
-                        foundNode = node;
-                        foundIndex = left_idx;
-                        int low = left_idx + 1, mid = 0, high = right_idx - 1;
-                        while (low <= high) {
-                            mid = (low + high) >>> 1;
-                            result = backingMap.cmp(object, key, keys[mid]);
-                            if (result > 0) {
-                                foundNode = node;
-                                foundIndex = mid;
-                                low = mid + 1;
-                            } else if (result == 0) {
-                                foundNode = node;
-                                foundIndex = mid - 1;
-                                break TOP_LOOP;
-                            } else {
-                                high = mid - 1;
-                            }
-                        }
-                        break TOP_LOOP;
-                    }
-                }
-            }
-            if (foundNode != null && !checkLowerBound(foundNode.keys[foundIndex])) {
-                foundNode = null;
-            }
-            lastKeyNode = foundNode;
-            lastKeyIndex = foundIndex;
-            lastKeyModCount = backingMap.modCount;
-        }
-
-        public K lastKey() {
-            if (backingMap.size > 0) {
-                if (!hasEnd) {
-                    Node<K, V> node = maximum(backingMap.root);
-                    if (node != null && checkLowerBound(node.keys[node.right_idx])) {
-                        return node.keys[node.right_idx];
-                    }
-                } else {
-                    setLastKey();
-                    if (lastKeyNode != null) {
-                        return lastKeyNode.keys[lastKeyIndex];
-                    }
-                }
-            }
-            throw new NoSuchElementException();
-        }
-
-
-        @Override
-        public V put(K key, V value) {
-            if (isInRange(key)) {
-                return backingMap.put(key, value);
-            }
-            throw new IllegalArgumentException();
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public V remove(Object key) {
-            if (isInRange((K) key)) {
-                return backingMap.remove(key);
-            }
-            return null;
-        }
-
-        public SortedMap<K, V> subMap(K startKey, K endKey) {
-            checkRange(startKey);
-            checkRange(endKey);
-            Comparator<? super K> c = backingMap.comparator();
-            if (c == null) {
-                if (toComparable(startKey).compareTo(endKey) <= 0) {
-                    return new SubMap<K, V>(startKey, backingMap, endKey);
-                }
-            } else {
-                if (c.compare(startKey, endKey) <= 0) {
-                    return new SubMap<K, V>(startKey, backingMap, endKey);
-                }
-            }
-            throw new IllegalArgumentException();
-        }
-
-        public SortedMap<K, V> tailMap(K startKey) {
-            checkRange(startKey);
-            if (hasEnd) {
-                return new SubMap<K, V>(startKey, backingMap, endKey);
-            }
-            return new SubMap<K, V>(startKey, backingMap);
-        }
-
-        @Override
-        public Collection<V> values() {
-            if (valuesCollection == null) {
-                valuesCollection = new SubMapValuesCollection<K, V>(this);
-            }
-            return valuesCollection;
-        }
-
-        public int size() {
-            Node<K, V> from, to;
-            int fromIndex, toIndex;
-            if (hasStart) {
-                setFirstKey();
-                from = firstKeyNode;
-                fromIndex = firstKeyIndex;
-            } else {
-                from = minimum(backingMap.root);
-                fromIndex = from == null ? 0 : from.left_idx;
-            }
-            if (from == null) {
-                return 0;
-            }
-            if (hasEnd) {
-                setLastKey();
-                to = lastKeyNode;
-                toIndex = lastKeyIndex;
-            } else {
-                to = maximum(backingMap.root);
-                toIndex = to == null ? 0 : to.right_idx;
-            }
-            if (to == null) {
-                return 0;
-            }
-            if (from == to) {
-                return toIndex - fromIndex + 1;
-            }
-            int sum = 0;
-            while (from != to) {
-                sum += (from.right_idx - fromIndex + 1);
-                from = from.next;
-                fromIndex = from.left_idx;
-            }
-            return sum + toIndex - fromIndex + 1;
-        }
-
-        private void readObject(ObjectInputStream stream) throws IOException,
-                                                                 ClassNotFoundException {
-            stream.defaultReadObject();
-            firstKeyModCount = -1;
-            lastKeyModCount = -1;
-        }
-    }
-
-    static class SubMapEntrySet <K,V> extends AbstractSet<Map.Entry<K, V>>
-                                                implements Set<Map.Entry<K, V>> {
-        SubMap<K, V> subMap;
-
-        SubMapEntrySet(SubMap<K, V> map) {
-            subMap = map;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return subMap.isEmpty();
-        }
-
-        public Iterator<Map.Entry<K, V>> iterator() {
-            Node<K, V> from;
-            int fromIndex;
-            if (subMap.hasStart) {
-                subMap.setFirstKey();
-                from = subMap.firstKeyNode;
-                fromIndex = subMap.firstKeyIndex;
-            } else {
-                from = minimum(subMap.backingMap.root);
-                fromIndex = from != null ? from.left_idx : 0;
-            }
-            if (!subMap.hasEnd) {
-                return new UnboundedEntryIterator<K, V>(subMap.backingMap, from, from == null ? 0 : from.right_idx - fromIndex);
-            }
-            subMap.setLastKey();
-            Node<K, V> to = subMap.lastKeyNode;
-            int toIndex = subMap.lastKeyIndex;
-            return new BoundedEntryIterator<K, V>(from, from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to, to == null ? 0 : to.right_idx - toIndex);
-        }
-
-        @Override
-        public int size() {
-            return subMap.size();
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public boolean contains(Object object) {
-            if (object instanceof Map.Entry) {
-                Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
-                K key = entry.getKey();
-                if (subMap.isInRange(key)) {
-                    V v1 = subMap.get(key), v2 = entry.getValue();
-                    return v1 == null ? ( v2 == null && subMap.containsKey(key) ) : v1.equals(v2);
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public boolean remove(Object object) {
-            if (contains(object)) {
-                Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
-                K key = entry.getKey();
-                subMap.remove(key);
-                return true;
-            }
-            return false;
-        }
-    }
-
-    static class SubMapKeySet <K,V> extends AbstractSet<K> implements Set<K> {
-        SubMap<K, V> subMap;
-
-        SubMapKeySet(SubMap<K, V> map) {
-            subMap = map;
-        }
-
-        @Override
-        public boolean contains(Object object) {
-            return subMap.containsKey(object);
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return subMap.isEmpty();
-        }
-
-        @Override
-        public int size() {
-            return subMap.size();
-        }
-
-        @Override
-        public boolean remove(Object object) {
-            if (subMap.containsKey(object)) {
-                subMap.remove(object);
-                return true;
-            }
-            return false;
-        }
-
-        public Iterator<K> iterator() {
-            Node<K, V> from;
-            int fromIndex;
-            if (subMap.hasStart) {
-                subMap.setFirstKey();
-                from = subMap.firstKeyNode;
-                fromIndex = subMap.firstKeyIndex;
-            } else {
-                from = minimum(subMap.backingMap.root);
-                fromIndex = from != null ? from.left_idx : 0;
-            }
-            if (!subMap.hasEnd) {
-                return new UnboundedKeyIterator<K, V>(subMap.backingMap, from,
-                                   from == null ? 0 : from.right_idx - fromIndex);
-            }
-            subMap.setLastKey();
-            Node<K, V> to = subMap.lastKeyNode;
-            int toIndex = subMap.lastKeyIndex;
-            return new BoundedKeyIterator<K, V>(from,
-               from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to,
-                 to == null ? 0 : to.right_idx   - toIndex);
-        }
-    }
-
-    static class SubMapValuesCollection <K,V> extends AbstractCollection<V> {
-        SubMap<K, V> subMap;
-
-        public SubMapValuesCollection(SubMap<K, V> subMap) {
-            this.subMap = subMap;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return subMap.isEmpty();
-        }
-
-        @Override
-        public Iterator<V> iterator() {
-            Node<K, V> from;
-            int fromIndex;
-            if (subMap.hasStart) {
-                subMap.setFirstKey();
-                from = subMap.firstKeyNode;
-                fromIndex = subMap.firstKeyIndex;
-            } else {
-                from = minimum(subMap.backingMap.root);
-                fromIndex = from != null ? from.left_idx : 0;
-            }
-            if (!subMap.hasEnd) {
-                return new UnboundedValueIterator<K, V>(subMap.backingMap, from,
-                                   from == null ? 0 : from.right_idx - fromIndex);
-            }
-            subMap.setLastKey();
-            Node<K, V> to = subMap.lastKeyNode;
-            int toIndex = subMap.lastKeyIndex;
-            return new BoundedValueIterator<K, V>(from,
-               from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to,
-                 to == null ? 0 : to.right_idx - toIndex);
-        }
-
-        @Override
-        public int size() {
-            return subMap.size();
-        }
-    }
+    Comparator<? super K> comparator;
+    Node<K, V> root;
+    int size = 0;
+    int modCount = 0;
 
     /**
-     * Constructs a new empty {@code TreeMap} instance.
+     * Create a natural order, empty tree map whose keys must be mutually
+     * comparable and non-null.
      */
+    @SuppressWarnings("unchecked") // unsafe! this assumes K is comparable
     public TreeMap() {
+        this.comparator = (Comparator<? super K>) NATURAL_ORDER;
     }
 
     /**
-     * Constructs a new empty {@code TreeMap} instance with the specified
-     * comparator.
+     * Create a natural order tree map populated with the key/value pairs of
+     * {@code copyFrom}. This map's keys must be mutually comparable and
+     * non-null.
      *
-     * @param comparator
-     *            the comparator to compare keys with.
+     * <p>Even if {@code copyFrom} is a {@code SortedMap}, the constructed map
+     * <strong>will not</strong> use {@code copyFrom}'s ordering. This
+     * constructor always creates a naturally-ordered map. Because the {@code
+     * TreeMap} constructor overloads are ambiguous, prefer to construct a map
+     * and populate it in two steps: <pre>   {@code
+     *   TreeMap<String, Integer> customOrderedMap
+     *       = new TreeMap<String, Integer>(copyFrom.comparator());
+     *   customOrderedMap.putAll(copyFrom);
+     * }</pre>
      */
+    public TreeMap(Map<? extends K, ? extends V> copyFrom) {
+        this();
+        for (Map.Entry<? extends K, ? extends V> entry : copyFrom.entrySet()) {
+            putInternal(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Create a tree map ordered by {@code comparator}. This map's keys may only
+     * be null if {@code comparator} permits.
+     *
+     * @parameter comparator the comparator to order elements with, or {@code
+     *     null} to use the natural ordering.
+     */
+    @SuppressWarnings("unchecked") // unsafe! if comparator is null, this assumes K is comparable
     public TreeMap(Comparator<? super K> comparator) {
-        this.comparator = comparator;
-    }
-
-    /**
-     * Constructs a new {@code TreeMap} instance containing the mappings from
-     * the specified map and using natural ordering.
-     *
-     * @param map
-     *            the mappings to add.
-     * @throws ClassCastException
-     *             if a key in the specified map does not implement the
-     *             Comparable interface, or if the keys in the map cannot be
-     *             compared.
-     */
-    public TreeMap(Map<? extends K, ? extends V> map) {
-        putAll(map);
-    }
-
-    /**
-     * Constructs a new {@code TreeMap} instance containing the mappings from
-     * the specified SortedMap and using the same comparator.
-     *
-     * @param map
-     *            the mappings to add.
-     */
-    public TreeMap(SortedMap<K, ? extends V> map) {
-        this(map.comparator());
-        Node<K, V> lastNode = null;
-        Iterator<? extends Map.Entry<K, ? extends V>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<K, ? extends V> entry = it.next();
-            lastNode = addToLast(lastNode, entry.getKey(), entry.getValue());
-        }
-    }
-
-    Node<K, V> addToLast(Node<K, V> last, K key, V value) {
-        if (last == null) {
-            root = last = createNode(key, value);
-            size = 1;
-        } else if (last.size == Node.NODE_SIZE) {
-            Node<K, V> newNode = createNode(key, value);
-            attachToRight(last, newNode);
-            balance(newNode);
-            size++;
-            last = newNode;
+        if (comparator != null) {
+            this.comparator = comparator;
         } else {
-            appendFromRight(last, key, value);
-            size++;
+            this.comparator = (Comparator<? super K>) NATURAL_ORDER;
         }
-        return last;
     }
 
     /**
-     * Removes all mappings from this TreeMap, leaving it empty.
+     * Create a tree map with the ordering and key/value pairs of {@code
+     * copyFrom}. This map's keys may only be null if the {@code copyFrom}'s
+     * ordering permits.
      *
-     * @see Map#isEmpty()
-     * @see #size()
+     * <p>The constructed map <strong>will always use</strong> {@code
+     * copyFrom}'s ordering. Because the {@code TreeMap} constructor overloads
+     * are ambigous, prefer to construct a map and populate it in two steps:
+     * <pre>   {@code
+     *   TreeMap<String, Integer> customOrderedMap
+     *       = new TreeMap<String, Integer>(copyFrom.comparator());
+     *   customOrderedMap.putAll(copyFrom);
+     * }</pre>
      */
-    @Override
-    public void clear() {
+    @SuppressWarnings("unchecked") // if copyFrom's keys are comparable this map's keys must be also
+    public TreeMap(SortedMap<K, ? extends V> copyFrom) {
+        Comparator<? super K> sourceComparator = copyFrom.comparator();
+        if (sourceComparator != null) {
+            this.comparator = sourceComparator;
+        } else {
+            this.comparator = (Comparator<? super K>) NATURAL_ORDER;
+        }
+        for (Map.Entry<K, ? extends V> entry : copyFrom.entrySet()) {
+            putInternal(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override public Object clone() {
+        try {
+            @SuppressWarnings("unchecked") // super.clone() must return the same type
+            TreeMap<K, V> map = (TreeMap<K, V>) super.clone();
+            map.root = root.copy(null);
+            map.entrySet = null;
+            map.keySet = null;
+            return map;
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError();
+        }
+    }
+
+    @Override public int size() {
+        return size;
+    }
+
+    @Override public boolean isEmpty() {
+        return size == 0;
+    }
+
+    @Override public V get(Object key) {
+        Entry<K, V> entry = findByObject(key);
+        return entry != null ? entry.getValue() : null;
+    }
+
+    @Override public boolean containsKey(Object key) {
+        return findByObject(key) != null;
+    }
+
+    @Override public V put(K key, V value) {
+        return putInternal(key, value);
+    }
+
+    @Override public void clear() {
         root = null;
         size = 0;
         modCount++;
     }
 
-    /**
-     * Returns a new {@code TreeMap} with the same mappings, size and comparator
-     * as this instance.
-     *
-     * @return a shallow copy of this instance.
-     * @see java.lang.Cloneable
+    @Override public V remove(Object key) {
+        Node<K, V> node = removeInternalByKey(key);
+        return node != null ? node.value : null;
+    }
+
+    /*
+     * AVL methods
      */
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object clone() {
-        try {
-            TreeMap<K, V> clone = (TreeMap<K, V>) super.clone();
-            clone.entrySet = null;
-            if (root != null) {
-                clone.root = root.clone(null);
-                // restore prev/next chain
-                Node<K, V> node = minimum(clone.root);
-                while (true) {
-                    Node<K, V> nxt = successor(node);
-                    if (nxt == null) {
-                        break;
-                    }
-                    nxt.prev = node;
-                    node.next = nxt;
-                    node = nxt;
-                }
+
+    enum Relation {
+        LOWER,
+        FLOOR,
+        EQUAL,
+        CREATE,
+        CEILING,
+        HIGHER;
+
+        /**
+         * Returns a possibly-flipped relation for use in descending views.
+         *
+         * @param ascending false to flip; true to return this.
+         */
+        Relation forOrder(boolean ascending) {
+            if (ascending) {
+                return this;
             }
-            return clone;
-        } catch (CloneNotSupportedException e) {
-            throw new AssertionError(e); // android-changed
-        }
-    }
 
-    static private <K, V> Node<K, V> successor(Node<K, V> x) {
-        if (x.right != null) {
-            return minimum(x.right);
-        }
-        Node<K, V> y = x.parent;
-        while (y != null && x == y.right) {
-            x = y;
-            y = y.parent;
-        }
-        return y;
-    }
-
-    /**
-     * Returns the comparator used to compare elements in this map.
-     *
-     * @return the comparator or {@code null} if the natural ordering is used.
-     */
-    public Comparator<? super K> comparator() {
-        return comparator;
-    }
-
-    /**
-     * Returns whether this map contains the specified key.
-     *
-     * @param key
-     *            the key to search for.
-     * @return {@code true} if this map contains the specified key,
-     *         {@code false} otherwise.
-     * @throws ClassCastException
-     *             if the specified key cannot be compared with the keys in this
-     *             map.
-     * @throws NullPointerException
-     *             if the specified key is {@code null} and the comparator
-     *             cannot handle {@code null} keys.
-     */
-    @Override
-    public boolean containsKey(Object key) {
-        Comparable<K> object = comparator == null ? toComparable((K) key) : null;
-        K keyK = (K) key;
-        Node<K, V> node = root;
-        while (node != null) {
-            K[] keys = node.keys;
-            int left_idx = node.left_idx;
-            int result = cmp(object, keyK, keys[left_idx]);
-            if (result < 0) {
-                node = node.left;
-            } else if (result == 0) {
-                return true;
-            } else {
-                int right_idx = node.right_idx;
-                if (left_idx != right_idx) {
-                    result = cmp(object, keyK, keys[right_idx]);
-                }
-                if (result > 0) {
-                    node = node.right;
-                } else if (result == 0) {
-                    return true;
-                } else { /*search in node*/
-                    int low = left_idx + 1, mid = 0, high = right_idx - 1;
-                    while (low <= high) {
-                        mid = (low + high) >>> 1;
-                        result = cmp(object, keyK, keys[mid]);
-                        if (result > 0) {
-                            low = mid + 1;
-                        } else if (result == 0) {
-                            return true;
-                        } else {
-                            high = mid - 1;
-                        }
-                    }
-                    return false;
-                }
+            switch (this) {
+                case LOWER:
+                    return HIGHER;
+                case FLOOR:
+                    return CEILING;
+                case EQUAL:
+                    return EQUAL;
+                case CEILING:
+                    return FLOOR;
+                case HIGHER:
+                    return LOWER;
+                default:
+                    throw new IllegalStateException();
             }
         }
-        return false;
+    }
+
+    V putInternal(K key, V value) {
+        Node<K, V> created = find(key, Relation.CREATE);
+        V result = created.value;
+        created.value = value;
+        return result;
     }
 
     /**
-     * Returns whether this map contains the specified value.
+     * Returns the node at or adjacent to the given key, creating it if requested.
      *
-     * @param value
-     *            the value to search for.
-     * @return {@code true} if this map contains the specified value,
-     *         {@code false} otherwise.
+     * @throws ClassCastException if {@code key} and the tree's keys aren't mutually comparable.
      */
-    @Override
-    public boolean containsValue(Object value) {
+    Node<K, V> find(K key, Relation relation) {
         if (root == null) {
-            return false;
-        }
-        Node<K, V> node = minimum(root);
-        if (value != null) {
-            while (node != null) {
-                int to = node.right_idx;
-                V[] values = node.values;
-                for (int i = node.left_idx; i <= to; i++) {
-                    if (value.equals(values[i])) {
-                        return true;
-                    }
+            if (relation == Relation.CREATE) {
+                if (comparator == NATURAL_ORDER && key == null) {
+                    throw new NullPointerException();
                 }
-                node = node.next;
-            }
-        } else {
-            while (node != null) {
-                int to = node.right_idx;
-                V[] values = node.values;
-                for (int i = node.left_idx; i <= to; i++) {
-                    if (values[i] == null) {
-                        return true;
-                    }
-                }
-                node = node.next;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns a set containing all of the mappings in this map. Each mapping is
-     * an instance of {@link Map.Entry}. As the set is backed by this map,
-     * changes in one will be reflected in the other. It does not support adding
-     * operations.
-     *
-     * @return a set of the mappings.
-     */
-    @Override
-    public Set<Map.Entry<K, V>> entrySet() {
-        if (entrySet == null) {
-            entrySet = new AbstractSet<Map.Entry<K, V>>() {
-                @Override
-                public int size() {
-                    return size;
-                }
-
-                @Override
-                public void clear() {
-                    TreeMap.this.clear();
-                }
-
-                @SuppressWarnings("unchecked")
-                @Override
-                public boolean contains(Object object) {
-                    if (object instanceof Map.Entry) {
-                        Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
-                        K key = entry.getKey();
-                        Object v1 = TreeMap.this.get(key), v2 = entry.getValue();
-                        return v1 == null ? ( v2 == null && TreeMap.this.containsKey(key) ) : v1.equals(v2);
-                    }
-                    return false;
-                }
-
-                @Override
-                public boolean remove(Object object) {
-                    if (contains(object)) {
-                        Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
-                        K key = entry.getKey();
-                        TreeMap.this.remove(key);
-                        return true;
-                    }
-                    return false;
-                }
-
-                @Override
-                public Iterator<Map.Entry<K, V>> iterator() {
-                    return new UnboundedEntryIterator<K, V>(TreeMap.this);
-                }
-            };
-        }
-        return entrySet;
-    }
-
-    /**
-     * Returns the first key in this map.
-     *
-     * @return the first key in this map.
-     * @throws NoSuchElementException
-     *                if this map is empty.
-     */
-    public K firstKey() {
-        if (root != null) {
-            Node<K, V> node = minimum(root);
-            return node.keys[node.left_idx];
-        }
-        throw new NoSuchElementException();
-    }
-
-
-    /**
-     * Returns the value of the mapping with the specified key.
-     *
-     * @param key
-     *            the key.
-     * @return the value of the mapping with the specified key.
-     * @throws ClassCastException
-     *             if the key cannot be compared with the keys in this map.
-     * @throws NullPointerException
-     *             if the key is {@code null} and the comparator cannot handle
-     *             {@code null}.
-     */
-    @Override
-    public V get(Object key) {
-        Comparable<K> object = comparator == null ? toComparable((K) key) : null;
-        K keyK = (K) key;
-        Node<K, V> node = root;
-        while (node != null) {
-            K[] keys = node.keys;
-            int left_idx = node.left_idx;
-            int result = cmp(object, keyK, keys[left_idx]);
-            if (result < 0) {
-                node = node.left;
-            } else if (result == 0) {
-                return node.values[left_idx];
+                root = new Node<K, V>(null, key);
+                size = 1;
+                modCount++;
+                return root;
             } else {
-                int right_idx = node.right_idx;
-                if (left_idx != right_idx) {
-                    result = cmp(object, keyK, keys[right_idx]);
+                return null;
+            }
+        }
+
+        /*
+         * Micro-optimization: avoid polymorphic calls to Comparator.compare().
+         * This is 10% faster for naturally ordered trees.
+         */
+        @SuppressWarnings("unchecked") // will throw a ClassCastException below if there's trouble
+        Comparable<Object> comparableKey = (comparator == NATURAL_ORDER)
+                ? (Comparable<Object>) key
+                : null;
+
+        Node<K, V> nearest = root;
+        while (true) {
+            int comparison = (comparableKey != null)
+                    ? comparableKey.compareTo(nearest.key)
+                    : comparator.compare(key, nearest.key);
+
+            /*
+             * We found the requested key.
+             */
+            if (comparison == 0) {
+                switch (relation) {
+                    case LOWER:
+                        return nearest.prev();
+                    case FLOOR:
+                    case EQUAL:
+                    case CREATE:
+                    case CEILING:
+                        return nearest;
+                    case HIGHER:
+                        return nearest.next();
                 }
-                if (result > 0) {
-                    node = node.right;
-                } else if (result == 0) {
-                    return node.values[right_idx];
-                } else { /*search in node*/
-                    int low = left_idx + 1, mid = 0, high = right_idx - 1;
-                    while (low <= high) {
-                        mid = (low + high) >>> 1;
-                        result = cmp(object, keyK, keys[mid]);
-                        if (result > 0) {
-                            low = mid + 1;
-                        } else if (result == 0) {
-                            return node.values[mid];
-                        } else {
-                            high = mid - 1;
-                        }
-                    }
-                    return null;
+            }
+
+            Node<K, V> child = (comparison < 0) ? nearest.left : nearest.right;
+            if (child != null) {
+                nearest = child;
+                continue;
+            }
+
+            /*
+             * We found a nearest node. Every key not in the tree has up to two
+             * nearest nodes, one lower and one higher.
+             */
+
+            if (comparison < 0) { // nearest.key is higher
+                switch (relation) {
+                    case LOWER:
+                    case FLOOR:
+                        return nearest.prev();
+                    case CEILING:
+                    case HIGHER:
+                        return nearest;
+                    case EQUAL:
+                        return null;
+                    case CREATE:
+                        Node<K, V> created = new Node<K, V>(nearest, key);
+                        nearest.left = created;
+                        size++;
+                        modCount++;
+                        rebalance(nearest, true);
+                        return created;
+                }
+            } else { // comparison > 0, nearest.key is lower
+                switch (relation) {
+                    case LOWER:
+                    case FLOOR:
+                        return nearest;
+                    case CEILING:
+                    case HIGHER:
+                        return nearest.next();
+                    case EQUAL:
+                        return null;
+                    case CREATE:
+                        Node<K, V> created = new Node<K, V>(nearest, key);
+                        nearest.right = created;
+                        size++;
+                        modCount++;
+                        rebalance(nearest, true);
+                        return created;
                 }
             }
         }
-        return null;
     }
 
-    private int cmp(Comparable<K> object, K key1, K key2) {
-        return object != null ?
-               object.compareTo(key2) : comparator.compare(key1, key2);
+    @SuppressWarnings("unchecked") // this method throws ClassCastExceptions!
+    Node<K, V> findByObject(Object key) {
+        return find((K) key, EQUAL);
     }
 
     /**
-     * Returns a sorted map over a range of this sorted map with all keys that
-     * are less than the specified {@code endKey}. Changes to the returned
-     * sorted map are reflected in this sorted map and vice versa.
-     * <p>
-     * Note: The returned map will not allow an insertion of a key outside the
-     * specified range.
+     * Returns this map's entry that has the same key and value as {@code
+     * entry}, or null if this map has no such entry.
      *
-     * @param endKey
-     *            the high boundary of the range specified.
-     * @return a sorted map where the keys are less than {@code endKey}.
-     * @throws ClassCastException
-     *             if the specified key cannot be compared with the keys in this
-     *             map.
-     * @throws NullPointerException
-     *             if the specified key is {@code null} and the comparator
-     *             cannot handle {@code null} keys.
-     * @throws IllegalArgumentException
-     *             if this map is itself a sorted map over a range of another
-     *             map and the specified key is outside of its range.
+     * <p>This method uses the comparator for key equality rather than {@code
+     * equals}. If this map's comparator isn't consistent with equals (such as
+     * {@code String.CASE_INSENSITIVE_ORDER}), then {@code remove()} and {@code
+     * contains()} will violate the collections API.
      */
-    public SortedMap<K, V> headMap(K endKey) {
-        // Check for errors
-        if (comparator == null) {
-            toComparable(endKey).compareTo(endKey);
+    Node<K, V> findByEntry(Entry<?, ?> entry) {
+        Node<K, V> mine = findByObject(entry.getKey());
+        boolean valuesEqual = mine != null && (mine.value != null
+                ? mine.value.equals(entry.getValue())
+                : entry.getValue() == null);
+        return valuesEqual ? mine : null;
+    }
+
+    /**
+     * Removes {@code node} from this tree, rearranging the tree's structure as
+     * necessary.
+     */
+    void removeInternal(Node<K, V> node) {
+        Node<K, V> left = node.left;
+        Node<K, V> right = node.right;
+        Node<K, V> originalParent = node.parent;
+        if (left != null && right != null) {
+
+            /*
+             * To remove a node with both left and right subtrees, move an
+             * adjacent node from one of those subtrees into this node's place.
+             *
+             * Removing the adjacent node may change this node's subtrees. This
+             * node may no longer have two subtrees once the adjacent node is
+             * gone!
+             */
+
+            Node<K, V> adjacent = (left.height > right.height) ? left.last() : right.first();
+            removeInternal(adjacent); // takes care of rebalance and size--
+
+            int leftHeight = 0;
+            left = node.left;
+            if (left != null) {
+                leftHeight = left.height;
+                adjacent.left = left;
+                left.parent = adjacent;
+                node.left = null;
+            }
+            int rightHeight = 0;
+            right = node.right;
+            if (right != null) {
+                rightHeight = right.height;
+                adjacent.right = right;
+                right.parent = adjacent;
+                node.right = null;
+            }
+            adjacent.height = Math.max(leftHeight, rightHeight) + 1;
+            replaceInParent(node, adjacent);
+            return;
+        } else if (left != null) {
+            replaceInParent(node, left);
+            node.left = null;
+        } else if (right != null) {
+            replaceInParent(node, right);
+            node.right = null;
         } else {
-            comparator.compare(endKey, endKey);
+            replaceInParent(node, null);
         }
-        return new SubMap<K, V>(this, endKey);
-    }
 
-    /**
-     * Returns a set of the keys contained in this map. The set is backed by
-     * this map so changes to one are reflected by the other. The set does not
-     * support adding.
-     *
-     * @return a set of the keys.
-     */
-    @Override
-    public Set<K> keySet() {
-        if (keySet == null) {
-            keySet = new AbstractSet<K>() {
-                @Override
-                public boolean contains(Object object) {
-                    return TreeMap.this.containsKey(object);
-                }
-
-                @Override
-                public int size() {
-                    return TreeMap.this.size;
-                }
-
-                @Override
-                public void clear() {
-                    TreeMap.this.clear();
-                }
-
-                @Override
-                public boolean remove(Object object) {
-                    if (contains(object)) {
-                        TreeMap.this.remove(object);
-                        return true;
-                    }
-                    return false;
-                }
-
-                @Override
-                public Iterator<K> iterator() {
-                    return new UnboundedKeyIterator<K, V>(TreeMap.this);
-                }
-            };
-        }
-        return keySet;
-    }
-
-    /**
-     * Returns the last key in this map.
-     *
-     * @return the last key in this map.
-     * @throws NoSuchElementException
-     *             if this map is empty.
-     */
-    public K lastKey() {
-        if (root != null) {
-            Node<K, V> node = maximum(root);
-            return node.keys[node.right_idx];
-        }
-        throw new NoSuchElementException();
-    }
-
-    static <K,V> Node<K, V> minimum(Node<K, V> x) {
-        if (x == null) {
-            return null;
-        }
-        while (x.left != null) {
-            x = x.left;
-        }
-        return x;
-    }
-
-    static <K,V> Node<K, V> maximum(Node<K, V> x) {
-        if (x == null) {
-            return null;
-        }
-        while (x.right != null) {
-            x = x.right;
-        }
-        return x;
-    }
-
-    /**
-     * Maps the specified key to the specified value.
-     *
-     * @param key
-     *            the key.
-     * @param value
-     *            the value.
-     * @return the value of any previous mapping with the specified key or
-     *         {@code null} if there was no mapping.
-     * @throws ClassCastException
-     *             if the specified key cannot be compared with the keys in this
-     *             map.
-     * @throws NullPointerException
-     *             if the specified key is {@code null} and the comparator
-     *             cannot handle {@code null} keys.
-     */
-    @Override
-    public V put(K key, V value) {
-        if (root == null) {
-            root = createNode(key, value);
-            size = 1;
-            modCount++;
-            return null;
-        }
-        Comparable<K> object = comparator == null ? toComparable((K) key) : null;
-        K keyK = (K) key;
-        Node<K, V> node = root;
-        Node<K, V> prevNode = null;
-        int result = 0;
-        while (node != null) {
-            prevNode = node;
-            K[] keys = node.keys;
-            int left_idx = node.left_idx;
-            result = cmp(object, keyK, keys[left_idx]);
-            if (result < 0) {
-                node = node.left;
-            } else if (result == 0) {
-                V res = node.values[left_idx];
-                node.values[left_idx] = value;
-                return res;
-            } else {
-                int right_idx = node.right_idx;
-                if (left_idx != right_idx) {
-                    result = cmp(object, keyK, keys[right_idx]);
-                }
-                if (result > 0) {
-                    node = node.right;
-                } else if (result == 0) {
-                    V res = node.values[right_idx];
-                    node.values[right_idx] = value;
-                    return res;
-                } else { /*search in node*/
-                    int low = left_idx + 1, mid = 0, high = right_idx - 1;
-                    while (low <= high) {
-                        mid = (low + high) >>> 1;
-                        result = cmp(object, keyK, keys[mid]);
-                        if (result > 0) {
-                            low = mid + 1;
-                        } else if (result == 0) {
-                            V res = node.values[mid];
-                            node.values[mid] = value;
-                            return res;
-                        } else {
-                            high = mid - 1;
-                        }
-                    }
-                    result = low;
-                    break;
-                }
-            }
-        } /* while */
-/*
-          if(node == null) {
-             if(prevNode==null) {
-                - case of empty Tree
-             } else {
-                result < 0 - prevNode.left==null - attach here
-                result > 0 - prevNode.right==null - attach here
-             }
-          } else {
-             insert into node.
-             result - index where it should be inserted.
-          }
-        */
-        size++;
+        rebalance(originalParent, false);
+        size--;
         modCount++;
-        if (node == null) {
-            if (prevNode == null) {
-                // case of empty Tree
-                root = createNode(key, value);
-            } else if (prevNode.size < Node.NODE_SIZE) {
-                // there is a place for insert
-                if (result < 0) {
-                    appendFromLeft(prevNode, key, value);
-                } else {
-                    appendFromRight(prevNode, key, value);
-                }
-            } else {
-                // create and link
-                Node<K, V> newNode = createNode(key, value);
-                if (result < 0) {
-                    attachToLeft(prevNode, newNode);
-                } else {
-                    attachToRight(prevNode, newNode);
-                }
-                balance(newNode);
-            }
-        } else {
-            // insert into node.
-            // result - index where it should be inserted.
-            if (node.size < Node.NODE_SIZE) { // insert and ok
-                int left_idx = node.left_idx;
-                int right_idx = node.right_idx;
-                if (left_idx == 0 || ((right_idx != Node.NODE_SIZE - 1) && (right_idx - result <= result - left_idx))) {
-                    int right_idxPlus1 = right_idx + 1;
-                    System.arraycopy(node.keys,   result, node.keys,   result + 1, right_idxPlus1 - result);
-                    System.arraycopy(node.values, result, node.values, result + 1, right_idxPlus1 - result);
-                    node.right_idx = right_idxPlus1;
-                    node.keys[result] = key;
-                    node.values[result] = value;
-                } else {
-                    int left_idxMinus1 = left_idx - 1;
-                    System.arraycopy(node.keys,   left_idx, node.keys,   left_idxMinus1, result - left_idx);
-                    System.arraycopy(node.values, left_idx, node.values, left_idxMinus1, result - left_idx);
-                    node.left_idx = left_idxMinus1;
-                    node.keys[result - 1] = key;
-                    node.values[result - 1] = value;
-                }
-                node.size++;
-            } else {
-                // there are no place here
-                // insert and push old pair
-                Node<K, V> previous = node.prev;
-                Node<K, V> nextNode = node.next;
-                boolean removeFromStart;
-                boolean attachFromLeft = false;
-                Node<K, V> attachHere = null;
-                if (previous == null) {
-                    if (nextNode != null && nextNode.size < Node.NODE_SIZE) {
-                        // move last pair to next
-                        removeFromStart = false;
-                    } else {
-                        // next node doesn't exist or full
-                        // left==null
-                        // drop first pair to new node from left
-                        removeFromStart = true;
-                        attachFromLeft = true;
-                        attachHere = node;
-                    }
-                } else if (nextNode == null) {
-                    if (previous.size < Node.NODE_SIZE) {
-                        // move first pair to prev
-                        removeFromStart = true;
-                    } else {
-                        // right == null;
-                        // drop last pair to new node from right
-                        removeFromStart = false;
-                        attachFromLeft = false;
-                        attachHere = node;
-                    }
-                } else {
-                    if (previous.size < Node.NODE_SIZE) {
-                        if (nextNode.size < Node.NODE_SIZE) {
-                            // choose prev or next for moving
-                            removeFromStart = previous.size < nextNode.size;
-                        } else {
-                            // move first pair to prev
-                            removeFromStart = true;
-                        }
-                    } else {
-                        if (nextNode.size < Node.NODE_SIZE) {
-                            // move last pair to next
-                            removeFromStart = false;
-                        } else {
-                            // prev & next are full
-                            // if node.right!=null then node.next.left==null
-                            // if node.left!=null then node.prev.right==null
-                            if (node.right == null) {
-                                attachHere = node;
-                                attachFromLeft = false;
-                                removeFromStart = false;
-                            } else {
-                                attachHere = nextNode;
-                                attachFromLeft = true;
-                                removeFromStart = false;
-                            }
-                        }
-                    }
-                }
-                K movedKey;
-                V movedValue;
-                if (removeFromStart) {
-                    // node.left_idx == 0
-                    movedKey = node.keys[0];
-                    movedValue = node.values[0];
-                    int resMunus1 = result - 1;
-                    System.arraycopy(node.keys,   1, node.keys,   0, resMunus1);
-                    System.arraycopy(node.values, 1, node.values, 0, resMunus1);
-                    node.keys  [resMunus1] = key;
-                    node.values[resMunus1] = value;
-                } else {
-                    // node.right_idx == Node.NODE_SIZE - 1
-                    movedKey   = node.keys[Node.NODE_SIZE - 1];
-                    movedValue = node.values[Node.NODE_SIZE - 1];
-                    System.arraycopy(node.keys,   result, node.keys,   result + 1, Node.NODE_SIZE - 1 - result);
-                    System.arraycopy(node.values, result, node.values, result + 1, Node.NODE_SIZE - 1 - result);
-                    node.keys[result] = key;
-                    node.values[result] = value;
-                }
-                if (attachHere == null) {
-                    if (removeFromStart) {
-                        appendFromRight(previous, movedKey, movedValue);
-                    } else {
-                        appendFromLeft(nextNode, movedKey, movedValue);
-                    }
-                } else {
-                    Node<K, V> newNode = createNode(movedKey, movedValue);
-                    if (attachFromLeft) {
-                        attachToLeft(attachHere, newNode);
-                    } else {
-                        attachToRight(attachHere, newNode);
-                    }
-                    balance(newNode);
-                }
-            }
-        }
-        return null;
     }
 
-    private void appendFromLeft(Node<K, V> node, K keyObj, V value) {
-        if (node.left_idx == 0) {
-            int new_right = node.right_idx + 1;
-            System.arraycopy(node.keys,   0, node.keys,   1, new_right);
-            System.arraycopy(node.values, 0, node.values, 1, new_right);
-            node.right_idx = new_right;
-        } else {
-            node.left_idx--;
+    Node<K, V> removeInternalByKey(Object key) {
+        Node<K, V> node = findByObject(key);
+        if (node != null) {
+            removeInternal(node);
         }
-        node.size++;
-        node.keys[node.left_idx] = keyObj;
-        node.values[node.left_idx] = value;
-    }
-
-    private void attachToLeft(Node<K, V> node, Node<K, V> newNode) {
-        newNode.parent = node;
-        // node.left==null - attach here
-        node.left = newNode;
-        Node<K, V> predecessor = node.prev;
-        newNode.prev = predecessor;
-        newNode.next = node;
-        if (predecessor != null) {
-            predecessor.next = newNode;
-        }
-        node.prev = newNode;
-    }
-
-    /* add pair into node; existence free room in the node should be checked
-     * before call
-     */
-    private void appendFromRight(Node<K, V> node, K keyObj, V value) {
-        if (node.right_idx == Node.NODE_SIZE - 1) {
-            int left_idx = node.left_idx;
-            int left_idxMinus1 = left_idx - 1;
-            System.arraycopy(node.keys,   left_idx, node.keys,   left_idxMinus1, Node.NODE_SIZE - left_idx);
-            System.arraycopy(node.values, left_idx, node.values, left_idxMinus1, Node.NODE_SIZE - left_idx);
-            node.left_idx = left_idxMinus1;
-        } else {
-            node.right_idx++;
-        }
-        node.size++;
-        node.keys[node.right_idx] = keyObj;
-        node.values[node.right_idx] = value;
-    }
-
-    private void attachToRight(Node<K, V> node, Node<K, V> newNode) {
-        newNode.parent = node;
-        // - node.right==null - attach here
-        node.right = newNode;
-        newNode.prev = node;
-        Node<K, V> successor = node.next;
-        newNode.next = successor;
-        if (successor != null) {
-            successor.prev = newNode;
-        }
-        node.next = newNode;
-    }
-
-    private Node<K, V> createNode(K keyObj, V value) {
-        Node<K, V> node = new Node<K, V>();
-        node.keys[0] = keyObj;
-        node.values[0] = value;
-        node.left_idx = 0;
-        node.right_idx = 0;
-        node.size = 1;
         return node;
     }
 
-    void balance(Node<K, V> x) {
-        Node<K, V> y;
-        x.color = true;
-        while (x != root && x.parent.color) {
-            if (x.parent == x.parent.parent.left) {
-                y = x.parent.parent.right;
-                if (y != null && y.color) {
-                    x.parent.color = false;
-                    y.color = false;
-                    x.parent.parent.color = true;
-                    x = x.parent.parent;
-                } else {
-                    if (x == x.parent.right) {
-                        x = x.parent;
-                        leftRotate(x);
-                    }
-                    x.parent.color = false;
-                    x.parent.parent.color = true;
-                    rightRotate(x.parent.parent);
-                }
-            } else {
-                y = x.parent.parent.left;
-                if (y != null && y.color) {
-                    x.parent.color = false;
-                    y.color = false;
-                    x.parent.parent.color = true;
-                    x = x.parent.parent;
-                } else {
-                    if (x == x.parent.left) {
-                        x = x.parent;
-                        rightRotate(x);
-                    }
-                    x.parent.color = false;
-                    x.parent.parent.color = true;
-                    leftRotate(x.parent.parent);
-                }
-            }
+    private void replaceInParent(Node<K, V> node, Node<K, V> replacement) {
+        Node<K, V> parent = node.parent;
+        node.parent = null;
+        if (replacement != null) {
+            replacement.parent = parent;
         }
-        root.color = false;
-    }
 
-    private void rightRotate(Node<K, V> x) {
-        Node<K, V> y = x.left;
-        x.left = y.right;
-        if (y.right != null) {
-            y.right.parent = x;
-        }
-        y.parent = x.parent;
-        if (x.parent == null) {
-            root = y;
+        if (parent != null) {
+            if (parent.left == node) {
+                parent.left = replacement;
+            } else {
+                assert (parent.right == node);
+                parent.right = replacement;
+            }
         } else {
-            if (x == x.parent.right) {
-                x.parent.right = y;
-            } else {
-                x.parent.left = y;
-            }
+            root = replacement;
         }
-        y.right = x;
-        x.parent = y;
-    }
-
-
-    private void leftRotate(Node<K, V> x) {
-        Node<K, V> y = x.right;
-        x.right = y.left;
-        if (y.left != null) {
-            y.left.parent = x;
-        }
-        y.parent = x.parent;
-        if (x.parent == null) {
-            root = y;
-        } else {
-            if (x == x.parent.left) {
-                x.parent.left = y;
-            } else {
-                x.parent.right = y;
-            }
-        }
-        y.left = x;
-        x.parent = y;
-    }
-
-
-    /**
-     * Copies all the mappings in the given map to this map. These mappings will
-     * replace all mappings that this map had for any of the keys currently in
-     * the given map.
-     *
-     * @param map
-     *            the map to copy mappings from.
-     * @throws ClassCastException
-     *             if a key in the specified map cannot be compared with the
-     *             keys in this map.
-     * @throws NullPointerException
-     *             if a key in the specified map is {@code null} and the
-     *             comparator cannot handle {@code null} keys.
-     */
-    @Override
-    public void putAll(Map<? extends K, ? extends V> map) {
-        super.putAll(map);
     }
 
     /**
-     * Removes the mapping with the specified key from this map.
+     * Rebalances the tree by making any AVL rotations necessary between the
+     * newly-unbalanced node and the tree's root.
      *
-     * @param key
-     *            the key of the mapping to remove.
-     * @return the value of the removed mapping or {@code null} if no mapping
-     *         for the specified key was found.
-     * @throws ClassCastException
-     *             if the specified key cannot be compared with the keys in this
-     *             map.
-     * @throws NullPointerException
-     *             if the specified key is {@code null} and the comparator
-     *             cannot handle {@code null} keys.
+     * @param insert true if the node was unbalanced by an insert; false if it
+     *     was by a removal.
      */
-    @Override
-    public V remove(Object key) {
-        if (size == 0) {
+    private void rebalance(Node<K, V> unbalanced, boolean insert) {
+        for (Node<K, V> node = unbalanced; node != null; node = node.parent) {
+            Node<K, V> left = node.left;
+            Node<K, V> right = node.right;
+            int leftHeight = left != null ? left.height : 0;
+            int rightHeight = right != null ? right.height : 0;
+
+            int delta = leftHeight - rightHeight;
+            if (delta == -2) {
+                Node<K, V> rightLeft = right.left;
+                Node<K, V> rightRight = right.right;
+                int rightRightHeight = rightRight != null ? rightRight.height : 0;
+                int rightLeftHeight = rightLeft != null ? rightLeft.height : 0;
+
+                int rightDelta = rightLeftHeight - rightRightHeight;
+                if (rightDelta == -1 || (rightDelta == 0 && !insert)) {
+                    rotateLeft(node); // AVL right right
+                } else {
+                    assert (rightDelta == 1);
+                    rotateRight(right); // AVL right left
+                    rotateLeft(node);
+                }
+                if (insert) {
+                    break; // no further rotations will be necessary
+                }
+
+            } else if (delta == 2) {
+                Node<K, V> leftLeft = left.left;
+                Node<K, V> leftRight = left.right;
+                int leftRightHeight = leftRight != null ? leftRight.height : 0;
+                int leftLeftHeight = leftLeft != null ? leftLeft.height : 0;
+
+                int leftDelta = leftLeftHeight - leftRightHeight;
+                if (leftDelta == 1 || (leftDelta == 0 && !insert)) {
+                    rotateRight(node); // AVL left left
+                } else {
+                    assert (leftDelta == -1);
+                    rotateLeft(left); // AVL left right
+                    rotateRight(node);
+                }
+                if (insert) {
+                    break; // no further rotations will be necessary
+                }
+
+            } else if (delta == 0) {
+                node.height = leftHeight + 1; // leftHeight == rightHeight
+                if (insert) {
+                    break; // the insert caused balance, so rebalancing is done!
+                }
+
+            } else {
+                assert (delta == -1 || delta == 1);
+                node.height = Math.max(leftHeight, rightHeight) + 1;
+                if (!insert) {
+                    break; // the height hasn't changed, so rebalancing is done!
+                }
+            }
+        }
+    }
+
+    /**
+     * Rotates the subtree so that its root's right child is the new root.
+     */
+    private void rotateLeft(Node<K, V> root) {
+        Node<K, V> left = root.left;
+        Node<K, V> pivot = root.right;
+        Node<K, V> pivotLeft = pivot.left;
+        Node<K, V> pivotRight = pivot.right;
+
+        // move the pivot's left child to the root's right
+        root.right = pivotLeft;
+        if (pivotLeft != null) {
+            pivotLeft.parent = root;
+        }
+
+        replaceInParent(root, pivot);
+
+        // move the root to the pivot's left
+        pivot.left = root;
+        root.parent = pivot;
+
+        // fix heights
+        root.height = Math.max(left != null ? left.height : 0,
+                pivotLeft != null ? pivotLeft.height : 0) + 1;
+        pivot.height = Math.max(root.height,
+                pivotRight != null ? pivotRight.height : 0) + 1;
+    }
+
+    /**
+     * Rotates the subtree so that its root's left child is the new root.
+     */
+    private void rotateRight(Node<K, V> root) {
+        Node<K, V> pivot = root.left;
+        Node<K, V> right = root.right;
+        Node<K, V> pivotLeft = pivot.left;
+        Node<K, V> pivotRight = pivot.right;
+
+        // move the pivot's right child to the root's left
+        root.left = pivotRight;
+        if (pivotRight != null) {
+            pivotRight.parent = root;
+        }
+
+        replaceInParent(root, pivot);
+
+        // move the root to the pivot's right
+        pivot.right = root;
+        root.parent = pivot;
+
+        // fixup heights
+        root.height = Math.max(right != null ? right.height : 0,
+                pivotRight != null ? pivotRight.height : 0) + 1;
+        pivot.height = Math.max(root.height,
+                pivotLeft != null ? pivotLeft.height : 0) + 1;
+    }
+
+    /*
+     * Navigable methods.
+     */
+
+    public Entry<K, V> firstEntry() {
+        return root == null ? null : root.first();
+    }
+
+    public Entry<K, V> pollFirstEntry() {
+        if (root == null) {
             return null;
         }
-        Comparable<K> object = comparator == null ? toComparable((K) key) : null;
-        K keyK = (K) key;
-        Node<K, V> node = root;
-        while (node != null) {
-            K[] keys = node.keys;
-            int left_idx = node.left_idx;
-            int result = cmp(object, keyK, keys[left_idx]);
-            if (result < 0) {
-                node = node.left;
-            } else if (result == 0) {
-                V value = node.values[left_idx];
-                removeLeftmost(node);
-                return value;
-            } else {
-                int right_idx = node.right_idx;
-                if (left_idx != right_idx) {
-                    result = cmp(object, keyK, keys[right_idx]);
-                }
-                if (result > 0) {
-                    node = node.right;
-                } else if (result == 0) {
-                    V value = node.values[right_idx];
-                    removeRightmost(node);
-                    return value;
-                } else { /*search in node*/
-                    int low = left_idx + 1, mid = 0, high = right_idx - 1;
-                    while (low <= high) {
-                        mid = (low + high) >>> 1;
-                        result = cmp(object, keyK, keys[mid]);
-                        if (result > 0) {
-                            low = mid + 1;
-                        } else if (result == 0) {
-                            V value = node.values[mid];
-                            removeMiddleElement(node, mid);
-                            return value;
-                        } else {
-                            high = mid - 1;
-                        }
-                    }
-                    return null;
-                }
-            }
-        }
-        return null;
+        Node<K, V> result = root.first();
+        removeInternal(result);
+        return result;
     }
 
-    void removeLeftmost(Node<K, V> node) {
-        int index = node.left_idx;
-        if (node.size == 1) {
-            deleteNode(node);
-        } else if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) {
-            // move all to prev node and kill it
-            Node<K, V> prev = node.prev;
-            int size = node.right_idx - index;
-            System.arraycopy(node.keys,   index + 1, prev.keys,   prev.right_idx + 1, size);
-            System.arraycopy(node.values, index + 1, prev.values, prev.right_idx + 1, size);
-            prev.right_idx += size;
-            prev.size += size;
-            deleteNode(node);
-        } else if (node.next != null && (node.next.left_idx) > node.size) {
-            // move all to next node and kill it
-            Node<K, V> next = node.next;
-            int size = node.right_idx - index;
-            int next_new_left = next.left_idx - size;
-            next.left_idx = next_new_left;
-            System.arraycopy(node.keys,   index + 1, next.keys,   next_new_left, size);
-            System.arraycopy(node.values, index + 1, next.values, next_new_left, size);
-            next.size += size;
-            deleteNode(node);
-        } else {
-            node.keys[index] = null;
-            node.values[index] = null;
-            node.left_idx++;
-            node.size--;
-            Node<K, V> prev = node.prev;
-            if (prev != null && prev.size == 1) {
-                node.size++;
-                node.left_idx--;
-                node.keys  [node.left_idx] = prev.keys  [prev.left_idx];
-                node.values[node.left_idx] = prev.values[prev.left_idx];
-                deleteNode(prev);
-            }
+    public K firstKey() {
+        if (root == null) {
+            throw new NoSuchElementException();
         }
-        modCount++;
-        size--;
+        return root.first().getKey();
     }
 
-    void removeRightmost(Node<K, V> node) {
-        int index = node.right_idx;
-        if (node.size == 1) {
-            deleteNode(node);
-        } else if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) {
-            // move all to prev node and kill it
-            Node<K, V> prev = node.prev;
-            int left_idx = node.left_idx;
-            int size = index - left_idx;
-            System.arraycopy(node.keys,   left_idx, prev.keys,   prev.right_idx + 1, size);
-            System.arraycopy(node.values, left_idx, prev.values, prev.right_idx + 1, size);
-            prev.right_idx += size;
-            prev.size += size;
-            deleteNode(node);
-        } else if (node.next != null && (node.next.left_idx) > node.size) {
-            // move all to next node and kill it
-            Node<K, V> next = node.next;
-            int left_idx = node.left_idx;
-            int size = index - left_idx;
-            int next_new_left = next.left_idx - size;
-            next.left_idx = next_new_left;
-            System.arraycopy(node.keys,   left_idx, next.keys,   next_new_left, size);
-            System.arraycopy(node.values, left_idx, next.values, next_new_left, size);
-            next.size += size;
-            deleteNode(node);
-        } else {
-            node.keys[index] = null;
-            node.values[index] = null;
-            node.right_idx--;
-            node.size--;
-            Node<K, V> next = node.next;
-            if (next != null && next.size == 1) {
-                node.size++;
-                node.right_idx++;
-                node.keys[node.right_idx]   = next.keys[next.left_idx];
-                node.values[node.right_idx] = next.values[next.left_idx];
-                deleteNode(next);
-            }
-        }
-        modCount++;
-        size--;
+    public Entry<K, V> lastEntry() {
+        return root == null ? null : root.last();
     }
 
-    void removeMiddleElement(Node<K, V> node, int index) {
-        // this function is called iff index if some middle element;
-        // so node.left_idx < index < node.right_idx
-        // condition above assume that node.size > 1
-        if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) {
-            // move all to prev node and kill it
-            Node<K, V> prev = node.prev;
-            int left_idx = node.left_idx;
-            int size = index - left_idx;
-            System.arraycopy(node.keys,   left_idx, prev.keys,   prev.right_idx + 1, size);
-            System.arraycopy(node.values, left_idx, prev.values, prev.right_idx + 1, size);
-            prev.right_idx += size;
-            size = node.right_idx - index;
-            System.arraycopy(node.keys,   index + 1, prev.keys,   prev.right_idx + 1, size);
-            System.arraycopy(node.values, index + 1, prev.values, prev.right_idx + 1, size);
-            prev.right_idx += size;
-            prev.size += (node.size - 1);
-            deleteNode(node);
-        } else if (node.next != null && (node.next.left_idx) > node.size) {
-            // move all to next node and kill it
-            Node<K, V> next = node.next;
-            int left_idx = node.left_idx;
-            int next_new_left = next.left_idx - node.size + 1;
-            next.left_idx = next_new_left;
-            int size = index - left_idx;
-            System.arraycopy(node.keys,   left_idx, next.keys,   next_new_left, size);
-            System.arraycopy(node.values, left_idx, next.values, next_new_left, size);
-            next_new_left += size;
-            size = node.right_idx - index;
-            System.arraycopy(node.keys,   index + 1, next.keys,   next_new_left, size);
-            System.arraycopy(node.values, index + 1, next.values, next_new_left, size);
-            next.size += (node.size - 1);
-            deleteNode(node);
-        } else {
-            int moveFromRight = node.right_idx - index;
-            int left_idx = node.left_idx;
-            int moveFromLeft = index - left_idx ;
-            if (moveFromRight <= moveFromLeft) {
-                System.arraycopy(node.keys,   index + 1, node.keys,   index, moveFromRight);
-                System.arraycopy(node.values, index + 1, node.values, index, moveFromRight);
-                Node<K, V> next = node.next;
-                if (next != null && next.size == 1) {
-                    node.keys  [node.right_idx] = next.keys  [next.left_idx];
-                    node.values[node.right_idx] = next.values[next.left_idx];
-                    deleteNode(next);
-                } else {
-                    node.keys  [node.right_idx] = null;
-                    node.values[node.right_idx] = null;
-                    node.right_idx--;
-                    node.size--;
-                }
-            } else {
-                System.arraycopy(node.keys,   left_idx , node.keys,   left_idx  + 1, moveFromLeft);
-                System.arraycopy(node.values, left_idx , node.values, left_idx + 1, moveFromLeft);
-                Node<K, V> prev = node.prev;
-                if (prev != null && prev.size == 1) {
-                    node.keys  [left_idx ] = prev.keys  [prev.left_idx];
-                    node.values[left_idx ] = prev.values[prev.left_idx];
-                    deleteNode(prev);
-                } else {
-                    node.keys  [left_idx ] = null;
-                    node.values[left_idx ] = null;
-                    node.left_idx++;
-                    node.size--;
-                }
-            }
+    public Entry<K, V> pollLastEntry() {
+        if (root == null) {
+            return null;
         }
-        modCount++;
-        size--;
+        Node<K, V> result = root.last();
+        removeInternal(result);
+        return result;
     }
 
-    void removeFromIterator(Node<K, V> node, int index) {
-        if (node.size == 1) {
-            // it is safe to delete the whole node here.
-            // iterator already moved to the next node;
-            deleteNode(node);
-        } else {
-            int left_idx = node.left_idx;
-            if (index == left_idx) {
-                Node<K, V> prev = node.prev;
-                if (prev != null && prev.size == 1) {
-                    node.keys  [left_idx] = prev.keys  [prev.left_idx];
-                    node.values[left_idx] = prev.values[prev.left_idx];
-                    deleteNode(prev);
-                } else {
-                    node.keys  [left_idx] = null;
-                    node.values[left_idx] = null;
-                    node.left_idx++;
-                    node.size--;
-                }
-            } else if (index == node.right_idx) {
-                node.keys  [index] = null;
-                node.values[index] = null;
-                node.right_idx--;
-                node.size--;
-            } else {
-                int moveFromRight = node.right_idx - index;
-                int moveFromLeft = index - left_idx;
-                if (moveFromRight <= moveFromLeft) {
-                    System.arraycopy(node.keys,   index + 1, node.keys,   index, moveFromRight );
-                    System.arraycopy(node.values, index + 1, node.values, index, moveFromRight );
-                    node.keys  [node.right_idx] = null;
-                    node.values[node.right_idx] = null;
-                    node.right_idx--;
-                    node.size--;
-                } else {
-                    System.arraycopy(node.keys,   left_idx, node.keys,   left_idx+ 1, moveFromLeft);
-                    System.arraycopy(node.values, left_idx, node.values, left_idx+ 1, moveFromLeft);
-                    node.keys  [left_idx] = null;
-                    node.values[left_idx] = null;
-                    node.left_idx++;
-                    node.size--;
-               }
-            }
+    public K lastKey() {
+        if (root == null) {
+            throw new NoSuchElementException();
         }
-        modCount++;
-        size--;
+        return root.last().getKey();
     }
 
-    private void deleteNode(Node<K, V> node) {
-        if (node.right == null) {
-            if (node.left != null) {
-                attachToParent(node, node.left);
-           } else {
-                attachNullToParent(node);
-            }
-            fixNextChain(node);
-        } else if(node.left == null) { // node.right != null
-            attachToParent(node, node.right);
-            fixNextChain(node);
-        } else {
-            // Here node.left!=nul && node.right!=null
-            // node.next should replace node in tree
-            // node.next!=null by tree logic.
-            // node.next.left==null by tree logic.
-            // node.next.right may be null or non-null
-            Node<K, V> toMoveUp = node.next;
-            fixNextChain(node);
-            if(toMoveUp.right==null){
-                attachNullToParent(toMoveUp);
-            } else {
-                attachToParent(toMoveUp, toMoveUp.right);
-            }
-            // Here toMoveUp is ready to replace node
-            toMoveUp.left = node.left;
-            if (node.left != null) {
-            	node.left.parent = toMoveUp;
-            }
-            toMoveUp.right = node.right;
-            if (node.right != null) {
-            	node.right.parent = toMoveUp;
-            }
-            attachToParentNoFixup(node,toMoveUp);
-            toMoveUp.color = node.color;
-        }
+    public Entry<K, V> lowerEntry(K key) {
+        return find(key, LOWER);
     }
 
-    private void attachToParentNoFixup(Node<K, V> toDelete, Node<K, V> toConnect) {
-        // assert toConnect!=null
-        Node<K,V> parent = toDelete.parent;
-        toConnect.parent = parent;
-        if (parent == null) {
-            root = toConnect;
-        } else if (toDelete == parent.left) {
-            parent.left = toConnect;
-        } else {
-            parent.right = toConnect;
-        }
+    public K lowerKey(K key) {
+        Entry<K, V> entry = find(key, LOWER);
+        return entry != null ? entry.getKey() : null;
     }
 
-    private void attachToParent(Node<K, V> toDelete, Node<K, V> toConnect) {
-        // assert toConnect!=null
-        attachToParentNoFixup(toDelete,toConnect);
-        if (!toDelete.color) {
-            fixup(toConnect);
-        }
+    public Entry<K, V> floorEntry(K key) {
+        return find(key, FLOOR);
     }
 
-    private void attachNullToParent(Node<K, V> toDelete) {
-        Node<K, V> parent = toDelete.parent;
-        if (parent == null) {
-            root = null;
-        } else {
-            if (toDelete == parent.left) {
-                parent.left = null;
-            } else {
-                parent.right = null;
-            }
-            if (!toDelete.color) {
-                fixup(parent);
-            }
-        }
+    public K floorKey(K key) {
+        Entry<K, V> entry = find(key, FLOOR);
+        return entry != null ? entry.getKey() : null;
     }
 
-    private void fixNextChain(Node<K, V> node) {
-        if (node.prev != null) {
-            node.prev.next = node.next;
-        }
-        if (node.next != null) {
-            node.next.prev = node.prev;
-        }
+    public Entry<K, V> ceilingEntry(K key) {
+        return find(key, CEILING);
     }
 
-    private void fixup(Node<K, V> x) {
-        Node<K, V> w;
-        while (x != root && !x.color) {
-            if (x == x.parent.left) {
-                w = x.parent.right;
-                if (w == null) {
-                    x = x.parent;
-                    continue;
-                }
-                if (w.color) {
-                    w.color = false;
-                    x.parent.color = true;
-                    leftRotate(x.parent);
-                    w = x.parent.right;
-                    if (w == null) {
-                        x = x.parent;
-                        continue;
-                    }
-                }
-                if ((w.left == null || !w.left.color)
-                    && (w.right == null || !w.right.color)) {
-                    w.color = true;
-                    x = x.parent;
-                } else {
-                    if (w.right == null || !w.right.color) {
-                        w.left.color = false;
-                        w.color = true;
-                        rightRotate(w);
-                        w = x.parent.right;
-                    }
-                    w.color = x.parent.color;
-                    x.parent.color = false;
-                    w.right.color = false;
-                    leftRotate(x.parent);
-                    x = root;
-                }
-            } else {
-                w = x.parent.left;
-                if (w == null) {
-                    x = x.parent;
-                    continue;
-                }
-                if (w.color) {
-                    w.color = false;
-                    x.parent.color = true;
-                    rightRotate(x.parent);
-                    w = x.parent.left;
-                    if (w == null) {
-                        x = x.parent;
-                        continue;
-                    }
-                }
-                if ((w.left == null || !w.left.color)
-                    && (w.right == null || !w.right.color)) {
-                    w.color = true;
-                    x = x.parent;
-                } else {
-                    if (w.left == null || !w.left.color) {
-                        w.right.color = false;
-                        w.color = true;
-                        leftRotate(w);
-                        w = x.parent.left;
-                    }
-                    w.color = x.parent.color;
-                    x.parent.color = false;
-                    w.left.color = false;
-                    rightRotate(x.parent);
-                    x = root;
-                }
-            }
-        }
-        x.color = false;
+    public K ceilingKey(K key) {
+        Entry<K, V> entry = find(key, CEILING);
+        return entry != null ? entry.getKey() : null;
     }
 
+    public Entry<K, V> higherEntry(K key) {
+        return find(key, HIGHER);
+    }
 
-    /**
-     * Returns the number of mappings in this map.
-     *
-     * @return the number of mappings in this map.
+    public K higherKey(K key) {
+        Entry<K, V> entry = find(key, HIGHER);
+        return entry != null ? entry.getKey() : null;
+    }
+
+    public Comparator<? super K> comparator() {
+        return comparator != NATURAL_ORDER ? comparator : null;
+    }
+
+    /*
+     * View factory methods.
      */
-    @Override
-    public int size() {
-        return size;
+
+    private EntrySet entrySet;
+    private KeySet keySet;
+
+    @Override public Set<Entry<K, V>> entrySet() {
+        EntrySet result = entrySet;
+        return result != null ? result : (entrySet = new EntrySet());
+    }
+
+    @Override public Set<K> keySet() {
+        KeySet result = keySet;
+        return result != null ? result : (keySet = new KeySet());
+    }
+
+    public NavigableSet<K> navigableKeySet() {
+        KeySet result = keySet;
+        return result != null ? result : (keySet = new KeySet());
+    }
+
+    public NavigableMap<K, V> subMap(K from, boolean fromInclusive, K to, boolean toInclusive) {
+        Bound fromBound = fromInclusive ? INCLUSIVE : EXCLUSIVE;
+        Bound toBound = toInclusive ? INCLUSIVE : EXCLUSIVE;
+        return new BoundedMap(true, from, fromBound, to, toBound);
+    }
+
+    public SortedMap<K, V> subMap(K fromInclusive, K toExclusive) {
+        return new BoundedMap(true, fromInclusive, INCLUSIVE, toExclusive, EXCLUSIVE);
+    }
+
+    public NavigableMap<K, V> headMap(K to, boolean inclusive) {
+        Bound toBound = inclusive ? INCLUSIVE : EXCLUSIVE;
+        return new BoundedMap(true, null, NO_BOUND, to, toBound);
+    }
+
+    public SortedMap<K, V> headMap(K toExclusive) {
+        return new BoundedMap(true, null, NO_BOUND, toExclusive, EXCLUSIVE);
+    }
+
+    public NavigableMap<K, V> tailMap(K from, boolean inclusive) {
+        Bound fromBound = inclusive ? INCLUSIVE : EXCLUSIVE;
+        return new BoundedMap(true, from, fromBound, null, NO_BOUND);
+    }
+
+    public SortedMap<K, V> tailMap(K fromInclusive) {
+        return new BoundedMap(true, fromInclusive, INCLUSIVE, null, NO_BOUND);
+    }
+
+    public NavigableMap<K, V> descendingMap() {
+        return new BoundedMap(false, null, NO_BOUND, null, NO_BOUND);
+    }
+
+    public NavigableSet<K> descendingKeySet() {
+        return new BoundedMap(false, null, NO_BOUND, null, NO_BOUND).navigableKeySet();
+    }
+
+    static class Node<K, V> implements Map.Entry<K, V> {
+        Node<K, V> parent;
+        Node<K, V> left;
+        Node<K, V> right;
+        final K key;
+        V value;
+        int height;
+
+        Node(Node<K, V> parent, K key) {
+            this.parent = parent;
+            this.key = key;
+            this.height = 1;
+        }
+
+        Node<K, V> copy(Node<K, V> parent) {
+            Node<K, V> result = new Node<K, V>(parent, key);
+            if (left != null) {
+                result.left = left.copy(result);
+            }
+            if (right != null) {
+                result.right = right.copy(result);
+            }
+            result.value = value;
+            result.height = height;
+            return result;
+        }
+
+        public K getKey() {
+            return key;
+        }
+
+        public V getValue() {
+            return value;
+        }
+
+        public V setValue(V value) {
+            throw new UnsupportedOperationException(); // per the spec
+        }
+
+        @Override public boolean equals(Object o) {
+            if (o instanceof Map.Entry) {
+                Map.Entry other = (Map.Entry) o;
+                return (key == null ? other.getKey() == null : key.equals(other.getKey()))
+                        && (value == null ? other.getValue() == null : value.equals(other.getValue()));
+            }
+            return false;
+        }
+
+        @Override public int hashCode() {
+            return (key == null ? 0 : key.hashCode())
+                    ^ (value == null ? 0 : value.hashCode());
+        }
+
+        @Override public String toString() {
+            return key + "=" + value;
+        }
+
+        /**
+         * Returns the next node in an inorder traversal, or null if this is the
+         * last node in the tree.
+         */
+        Node<K, V> next() {
+            if (right != null) {
+                return right.first();
+            }
+
+            Node<K, V> node = this;
+            Node<K, V> parent = node.parent;
+            while (parent != null) {
+                if (parent.left == node) {
+                    return parent;
+                }
+                node = parent;
+                parent = node.parent;
+            }
+            return null;
+        }
+
+        /**
+         * Returns the previous node in an inorder traversal, or null if this is
+         * the first node in the tree.
+         */
+        public Node<K, V> prev() {
+            if (left != null) {
+                return left.last();
+            }
+
+            Node<K, V> node = this;
+            Node<K, V> parent = node.parent;
+            while (parent != null) {
+                if (parent.right == node) {
+                    return parent;
+                }
+                node = parent;
+                parent = node.parent;
+            }
+            return null;
+        }
+
+        /**
+         * Returns the first node in this subtree.
+         */
+        public Node<K, V> first() {
+            Node<K, V> node = this;
+            Node<K, V> child = node.left;
+            while (child != null) {
+                node = child;
+                child = node.left;
+            }
+            return node;
+        }
+
+        /**
+         * Returns the last node in this subtree.
+         */
+        public Node<K, V> last() {
+            Node<K, V> node = this;
+            Node<K, V> child = node.right;
+            while (child != null) {
+                node = child;
+                child = node.right;
+            }
+            return node;
+        }
     }
 
     /**
-     * Returns a sorted map over a range of this sorted map with all keys
-     * greater than or equal to the specified {@code startKey} and less than the
-     * specified {@code endKey}. Changes to the returned sorted map are
-     * reflected in this sorted map and vice versa.
-     * <p>
-     * Note: The returned map will not allow an insertion of a key outside the
-     * specified range.
-     *
-     * @param startKey
-     *            the low boundary of the range (inclusive).
-     * @param endKey
-     *            the high boundary of the range (exclusive),
-     * @return a sorted map with the key from the specified range.
-     * @throws ClassCastException
-     *             if the start or end key cannot be compared with the keys in
-     *             this map.
-     * @throws NullPointerException
-     *             if the start or end key is {@code null} and the comparator
-     *             cannot handle {@code null} keys.
-     * @throws IllegalArgumentException
-     *             if the start key is greater than the end key, or if this map
-     *             is itself a sorted map over a range of another sorted map and
-     *             the specified range is outside of its range.
+     * Walk the nodes of the tree left-to-right or right-to-left. Note that in
+     * descending iterations, {@code next} will return the previous node.
      */
-    public SortedMap<K, V> subMap(K startKey, K endKey) {
-        if (comparator == null) {
-            if (toComparable(startKey).compareTo(endKey) <= 0) {
-                return new SubMap<K, V>(startKey, this, endKey);
-            }
-        } else {
-            if (comparator.compare(startKey, endKey) <= 0) {
-                return new SubMap<K, V>(startKey, this, endKey);
-            }
+    abstract class MapIterator<T> implements Iterator<T> {
+        protected Node<K, V> next;
+        protected Node<K, V> last;
+        protected int expectedModCount = modCount;
+
+        MapIterator(Node<K, V> next) {
+            this.next = next;
         }
-        throw new IllegalArgumentException();
+
+        public boolean hasNext() {
+            return next != null;
+        }
+
+        protected Node<K, V> stepForward() {
+            if (next == null) {
+                throw new NoSuchElementException();
+            }
+            if (modCount != expectedModCount) {
+                throw new ConcurrentModificationException();
+            }
+            last = next;
+            next = next.next();
+            return last;
+        }
+
+        protected Node<K, V> stepBackward() {
+            if (next == null) {
+                throw new NoSuchElementException();
+            }
+            if (modCount != expectedModCount) {
+                throw new ConcurrentModificationException();
+            }
+            last = next;
+            next = next.prev();
+            return last;
+        }
+
+        public void remove() {
+            if (last == null) {
+                throw new IllegalStateException();
+            }
+            removeInternal(last);
+            expectedModCount = modCount;
+            last = null;
+        }
     }
 
-    /**
-     * Returns a sorted map over a range of this sorted map with all keys that
-     * are greater than or equal to the specified {@code startKey}. Changes to
-     * the returned sorted map are reflected in this sorted map and vice versa.
-     * <p>
-     * Note: The returned map will not allow an insertion of a key outside the
-     * specified range.
-     *
-     * @param startKey
-     *            the low boundary of the range specified.
-     * @return a sorted map where the keys are greater or equal to
-     *         {@code startKey}.
-     * @throws ClassCastException
-     *             if the specified key cannot be compared with the keys in this
-     *             map.
-     * @throws NullPointerException
-     *             if the specified key is {@code null} and the comparator
-     *             cannot handle {@code null} keys.
-     * @throws IllegalArgumentException
-     *             if this map itself a sorted map over a range of another map
-     *             and the specified key is outside of its range.
+    /*
+     * View implementations.
      */
-    public SortedMap<K, V> tailMap(K startKey) {
-        // Check for errors
-        if (comparator == null) {
-            toComparable(startKey).compareTo(startKey);
-        } else {
-            comparator.compare(startKey, startKey);
+
+    class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+        @Override public int size() {
+            return size;
         }
-        return new SubMap<K, V>(startKey, this);
-    }
 
-    /**
-     * Returns a collection of the values contained in this map. The collection
-     * is backed by this map so changes to one are reflected by the other. The
-     * collection supports remove, removeAll, retainAll and clear operations,
-     * and it does not support add or addAll operations.
-     * <p>
-     * This method returns a collection which is the subclass of
-     * AbstractCollection. The iterator method of this subclass returns a
-     * "wrapper object" over the iterator of map's entrySet(). The {@code size}
-     * method wraps the map's size method and the {@code contains} method wraps
-     * the map's containsValue method.
-     * <p>
-     * The collection is created when this method is called for the first time
-     * and returned in response to all subsequent calls. This method may return
-     * different collections when multiple concurrent calls occur, since no
-     * synchronization is performed.
-     *
-     * @return a collection of the values contained in this map.
-     */
-    @Override
-    public Collection<V> values() {
-        if (valuesCollection == null) {
-            valuesCollection = new AbstractCollection<V>() {
-                @Override
-                public boolean contains(Object object) {
-                    return containsValue(object);
-                }
-
-                @Override
-                public int size() {
-                    return size;
-                }
-
-                @Override
-                public void clear() {
-                    TreeMap.this.clear();
-                }
-
-                @Override
-                public Iterator<V> iterator() {
-                    return new UnboundedValueIterator<K, V>(TreeMap.this);
+        @Override public Iterator<Entry<K, V>> iterator() {
+            return new MapIterator<Entry<K, V>>((Node<K, V>) firstEntry()) {
+                public Entry<K, V> next() {
+                    return stepForward();
                 }
             };
         }
-        return valuesCollection;
-    }
 
-    private void writeObject(ObjectOutputStream stream) throws IOException {
-        stream.defaultWriteObject();
-        stream.writeInt(size);
-        if (size > 0) {
-            Node<K, V> node = minimum(root);
-            while (node != null) {
-                int to = node.right_idx;
-                for (int i = node.left_idx; i <= to; i++) {
-                    stream.writeObject(node.keys[i]);
-                    stream.writeObject(node.values[i]);
-                }
-                node = node.next;
+        @Override public boolean contains(Object o) {
+            return o instanceof Entry && findByEntry((Entry<?, ?>) o) != null;
+        }
+
+        @Override public boolean remove(Object o) {
+            if (!(o instanceof Entry)) {
+                return false;
             }
+
+            Node<K, V> node = findByEntry((Entry<?, ?>) o);
+            if (node == null) {
+                return false;
+            }
+            removeInternal(node);
+            return true;
+        }
+
+        @Override public void clear() {
+            TreeMap.this.clear();
         }
     }
 
-    @SuppressWarnings("unchecked")
-    private void readObject(ObjectInputStream stream) throws IOException,
-                                                          ClassNotFoundException {
-        stream.defaultReadObject();
+    class KeySet extends AbstractSet<K> implements NavigableSet<K> {
+        @Override public int size() {
+            return size;
+        }
+
+        @Override public Iterator<K> iterator() {
+            return new MapIterator<K>((Node<K, V>) firstEntry()) {
+                public K next() {
+                    return stepForward().key;
+                }
+            };
+        }
+
+        public Iterator<K> descendingIterator() {
+            return new MapIterator<K>((Node<K, V>) lastEntry()) {
+                public K next() {
+                    return stepBackward().key;
+                }
+            };
+        }
+
+        @Override public boolean contains(Object o) {
+            return containsKey(o);
+        }
+
+        @Override public boolean remove(Object key) {
+            return removeInternalByKey(key) != null;
+        }
+
+        @Override public void clear() {
+            TreeMap.this.clear();
+        }
+
+        public Comparator<? super K> comparator() {
+            return TreeMap.this.comparator();
+        }
+
+        /*
+         * Navigable methods.
+         */
+
+        public K first() {
+            return firstKey();
+        }
+
+        public K last() {
+            return lastKey();
+        }
+
+        public K lower(K key) {
+            return lowerKey(key);
+        }
+
+        public K floor(K key) {
+            return floorKey(key);
+        }
+
+        public K ceiling(K key) {
+            return ceilingKey(key);
+        }
+
+        public K higher(K key) {
+            return higherKey(key);
+        }
+
+        public K pollFirst() {
+            Entry<K, V> entry = pollFirstEntry();
+            return entry != null ? entry.getKey() : null;
+        }
+
+        public K pollLast() {
+            Entry<K, V> entry = pollLastEntry();
+            return entry != null ? entry.getKey() : null;
+        }
+
+        /*
+         * View factory methods.
+         */
+
+        public NavigableSet<K> subSet(K from, boolean fromInclusive, K to, boolean toInclusive) {
+            return TreeMap.this.subMap(from, fromInclusive, to, toInclusive).navigableKeySet();
+        }
+
+        public SortedSet<K> subSet(K fromInclusive, K toExclusive) {
+            return TreeMap.this.subMap(fromInclusive, true, toExclusive, false).navigableKeySet();
+        }
+
+        public NavigableSet<K> headSet(K to, boolean inclusive) {
+            return TreeMap.this.headMap(to, inclusive).navigableKeySet();
+        }
+
+        public SortedSet<K> headSet(K toExclusive) {
+            return TreeMap.this.headMap(toExclusive, false).navigableKeySet();
+        }
+
+        public NavigableSet<K> tailSet(K from, boolean inclusive) {
+            return TreeMap.this.tailMap(from, inclusive).navigableKeySet();
+        }
+
+        public SortedSet<K> tailSet(K fromInclusive) {
+            return TreeMap.this.tailMap(fromInclusive, true).navigableKeySet();
+        }
+
+        public NavigableSet<K> descendingSet() {
+            return new BoundedMap(false, null, NO_BOUND, null, NO_BOUND).navigableKeySet();
+        }
+    }
+
+    /*
+     * Bounded views implementations.
+     */
+
+    enum Bound {
+        INCLUSIVE,
+        EXCLUSIVE,
+        NO_BOUND
+    }
+
+    /**
+     * A map with optional limits on its range.
+     */
+    final class BoundedMap extends AbstractMap<K, V> implements NavigableMap<K, V>, Serializable {
+        private final boolean ascending;
+        private final K from;
+        private final Bound fromBound;
+        private final K to;
+        private final Bound toBound;
+
+        BoundedMap(boolean ascending, K from, Bound fromBound, K to, Bound toBound) {
+            /*
+             * Validate the bounds. In addition to checking that from <= to, we
+             * verify that the comparator supports our bound objets.
+             */
+            if (fromBound != NO_BOUND && toBound != NO_BOUND) {
+                if (comparator.compare(from, to) > 0) {
+                    throw new IllegalArgumentException(from + " > " + to);
+                }
+            } else if (fromBound != NO_BOUND) {
+                comparator.compare(from, from);
+            } else if (toBound != NO_BOUND) {
+                comparator.compare(to, to);
+            }
+
+            this.ascending = ascending;
+            this.from = from;
+            this.fromBound = fromBound;
+            this.to = to;
+            this.toBound = toBound;
+        }
+
+        @Override public int size() {
+            return count(entrySet().iterator());
+        }
+
+        @Override public boolean isEmpty() {
+            return firstEntry() == null;
+        }
+
+        @Override public V get(Object key) {
+            return isInBounds(key) ? TreeMap.this.get(key) : null;
+        }
+
+        @Override public boolean containsKey(Object key) {
+            return isInBounds(key) && TreeMap.this.containsKey(key);
+        }
+
+        @Override public V put(K key, V value) {
+            if (!isInBounds(key)) {
+                throw new IllegalArgumentException();
+            }
+            return putInternal(key, value);
+        }
+
+        @Override public V remove(Object key) {
+            return isInBounds(key) ? TreeMap.this.remove(key) : null;
+        }
+
+        /**
+         * Returns true if the key is in bounds.
+         */
+        @SuppressWarnings("unchecked") // this method throws ClassCastExceptions!
+        private boolean isInBounds(Object key) {
+            return isInBounds((K) key, fromBound, toBound);
+        }
+
+        /**
+         * Returns true if the key is in bounds. Use this overload with
+         * NO_BOUND to skip bounds checking on either end.
+         */
+        private boolean isInBounds(K key, Bound fromBound, Bound toBound) {
+            if (fromBound == INCLUSIVE) {
+                if (comparator.compare(key, from) < 0) {
+                    return false; // less than from
+                }
+            } else if (fromBound == EXCLUSIVE) {
+                if (comparator.compare(key, from) <= 0) {
+                    return false; // less than or equal to from
+                }
+            }
+
+            if (toBound == INCLUSIVE) {
+                if (comparator.compare(key, to) > 0) {
+                    return false; // greater than 'to'
+                }
+            } else if (toBound == EXCLUSIVE) {
+                if (comparator.compare(key, to) >= 0) {
+                    return false; // greater than or equal to 'to'
+                }
+            }
+
+            return true;
+        }
+
+        /**
+         * Returns the entry if it is in bounds, or null if it is out of bounds.
+         */
+        private Entry<K, V> bound(Entry<K, V> node, Bound fromBound, Bound toBound) {
+            return node != null && isInBounds(node.getKey(), fromBound, toBound) ? node : null;
+        }
+
+        private Entry<K, V> bound(Entry<K, V> node) {
+            return bound(node, fromBound, toBound);
+        }
+
+        /*
+         * Navigable methods.
+         */
+
+        public Entry<K, V> firstEntry() {
+            return endpoint(true);
+        }
+
+        public Entry<K, V> pollFirstEntry() {
+            Node<K, V> result = (Node<K, V>) firstEntry();
+            if (result != null) {
+                removeInternal(result);
+            }
+            return result;
+        }
+
+        public K firstKey() {
+            Entry<K, V> entry = firstEntry();
+            if (entry == null) {
+                throw new NoSuchElementException();
+            }
+            return entry.getKey();
+        }
+
+        public Entry<K, V> lastEntry() {
+            return endpoint(false);
+        }
+
+        public Entry<K, V> pollLastEntry() {
+            Node<K, V> result = (Node<K, V>) lastEntry();
+            if (result != null) {
+                removeInternal(result);
+            }
+            return result;
+        }
+
+        public K lastKey() {
+            Entry<K, V> entry = lastEntry();
+            if (entry == null) {
+                throw new NoSuchElementException();
+            }
+            return entry.getKey();
+        }
+
+        /**
+         * @param first true for the first element, false for the last.
+         */
+        private Entry<K, V> endpoint(boolean first) {
+            Entry<K, V> entry;
+            if (ascending == first) {
+                switch (fromBound) {
+                    case NO_BOUND:
+                        entry = TreeMap.this.firstEntry();
+                        break;
+                    case INCLUSIVE:
+                        entry = TreeMap.this.ceilingEntry(from);
+                        break;
+                    case EXCLUSIVE:
+                        entry = TreeMap.this.higherEntry(from);
+                        break;
+                    default:
+                        throw new AssertionError();
+                }
+                return bound(entry, NO_BOUND, toBound);
+            } else {
+                switch (toBound) {
+                    case NO_BOUND:
+                        entry = TreeMap.this.lastEntry();
+                        break;
+                    case INCLUSIVE:
+                        entry = TreeMap.this.floorEntry(to);
+                        break;
+                    case EXCLUSIVE:
+                        entry = TreeMap.this.lowerEntry(to);
+                        break;
+                    default:
+                        throw new AssertionError();
+                }
+                return bound(entry, fromBound, NO_BOUND);
+            }
+        }
+
+        public Entry<K, V> lowerEntry(K key) {
+            return bound(find(key, LOWER.forOrder(ascending)));
+        }
+
+        public K lowerKey(K key) {
+            Entry<K, V> entry = bound(find(key, LOWER.forOrder(ascending)));
+            return entry != null ? entry.getKey() : null;
+        }
+
+        public Entry<K, V> floorEntry(K key) {
+            return bound(find(key, FLOOR.forOrder(ascending)));
+        }
+
+        public K floorKey(K key) {
+            Entry<K, V> entry = bound(find(key, FLOOR.forOrder(ascending)));
+            return entry != null ? entry.getKey() : null;
+        }
+
+        public Entry<K, V> ceilingEntry(K key) {
+            return bound(find(key, CEILING.forOrder(ascending)));
+        }
+
+        public K ceilingKey(K key) {
+            Entry<K, V> entry = bound(find(key, CEILING.forOrder(ascending)));
+            return entry != null ? entry.getKey() : null;
+        }
+
+        public Entry<K, V> higherEntry(K key) {
+            return bound(find(key, HIGHER.forOrder(ascending)));
+        }
+
+        public K higherKey(K key) {
+            Entry<K, V> entry = bound(find(key, HIGHER.forOrder(ascending)));
+            return entry != null ? entry.getKey() : null;
+        }
+
+        public Comparator<? super K> comparator() {
+          if (ascending) {
+            return TreeMap.this.comparator();
+          } else {
+            return Collections.reverseOrder(comparator);
+          }
+        }
+
+        /*
+         * View factory methods.
+         */
+
+        private BoundedEntrySet entrySet;
+        private BoundedKeySet keySet;
+
+        @Override public Set<Entry<K, V>> entrySet() {
+            BoundedEntrySet result = entrySet;
+            return result != null ? result : (entrySet = new BoundedEntrySet());
+        }
+
+        @Override public Set<K> keySet() {
+            return navigableKeySet();
+        }
+
+        public NavigableSet<K> navigableKeySet() {
+            BoundedKeySet result = keySet;
+            return result != null ? result : (keySet = new BoundedKeySet());
+        }
+
+        public NavigableMap<K, V> descendingMap() {
+            return new BoundedMap(!ascending, from, fromBound, to, toBound);
+        }
+
+        public NavigableSet<K> descendingKeySet() {
+            return new BoundedMap(!ascending, from, fromBound, to, toBound).navigableKeySet();
+        }
+
+        public NavigableMap<K, V> subMap(K from, boolean fromInclusive, K to, boolean toInclusive) {
+            Bound fromBound = fromInclusive ? INCLUSIVE : EXCLUSIVE;
+            Bound toBound = toInclusive ? INCLUSIVE : EXCLUSIVE;
+            return subMap(from, fromBound, to, toBound);
+        }
+
+        public NavigableMap<K, V> subMap(K fromInclusive, K toExclusive) {
+            return subMap(fromInclusive, INCLUSIVE, toExclusive, EXCLUSIVE);
+        }
+
+        public NavigableMap<K, V> headMap(K to, boolean inclusive) {
+            Bound toBound = inclusive ? INCLUSIVE : EXCLUSIVE;
+            return subMap(null, NO_BOUND, to, toBound);
+        }
+
+        public NavigableMap<K, V> headMap(K toExclusive) {
+            return subMap(null, NO_BOUND, toExclusive, EXCLUSIVE);
+        }
+
+        public NavigableMap<K, V> tailMap(K from, boolean inclusive) {
+            Bound fromBound = inclusive ? INCLUSIVE : EXCLUSIVE;
+            return subMap(from, fromBound, null, NO_BOUND);
+        }
+
+        public NavigableMap<K, V> tailMap(K fromInclusive) {
+            return subMap(fromInclusive, INCLUSIVE, null, NO_BOUND);
+        }
+
+        private NavigableMap<K, V> subMap(K from, Bound fromBound, K to, Bound toBound) {
+            if (!ascending) {
+                K fromTmp = from;
+                Bound fromBoundTmp = fromBound;
+                from = to;
+                fromBound = toBound;
+                to = fromTmp;
+                toBound = fromBoundTmp;
+            }
+
+            if (fromBound == NO_BOUND) {
+                from = this.from;
+                fromBound = this.fromBound;
+            } else if (this.fromBound != NO_BOUND) {
+                int comparison = comparator.compare(from, this.from);
+                if (comparison < 0 || (comparison == 0
+                        && fromBound == INCLUSIVE && this.fromBound == EXCLUSIVE)) {
+                    throw new IllegalArgumentException();
+                }
+            }
+
+            if (toBound == NO_BOUND) {
+                to = this.to;
+                toBound = this.toBound;
+            } else if (this.toBound != NO_BOUND) {
+                int comparison = comparator.compare(to, this.to);
+                if (comparison > 0 || (comparison == 0
+                        && toBound == EXCLUSIVE && this.toBound == INCLUSIVE)) {
+                    throw new IllegalArgumentException();
+                }
+            }
+
+            return new BoundedMap(ascending, from, fromBound, to, toBound);
+        }
+
+        /*
+         * Bounded view implementations.
+         */
+
+        abstract class BoundedIterator<T> extends MapIterator<T> {
+            protected BoundedIterator(Node<K, V> next) {
+                super(next);
+            }
+
+            @Override protected Node<K, V> stepForward() {
+                Node<K, V> result = super.stepForward();
+                if (next != null && !isInBounds(next.key, NO_BOUND, toBound)) {
+                    next = null;
+                }
+                return result;
+            }
+
+            @Override protected Node<K, V> stepBackward() {
+                Node<K, V> result = super.stepBackward();
+                if (next != null && !isInBounds(next.key, fromBound, NO_BOUND)) {
+                    next = null;
+                }
+                return result;
+            }
+        }
+
+        final class BoundedEntrySet extends AbstractSet<Entry<K, V>> {
+            @Override public int size() {
+                return BoundedMap.this.size();
+            }
+
+            @Override public boolean isEmpty() {
+                return BoundedMap.this.isEmpty();
+            }
+
+            @Override public Iterator<Entry<K, V>> iterator() {
+                return new BoundedIterator<Entry<K, V>>((Node<K, V>) firstEntry()) {
+                    public Entry<K, V> next() {
+                        return ascending ? stepForward() : stepBackward();
+                    }
+                };
+            }
+
+            @Override public boolean contains(Object o) {
+                if (!(o instanceof Entry)) {
+                    return false;
+                }
+                Entry<?, ?> entry = (Entry<?, ?>) o;
+                return isInBounds(entry.getKey()) && findByEntry(entry) != null;
+            }
+
+            @Override public boolean remove(Object o) {
+                if (!(o instanceof Entry)) {
+                    return false;
+                }
+                Entry<?, ?> entry = (Entry<?, ?>) o;
+                return isInBounds(entry.getKey()) && TreeMap.this.entrySet().remove(entry);
+            }
+        }
+
+        final class BoundedKeySet extends AbstractSet<K> implements NavigableSet<K> {
+            @Override public int size() {
+                return BoundedMap.this.size();
+            }
+
+            @Override public boolean isEmpty() {
+                return BoundedMap.this.isEmpty();
+            }
+
+            @Override public Iterator<K> iterator() {
+                return new BoundedIterator<K>((Node<K, V>) firstEntry()) {
+                    public K next() {
+                        return (ascending ? stepForward() : stepBackward()).key;
+                    }
+                };
+            }
+
+            public Iterator<K> descendingIterator() {
+                return new BoundedIterator<K>((Node<K, V>) lastEntry()) {
+                    public K next() {
+                        return (ascending ? stepBackward() : stepForward()).key;
+                    }
+                };
+            }
+
+            @Override public boolean contains(Object key) {
+                return isInBounds(key) && findByObject(key) != null;
+            }
+
+            @Override public boolean remove(Object key) {
+                return isInBounds(key) && removeInternalByKey(key) != null;
+            }
+
+            /*
+             * Navigable methods.
+             */
+
+            public K first() {
+                return firstKey();
+            }
+
+            public K pollFirst() {
+                Entry<K, ?> entry = pollFirstEntry();
+                return entry != null ? entry.getKey() : null;
+            }
+
+            public K last() {
+                return lastKey();
+            }
+
+            public K pollLast() {
+                Entry<K, ?> entry = pollLastEntry();
+                return entry != null ? entry.getKey() : null;
+            }
+
+            public K lower(K key) {
+                return lowerKey(key);
+            }
+
+            public K floor(K key) {
+                return floorKey(key);
+            }
+
+            public K ceiling(K key) {
+                return ceilingKey(key);
+            }
+
+            public K higher(K key) {
+                return higherKey(key);
+            }
+
+            public Comparator<? super K> comparator() {
+                return BoundedMap.this.comparator();
+            }
+
+            /*
+             * View factory methods.
+             */
+
+            public NavigableSet<K> subSet(K from, boolean fromInclusive, K to, boolean toInclusive) {
+                return subMap(from, fromInclusive, to, toInclusive).navigableKeySet();
+            }
+
+            public SortedSet<K> subSet(K fromInclusive, K toExclusive) {
+                return subMap(fromInclusive, toExclusive).navigableKeySet();
+            }
+
+            public NavigableSet<K> headSet(K to, boolean inclusive) {
+                return headMap(to, inclusive).navigableKeySet();
+            }
+
+            public SortedSet<K> headSet(K toExclusive) {
+                return headMap(toExclusive).navigableKeySet();
+            }
+
+            public NavigableSet<K> tailSet(K from, boolean inclusive) {
+                return tailMap(from, inclusive).navigableKeySet();
+            }
+
+            public SortedSet<K> tailSet(K fromInclusive) {
+                return tailMap(fromInclusive).navigableKeySet();
+            }
+
+            public NavigableSet<K> descendingSet() {
+                return new BoundedMap(!ascending, from, fromBound, to, toBound).navigableKeySet();
+            }
+        }
+
+        Object writeReplace() throws ObjectStreamException {
+            return ascending
+                    ? new AscendingSubMap<K, V>(TreeMap.this, from, fromBound, to, toBound)
+                    : new DescendingSubMap<K, V>(TreeMap.this, from, fromBound, to, toBound);
+        }
+    }
+
+    /**
+     * Returns the number of elements in the iteration.
+     */
+    static int count(Iterator<?> iterator) {
+        int count = 0;
+        while (iterator.hasNext()) {
+            iterator.next();
+            count++;
+        }
+        return count;
+    }
+
+    /*
+     * Serialization
+     */
+
+    private static final long serialVersionUID = 919286545866124006L;
+
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+        stream.putFields().put("comparator", comparator != NATURAL_ORDER ? comparator : null);
+        stream.writeFields();
+        stream.writeInt(size);
+        for (Map.Entry<K, V> entry : entrySet()) {
+            stream.writeObject(entry.getKey());
+            stream.writeObject(entry.getValue());
+        }
+    }
+
+    @SuppressWarnings("unchecked") // we have to trust that keys are Ks and values are Vs
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+        GetField fields = stream.readFields();
+        comparator = (Comparator<? super K>) fields.get("comparator", null);
+        if (comparator == null) {
+            comparator = (Comparator<? super K>) NATURAL_ORDER;
+        }
         int size = stream.readInt();
-        Node<K, V> lastNode = null;
         for (int i = 0; i < size; i++) {
-            lastNode = addToLast(lastNode, (K) stream.readObject(), (V) stream.readObject());
+            putInternal((K) stream.readObject(), (V) stream.readObject());
+        }
+    }
+
+    static abstract class NavigableSubMap<K, V> extends AbstractMap<K, V> implements Serializable {
+        private static final long serialVersionUID = -2102997345730753016L;
+        TreeMap<K, V> m;
+        Object lo;
+        Object hi;
+        boolean fromStart;
+        boolean toEnd;
+        boolean loInclusive;
+        boolean hiInclusive;
+
+        NavigableSubMap(TreeMap<K, V> delegate, K from, Bound fromBound, K to, Bound toBound) {
+            this.m = delegate;
+            this.lo = from;
+            this.hi = to;
+            this.fromStart = fromBound == NO_BOUND;
+            this.toEnd = toBound == NO_BOUND;
+            this.loInclusive = fromBound == INCLUSIVE;
+            this.hiInclusive = toBound == INCLUSIVE;
+        }
+
+        @Override public Set<Entry<K, V>> entrySet() {
+            throw new UnsupportedOperationException();
+        }
+
+        @SuppressWarnings("unchecked") // we have to trust that the bounds are Ks
+        protected Object readResolve() throws ObjectStreamException {
+            Bound fromBound = fromStart ? NO_BOUND : (loInclusive ? INCLUSIVE : EXCLUSIVE);
+            Bound toBound = toEnd ? NO_BOUND : (hiInclusive ? INCLUSIVE : EXCLUSIVE);
+            boolean ascending = !(this instanceof DescendingSubMap);
+            return m.new BoundedMap(ascending, (K) lo, fromBound, (K) hi, toBound);
+        }
+    }
+
+    static class DescendingSubMap<K, V> extends NavigableSubMap<K, V> {
+        private static final long serialVersionUID = 912986545866120460L;
+        Comparator<K> reverseComparator;
+        DescendingSubMap(TreeMap<K, V> delegate, K from, Bound fromBound, K to, Bound toBound) {
+            super(delegate, from, fromBound, to, toBound);
+        }
+    }
+
+    static class AscendingSubMap<K, V> extends NavigableSubMap<K, V> {
+        private static final long serialVersionUID = 912986545866124060L;
+        AscendingSubMap(TreeMap<K, V> delegate, K from, Bound fromBound, K to, Bound toBound) {
+            super(delegate, from, fromBound, to, toBound);
+        }
+    }
+
+    class SubMap extends AbstractMap<K, V> implements Serializable {
+        private static final long serialVersionUID = -6520786458950516097L;
+        Object fromKey;
+        Object toKey;
+        boolean fromStart;
+        boolean toEnd;
+
+        @Override public Set<Entry<K, V>> entrySet() {
+            throw new UnsupportedOperationException();
+        }
+
+        @SuppressWarnings("unchecked") // we have to trust that the bounds are Ks
+        protected Object readResolve() throws ObjectStreamException {
+            Bound fromBound = fromStart ? NO_BOUND : INCLUSIVE;
+            Bound toBound = toEnd ? NO_BOUND : EXCLUSIVE;
+            return new BoundedMap(true, (K) fromKey, fromBound, (K) toKey, toBound);
         }
     }
 }
diff --git a/luni/src/main/java/java/util/TreeSet.java b/luni/src/main/java/java/util/TreeSet.java
index b6ed5ff..98f6303 100644
--- a/luni/src/main/java/java/util/TreeSet.java
+++ b/luni/src/main/java/java/util/TreeSet.java
@@ -377,12 +377,9 @@
         TreeMap<E, Object> map = new TreeMap<E, Object>(
                 (Comparator<? super E>) stream.readObject());
         int size = stream.readInt();
-        if (size > 0) {
-            TreeMap.Node<E, Object> lastNode = null;
-            for(int i=0; i<size; i++) {
-                E elem = (E)stream.readObject();
-                lastNode = map.addToLast(lastNode,elem, Boolean.TRUE);
-            }
+        for (int i = 0; i < size; i++) {
+            E elem = (E)stream.readObject();
+            map.put(elem, Boolean.TRUE);
         }
         backingMap = map;
     }
diff --git a/luni/src/main/java/java/util/package.html b/luni/src/main/java/java/util/package.html
index 6b38357..3656147 100644
--- a/luni/src/main/java/java/util/package.html
+++ b/luni/src/main/java/java/util/package.html
@@ -6,6 +6,5 @@
       and maps), classes for dealing with date and time, String-handling, formatting,
       localization, and scheduling repeated tasks.
     </p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/luni/src/main/java/java/util/spi/CurrencyNameProvider.java b/luni/src/main/java/java/util/spi/CurrencyNameProvider.java
new file mode 100644
index 0000000..90806c8
--- /dev/null
+++ b/luni/src/main/java/java/util/spi/CurrencyNameProvider.java
@@ -0,0 +1,49 @@
+/*

+ *  Licensed to the Apache Software Foundation (ASF) under one or more

+ *  contributor license agreements.  See the NOTICE file distributed with

+ *  this work for additional information regarding copyright ownership.

+ *  The ASF licenses this file to You under the Apache License, Version 2.0

+ *  (the "License"); you may not use this file except in compliance with

+ *  the License.  You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+

+package java.util.spi;

+

+import java.util.Locale;

+

+/**

+ * This abstract class should be extended by service providers that provide

+ * localized currency symbols (currency names) from currency codes.

+ * <p>Note that Android does not currently support user-supplied locale service providers.

+ * @since 1.6

+ * @hide

+ */

+public abstract class CurrencyNameProvider extends LocaleServiceProvider {

+    /**

+     * Default constructor, for use by subclasses.

+     */

+    protected CurrencyNameProvider() {

+        // do nothing

+    }

+

+    /**

+     * Returns the localized currency symbol for the given currency code.

+     * 

+     * @param code an ISO 4217 currency code

+     * @param locale a locale

+     * @return the symbol or null if there is no available symbol in the locale

+     * @throws NullPointerException

+     *             if {@code code == null || locale == null}

+     * @throws IllegalArgumentException

+     *             if code or locale is not in a legal format or not available

+     */

+    public abstract String getSymbol(String code, Locale locale);

+}

diff --git a/luni/src/main/java/java/util/spi/LocaleNameProvider.java b/luni/src/main/java/java/util/spi/LocaleNameProvider.java
new file mode 100644
index 0000000..099ef7d
--- /dev/null
+++ b/luni/src/main/java/java/util/spi/LocaleNameProvider.java
@@ -0,0 +1,75 @@
+/*

+ *  Licensed to the Apache Software Foundation (ASF) under one or more

+ *  contributor license agreements.  See the NOTICE file distributed with

+ *  this work for additional information regarding copyright ownership.

+ *  The ASF licenses this file to You under the Apache License, Version 2.0

+ *  (the "License"); you may not use this file except in compliance with

+ *  the License.  You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+

+package java.util.spi;

+

+import java.util.Locale;

+

+/**

+ * This abstract class should be extended by service providers that provide

+ * localized locale names.

+ * <p>Note that Android does not currently support user-supplied locale service providers.

+ * @since 1.6

+ * @hide

+ */

+public abstract class LocaleNameProvider extends LocaleServiceProvider {

+    /**

+     * Default constructor, for use by subclasses.

+     */

+    protected LocaleNameProvider() {

+        // do nothing

+    }

+

+    /**

+     * Returns the localized name for the given ISO 639 language code.

+     * 

+     * @param languageCode an ISO 639 language code

+     * @param locale a locale

+     * @return the name or null if unavailable

+     * @throws NullPointerException

+     *             if {@code code == null || locale == null}

+     * @throws IllegalArgumentException

+     *             if code or locale is not in a legal format or not available

+     */

+    public abstract String getDisplayLanguage(String languageCode, Locale locale);

+

+    /**

+     * Returns the localized name for the given ISO 3166 country code.

+     * 

+     * @param countryCode an ISO 3166 language code

+     * @param locale a locale

+     * @return the name or null if unavailable

+     * @throws NullPointerException

+     *             if {@code code == null || locale == null}

+     * @throws IllegalArgumentException

+     *             if code or locale is not in a legal format or not available

+     */

+    public abstract String getDisplayCountry(String countryCode, Locale locale);

+

+    /**

+     * Returns the localized name for the given variant code.

+     * 

+     * @param variantCode a variant code

+     * @param locale a locale

+     * @return the name or null if unavailable

+     * @throws NullPointerException

+     *             if {@code code == null || locale == null}

+     * @throws IllegalArgumentException

+     *             if code or locale is not in a legal format or not available

+     */

+    public abstract String getDisplayVariant(String variantCode, Locale locale);

+}

diff --git a/luni/src/main/java/java/util/spi/LocaleServiceProvider.java b/luni/src/main/java/java/util/spi/LocaleServiceProvider.java
new file mode 100644
index 0000000..44f935b
--- /dev/null
+++ b/luni/src/main/java/java/util/spi/LocaleServiceProvider.java
@@ -0,0 +1,40 @@
+/*

+ *  Licensed to the Apache Software Foundation (ASF) under one or more

+ *  contributor license agreements.  See the NOTICE file distributed with

+ *  this work for additional information regarding copyright ownership.

+ *  The ASF licenses this file to You under the Apache License, Version 2.0

+ *  (the "License"); you may not use this file except in compliance with

+ *  the License.  You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+

+package java.util.spi;

+

+import java.util.Locale;

+

+/**

+ * The base class for all the locale related service provider interfaces (SPIs).

+ * <p>Note that Android does not currently support user-supplied locale service providers.

+ * @since 1.6

+ * @hide

+ */

+public abstract class LocaleServiceProvider {

+    /**

+     * Default constructor, for use by subclasses.

+     */

+    protected LocaleServiceProvider() {

+        // do nothing

+    }

+

+    /**

+     * Returns all locales for which this locale service provider has localized objects or names.

+     */

+    public abstract Locale[] getAvailableLocales();

+}

diff --git a/luni/src/main/java/java/util/spi/TimeZoneNameProvider.java b/luni/src/main/java/java/util/spi/TimeZoneNameProvider.java
new file mode 100644
index 0000000..e06192f
--- /dev/null
+++ b/luni/src/main/java/java/util/spi/TimeZoneNameProvider.java
@@ -0,0 +1,51 @@
+/*

+ *  Licensed to the Apache Software Foundation (ASF) under one or more

+ *  contributor license agreements.  See the NOTICE file distributed with

+ *  this work for additional information regarding copyright ownership.

+ *  The ASF licenses this file to You under the Apache License, Version 2.0

+ *  (the "License"); you may not use this file except in compliance with

+ *  the License.  You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ *  Unless required by applicable law or agreed to in writing, software

+ *  distributed under the License is distributed on an "AS IS" BASIS,

+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ *  See the License for the specific language governing permissions and

+ *  limitations under the License.

+ */

+

+package java.util.spi;

+

+import java.util.Locale;

+

+/**

+ * This abstract class should be extended by service providers that provide

+ * localized time zone names.

+ * <p>Note that Android does not currently support user-supplied locale service providers.

+ * @since 1.6

+ * @hide

+ */

+public abstract class TimeZoneNameProvider extends LocaleServiceProvider {

+    /**

+     * Default constructor, for use by subclasses.

+     */

+    protected TimeZoneNameProvider() {

+        // do nothing

+    }

+

+    /**

+     * Returns the localized name for the given time zone in the given locale.

+     * 

+     * @param id the time zone id

+     * @param daylight true to return the name for daylight saving time.

+     * @param style TimeZone.LONG or TimeZone.SHORT

+     * @param locale the locale

+     * @return the readable time zone name, or null if it is unavailable

+     * @throws NullPointerException

+     *             if {@code id == null || locale == null}

+     * @throws IllegalArgumentException

+     *             if locale is not available or style is invalid

+     */

+    public abstract String getDisplayName(String id, boolean daylight, int style, Locale locale);

+}

diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
index 7f738d3..72c078f 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
@@ -81,9 +81,7 @@
             is = getDirectoryListing(f);
             // use -1 for the contentLength
         } else {
-            // BEGIN android-modified
-            is = new BufferedInputStream(new FileInputStream(f), 8192);
-            // END android-modified
+            is = new BufferedInputStream(new FileInputStream(f));
             length = is.available();
         }
         connected = true;
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
index 3f02817..3f1ac79 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
@@ -250,13 +250,9 @@
             throw new IOException(Msg.getString("K0095")); //$NON-NLS-1$
         }
         if (getDoInput()) {
-            // BEGIN android-modified
             inputStream = new FtpURLInputStream(
-                    new BufferedInputStream(dataSocket.getInputStream(), 8192),
-                    controlSocket);
-            // END android-modified
+                    new BufferedInputStream(dataSocket.getInputStream()), controlSocket);
         }
-
     }
 
     /**
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
index bdd1d0a..f919b39 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
@@ -19,7 +19,8 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.SortedMap;
+import java.util.TreeMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -30,13 +31,9 @@
  * constructed by hashtable with key indexed in a vector for position lookup.
  */
 public class Header implements Cloneable {
-    /*
-     * we use the non-synchronized ArrayList and HashMap instead of the
-     * synchronized Vector and Hashtable
-     */
     private ArrayList<String> props;
 
-    private HashMap<String, LinkedList<String>> keyTable;
+    private SortedMap<String, LinkedList<String>> keyTable;
 
     private String statusLine;
 
@@ -48,7 +45,8 @@
     public Header() {
         super();
         this.props = new ArrayList<String>(20);
-        this.keyTable = new HashMap<String, LinkedList<String>>(20);
+        this.keyTable = new TreeMap<String, LinkedList<String>>(
+                String.CASE_INSENSITIVE_ORDER);
     }
 
     /**
@@ -62,11 +60,11 @@
         this(); // initialize fields
         for (Entry<String, List<String>> next : map.entrySet()) {
             String key = next.getKey();
-            props.add(key);
             List<String> value = next.getValue();
             LinkedList<String> linkedList = new LinkedList<String>();
             for (String element : value) {
                 linkedList.add(element);
+                props.add(key);
                 props.add(element);
             }
             keyTable.put(key, linkedList);
@@ -79,7 +77,8 @@
         try {
             Header clone = (Header) super.clone();
             clone.props = (ArrayList<String>) props.clone();
-            clone.keyTable = new HashMap<String, LinkedList<String>>(20);
+            clone.keyTable = new TreeMap<String, LinkedList<String>>(
+                    String.CASE_INSENSITIVE_ORDER);
             for (Map.Entry<String, LinkedList<String>> next : this.keyTable
                     .entrySet()) {
                 LinkedList<String> v = (LinkedList<String>) next.getValue()
@@ -102,14 +101,11 @@
         if (key == null) {
             throw new NullPointerException();
         }
-        // BEGIN android-changed
-        key = key.toLowerCase();
         LinkedList<String> list = keyTable.get(key);
         if (list == null) {
             list = new LinkedList<String>();
             keyTable.put(key, list);
         }
-        // END android-changed
         list.add(value);
         props.add(key);
         props.add(value);
@@ -126,9 +122,6 @@
         if (key == null) {
             throw new NullPointerException();
         }
-        // BEGIN android-added
-        key = key.toLowerCase();
-        // END android-added
         LinkedList<String> list = keyTable.get(key);
         if (list == null) {
             add(key, value);
@@ -154,8 +147,7 @@
      * @since 1.4
      */
     public Map<String, List<String>> getFieldMap() {
-        Map<String, List<String>> result = new HashMap<String, List<String>>(
-                keyTable.size());
+        Map<String, List<String>> result = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER); // android-changed
         for (Map.Entry<String, LinkedList<String>> next : keyTable.entrySet()) {
             List<String> v = next.getValue();
             result.put(next.getKey(), Collections.unmodifiableList(v));
@@ -203,7 +195,7 @@
      *         such key exists.
      */
     public String get(String key) {
-        LinkedList<String> result = keyTable.get(key.toLowerCase());
+        LinkedList<String> result = keyTable.get(key);
         if (result == null) {
             return null;
         }
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java
index 55d762d..905d9ab 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java
@@ -30,7 +30,7 @@
  * and host name (<code>String</code>) or all three,  depending on whether or not a 
  * <code>Proxy</code> is used and the type of <code>Proxy</code> it is.
  * 
- * <code>HttpConfiguration</code> is used as a key by <code>HttpConnectionManager</code>
+ * <code>HttpConfiguration</code> is used as a key by <code>HttpConnectionPool</code>
  * to retrieve <code>HttpConnection</code>s from its connection pool.
  */
 public class HttpConfiguration {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
index 4c51bdc..3491ccc 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
@@ -24,13 +24,10 @@
 import java.net.Proxy;
 import java.net.Socket;
 import java.net.SocketException;
-
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 
-import org.apache.harmony.luni.internal.nls.Messages;
-
 /**
  * An <code>HttpConnection</code> represents a persistent http or https connection and contains
  * various utility methods to access that connection.
@@ -158,16 +155,15 @@
     }
     
     public SSLSocket getSecureSocket(SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier) throws IOException {
-        if(!usingSecureSocket) {
+        if (!usingSecureSocket) {
             String hostName = config.getHostName();
             int port = config.getHostPort();
             // create the wrapper over connected socket
-            sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket,
-                    hostName, port, true);
+            sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket, hostName, port, true);
             sslSocket.setUseClientMode(true);
             sslSocket.startHandshake();
             if (!hostnameVerifier.verify(hostName, sslSocket.getSession())) {
-                throw new IOException(Messages.getString("luni.02", hostName)); //$NON-NLS-1$
+                throw new IOException("Hostname '" + hostName + "' was not verified");
             }
             usingSecureSocket = true;
         }
@@ -268,4 +264,4 @@
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java
deleted file mode 100644
index 61d7cbe..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.harmony.luni.internal.net.www.protocol.http;
-
-import java.io.IOException;
-import java.net.Proxy;
-import java.net.URI;
-import java.security.AccessController;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.harmony.luni.util.PriviAction;
-
-/**
- * <code>HttpConnectionManager</code> manages a pool of <code>HttpConnection</code>s
- * that are not currently in use and is used to get hold of persistent <code>HttpConnection</code>s.  
- * Clients should return an <code>HttpConnection</code> to the pool after use by calling 
- * <code>returnConnectionToPool</code>
- * 
- * Two system properties affect the behaviour of this class - <code>http.maxConnections</code>
- * and <code>http.keepAlive</code>.  <code>http.keepAlive</code> determines whether 
- * or not connections should be persisted and <code>http.maxConnections</code> 
- * determines the maximum number of connections to each individual host that 
- * should be kept in the pool.
- */
-public class HttpConnectionManager {
-
-    // The maximum number of connections to any location
-    private static int maxConnections = 5;
-
-    // Keeps connections alive if true
-    private static boolean keepAlive = true;
-
-    private static HttpConnectionManager defaultConnectionManager;
-    private ConnectionPool pool = new ConnectionPool();
-
-    /**
-     * Returns the default connection manager
-     */
-    public static HttpConnectionManager getDefault() {
-        if(defaultConnectionManager == null) {
-            defaultConnectionManager = new HttpConnectionManager();
-        }
-        return defaultConnectionManager;
-    }
-
-    public HttpConnection getConnection(URI uri, int connectTimeout) throws IOException {
-        checkSystemProperties();
-        HttpConfiguration config = new HttpConfiguration(uri);
-        return pool.getHttpConnection(config, connectTimeout);
-    }
-
-    public HttpConnection getConnection(URI uri, Proxy proxy, int connectTimeout) throws IOException {
-        checkSystemProperties();
-        HttpConfiguration config = new HttpConfiguration(uri, proxy);
-        return pool.getHttpConnection(config, connectTimeout);
-    }
-
-    public void returnConnectionToPool(HttpConnection connection) {
-        checkSystemProperties();
-        pool.returnConnection(connection);
-    }
-
-    public int numFreeConnections() {
-        return pool.numFreeConnections();
-    }
-
-    private void checkSystemProperties() {
-        String httpMaxConnections =  AccessController.doPrivileged(new PriviAction<String>("http.maxConnections"));
-        String httpKeepAlive = AccessController.doPrivileged(new PriviAction<String>("http.keepAlive"));
-        if(httpMaxConnections != null) {
-            maxConnections = Integer.parseInt(httpMaxConnections);
-        }
-        if(httpKeepAlive != null) {
-            keepAlive = Boolean.parseBoolean(httpKeepAlive);
-            if(!keepAlive) {
-                pool.clear();
-            }
-        }
-    }
-
-    private static class ConnectionPool {
-
-        private Map<HttpConfiguration, List<HttpConnection>> freeConnectionMap = new HashMap<HttpConfiguration, List<HttpConnection>>(); // Map of free Sockets
-
-        public synchronized void clear() {
-            for (Iterator<List<HttpConnection>> iter = freeConnectionMap.values().iterator(); iter.hasNext();) {
-                List<HttpConnection> connections = iter.next();
-                for (Iterator<HttpConnection> iterator = connections.iterator(); iterator.hasNext();) {
-                    HttpConnection connection = iterator.next();
-                    connection.closeSocketAndStreams();
-                }
-            }
-            freeConnectionMap.clear();
-        }
-
-        public synchronized void returnConnection(HttpConnection connection) {
-            // BEGIN android-note
-            // Simplified the following test.
-            // END android-note
-            if(keepAlive && connection.isEligibleForRecycling()) {
-                HttpConfiguration config = connection.getHttpConfiguration();
-                List<HttpConnection> connections = freeConnectionMap.get(config);
-                if(connections == null) {
-                    connections = new ArrayList<HttpConnection>();
-                    freeConnectionMap.put(config, connections);
-                }
-                if(connections.size() < HttpConnectionManager.maxConnections) {
-                    if(!connections.contains(connection)) {
-                        connections.add(connection);
-                    }
-                } else {
-                    connection.closeSocketAndStreams();
-                }
-            } else {
-                // Make sure all streams are closed etc.
-                connection.closeSocketAndStreams();
-            }
-        }
-
-        public synchronized HttpConnection getHttpConnection(HttpConfiguration config, int connectTimeout) throws IOException {
-            List<HttpConnection> connections = freeConnectionMap.get(config);
-            if(keepAlive && connections == null) {
-                connections = new ArrayList<HttpConnection>();
-                freeConnectionMap.put(config, connections);
-            }
-            if(!keepAlive || connections.isEmpty()) {
-                HttpConnection connection = new HttpConnection(config, connectTimeout);
-                return connection;
-            } else {
-                HttpConnection connection = connections.get(0);
-                connections.remove(0);
-                if(!connection.isStale()) {
-                    SecurityManager security = System.getSecurityManager();
-                    if (security != null) {
-                        security.checkConnect(connection.getSocket().getInetAddress().getHostName(), connection.getSocket().getPort());
-                    }
-                    return connection;                 
-                } else {
-                    return getHttpConnection(config, connectTimeout);
-                }
-            }
-        }
-
-        public int numFreeConnections() {
-            int numFree = 0;
-            for (Iterator<List<HttpConnection>> iter = freeConnectionMap.values().iterator(); iter.hasNext();) {
-                List<HttpConnection> connections = iter.next();
-                numFree += connections.size();
-            }
-            return numFree;
-        }
-    }
-
-    public void reset() {
-        pool.clear();
-    }
-
-}
\ No newline at end of file
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionPool.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionPool.java
new file mode 100644
index 0000000..c3a997b
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionPool.java
@@ -0,0 +1,110 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.harmony.luni.internal.net.www.protocol.http;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * A pool of HTTP connections. This class exposes its tuning parameters as
+ * system properties:
+ * <ul>
+ *   <li>{@code http.keepAlive} true if HTTP connections should be pooled at
+ *       all. Default is true.
+ *   <li>{@code http.maxConnections} maximum number of connections to each URI.
+ *       Default is 5.
+ * </ul>
+ *
+ * <p>This class <i>doesn't</i> adjust its configuration as system properties
+ * are changed. This assumes that the applications that set these parameters do
+ * so before making HTTP connections, and that this class is initialized lazily.
+ *
+ * <p>If a security manager is in place, HTTP connection pooling will be
+ * disabled and these system properties will be ignored.
+ */
+public final class HttpConnectionPool {
+
+    public static final HttpConnectionPool INSTANCE = new HttpConnectionPool();
+
+    private final int maxConnections;
+    private final HashMap<HttpConfiguration, List<HttpConnection>> connectionPool
+            = new HashMap<HttpConfiguration, List<HttpConnection>>();
+
+    private HttpConnectionPool() {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            maxConnections = 0;
+            return;
+        }
+
+        String keepAlive = System.getProperty("http.keepAlive");
+        if (keepAlive != null && !Boolean.parseBoolean(keepAlive)) {
+            maxConnections = 0;
+            return;
+        }
+
+        String maxConnectionsString = System.getProperty("http.maxConnections");
+        this.maxConnections = maxConnectionsString != null
+                ? Integer.parseInt(maxConnectionsString)
+                : 5;
+    }
+
+    public HttpConnection get(HttpConfiguration config, int connectTimeout) throws IOException {
+        // First try to reuse an existing HTTP connection.
+        synchronized (connectionPool) {
+            List<HttpConnection> connections = connectionPool.get(config);
+            if (connections != null) {
+                while (!connections.isEmpty()) {
+                    HttpConnection connection = connections.remove(connections.size() - 1);
+                    if (!connection.isStale()) {
+                        return connection;
+                    }
+                }
+                connectionPool.remove(config);
+            }
+        }
+
+        /*
+         * We couldn't find a reusable connection, so we need to create a new
+         * connection. We're careful not to do so while holding a lock!
+         */
+        return new HttpConnection(config, connectTimeout);
+    }
+
+    public void recycle(HttpConnection connection) {
+        if (maxConnections > 0 && connection.isEligibleForRecycling()) {
+            HttpConfiguration config = connection.getHttpConfiguration();
+            synchronized (connectionPool) {
+                List<HttpConnection> connections = connectionPool.get(config);
+                if (connections == null) {
+                    connections = new ArrayList<HttpConnection>();
+                    connectionPool.put(config, connections);
+                }
+                if (connections.size() < maxConnections) {
+                    connections.add(connection);
+                    return; // keep the connection open
+                }
+            }
+        }
+
+        // don't close streams while holding a lock!
+        connection.closeSocketAndStreams();
+    }
+}
\ No newline at end of file
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
index b078727..f66b236 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java
@@ -834,14 +834,14 @@
      * Returns connected socket to be used for this HTTP connection.
      */
     protected HttpConnection getHTTPConnection(Proxy proxy) throws IOException {
-        HttpConnection connection;
+        HttpConfiguration configuration;
         if (proxy == null || proxy.type() == Proxy.Type.DIRECT) {
-          this.proxy = null; // not using proxy
-          connection = HttpConnectionManager.getDefault().getConnection(uri, getConnectTimeout());
+            this.proxy = null; // not using proxy
+            configuration = new HttpConfiguration(uri);
         } else {
-            connection = HttpConnectionManager.getDefault().getConnection(uri, proxy, getConnectTimeout());
+            configuration = new HttpConfiguration(uri, proxy);
         }
-        return connection;
+        return HttpConnectionPool.INSTANCE.get(configuration, getConnectTimeout());
     }
 
     /**
@@ -917,8 +917,7 @@
                  */
                 connection.closeSocketAndStreams();
             } else {
-                HttpConnectionManager.getDefault().returnConnectionToPool(
-                        connection);
+                HttpConnectionPool.INSTANCE.recycle(connection);
             }
             connection = null;
         }
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java
index 2ad5b13..401d74d 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnectionImpl.java
@@ -27,13 +27,10 @@
 import java.security.cert.Certificate;
 import java.util.List;
 import java.util.Map;
-
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLSocket;
-
 import org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl;
-import org.apache.harmony.luni.internal.nls.Messages;
 
 /**
  * HttpsURLConnection implementation.
@@ -55,45 +52,40 @@
         super(url);
         httpsEngine = new HttpsEngine(url, port, proxy);
     }
-
+    
+    private void checkConnected() {
+        if (sslSocket == null) {
+            throw new IllegalStateException("Connection has not yet been established");
+        }
+    }
+    
     @Override
     public String getCipherSuite() {
-        if (sslSocket == null) {
-            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
-        }
+        checkConnected();
         return sslSocket.getSession().getCipherSuite();
     }
 
     @Override
     public Certificate[] getLocalCertificates() {
-        if (sslSocket == null) {
-            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
-        }
+        checkConnected();
         return sslSocket.getSession().getLocalCertificates();
     }
 
     @Override
-    public Certificate[] getServerCertificates()
-            throws SSLPeerUnverifiedException {
-        if (sslSocket == null) {
-            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
-        }
+    public Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {
+        checkConnected();
         return sslSocket.getSession().getPeerCertificates();
     }
 
     @Override
     public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
-        if (sslSocket == null) {
-            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
-        }
+        checkConnected();
         return sslSocket.getSession().getPeerPrincipal();
     }
 
     @Override
     public Principal getLocalPrincipal() {
-        if (sslSocket == null) {
-            throw new IllegalStateException(Messages.getString("luni.00")); //$NON-NLS-1$
-        }
+        checkConnected();
         return sslSocket.getSession().getLocalPrincipal();
     }
 
@@ -382,8 +374,8 @@
                     method = save_meth;
                 }
                 if (!connected) {
-                    throw new IOException(Messages.getString("luni.01", //$NON-NLS-1$
-                            responseMessage, responseCode));
+                    throw new IOException("Could not make SSL tunnel. " +
+                            responseMessage + " (" + responseCode + ")");
                 }
                 // if there are some remaining data in the stream - read it out
                 InputStream is = connection.getInputStream();
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java
index 493b768..eb678f8 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnectionImpl.java
@@ -150,24 +150,32 @@
                 jar = AccessController
                         .doPrivileged(new PrivilegedAction<JarFile>() {
                             public JarFile run() {
+                                FileOutputStream fos = null;
+                                JarFile result = null;
                                 try {
-                                    File tempJar = File.createTempFile(
-                                            "hyjar_", ".tmp", null);
+                                    File tempJar = File.createTempFile("hyjar_", ".tmp", null);
                                     tempJar.deleteOnExit();
-                                    FileOutputStream fos = new FileOutputStream(
-                                            tempJar);
+                                    fos = new FileOutputStream(tempJar);
                                     byte[] buf = new byte[4096];
                                     int nbytes = 0;
                                     while ((nbytes = is.read(buf)) > -1) {
                                         fos.write(buf, 0, nbytes);
                                     }
                                     fos.close();
-                                    return new JarFile(tempJar, true,
-                                            ZipFile.OPEN_READ
-                                                    | ZipFile.OPEN_DELETE);
+                                    result = new JarFile(tempJar, true,
+                                            ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
                                 } catch (IOException e) {
                                     return null;
+                                } finally {
+                                    if (fos != null) {
+                                        try {
+                                            fos.close();
+                                        } catch (IOException ex) {
+                                            result = null;
+                                        }
+                                    }
                                 }
+                                return result;
                             }
                         });
             } finally {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/nls/Messages.java b/luni/src/main/java/org/apache/harmony/luni/internal/nls/Messages.java
deleted file mode 100644
index f935a75..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/nls/Messages.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.luni.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.luni.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.luni.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties b/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
deleted file mode 100644
index 8869880..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# messages for EN locale
-luni.00=Connection has not been established yet
-luni.01=Could not make SSL Tunneling. Got response: {0} ({1})
-luni.02=Hostname <{0}> was not verified
-luni.03=The enum constant {0}.{1} is missing
-luni.04=this Map
-luni.05=Attempt to insert {0} element into collection with element type {1}
-luni.06=The string argument is null
-luni.07=The stream is corrupted
-luni.08=Invalid Unicode sequence: expected format \\uxxxx
-luni.09=Invalid Unicode sequence: illegal character
-luni.0A=Index: {0}, Size: {1}
-luni.0B=Array index out of range: {0}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfoDB.java b/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfoDB.java
index 3e7bdc3..2e6a1f8 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfoDB.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/util/ZoneInfoDB.java
@@ -32,7 +32,7 @@
  * 'zoneinfo' database as the source of time zone information.  However, to conserve
  * disk space the data for all time zones are concatenated into a single file, and a
  * second file is used to indicate the starting position of each time zone record.  A
- * third file indicates the version of the zoneinfo databse used to generate the data.
+ * third file indicates the version of the zoneinfo database used to generate the data.
  *
  * {@hide}
  */
@@ -41,7 +41,7 @@
     private static final int TZINT_LENGTH = 4;
 
     /**
-     * The directory contining the time zone database files.
+     * The directory containing the time zone database files.
      */
     private static final String ZONE_DIRECTORY_NAME =
         System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/";
@@ -73,7 +73,6 @@
         ZONE_DIRECTORY_NAME + "zoneinfo.version";
 
     private static Object lock = new Object();
-    private static TimeZone defaultZone = null;
 
     private static String version;
     private static String[] names;
@@ -81,12 +80,7 @@
     private static int[] lengths;
     private static int[] offsets;
 
-    /**
-     * This class is uninstantiable.
-     */
-    private ZoneInfoDB() {
-        // This space intentionally left blank.
-    }
+    private ZoneInfoDB() {}
 
     private static void readVersion() throws IOException {
         RandomAccessFile versionFile = new RandomAccessFile(VERSION_FILE_NAME, "r");
@@ -307,39 +301,13 @@
         return tz;
     }
 
-    public static TimeZone getDefault() {
-        TimeZone zone;
-
+    public static TimeZone getSystemDefault() {
         synchronized (lock) {
-            if (defaultZone != null) {
-                return defaultZone;
-            }
-
-            String zoneName = null;
             TimezoneGetter tzGetter = TimezoneGetter.getInstance();
-            if (tzGetter != null) {
-                zoneName = tzGetter.getId();
-            }
-            if (zoneName != null && zoneName.length() > 0) {
-                zone = TimeZone.getTimeZone(zoneName.trim());
-            } else {
-                // use localtime here so that the simulator works
-                zone = TimeZone.getTimeZone("localtime");
-            }
-
-            defaultZone = zone;
-        }
-        return zone;
-    }
-
-    // TODO - why does this ignore the 'zone' parameter?
-    public static void setDefault(@SuppressWarnings("unused") TimeZone zone) {
-        /*
-         * if (zone == null), the next call to getDefault will set it to the
-         * the system's default time zone.
-         */
-        synchronized (lock) {
-            defaultZone = null;
+            String zoneName = tzGetter != null ? tzGetter.getId() : null;
+            return zoneName != null && !zoneName.isEmpty()
+                    ? TimeZone.getTimeZone(zoneName.trim())
+                    : TimeZone.getTimeZone("localtime"); // use localtime for the simulator
         }
     }
 
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
index 4d75faf..7721cbb 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
@@ -44,14 +44,8 @@
  */
 public class PlainDatagramSocketImpl extends DatagramSocketImpl {
 
-    static final int MULTICAST_IF = 1;
-
-    static final int MULTICAST_TTL = 2;
-
     static final int TCP_NODELAY = 4;
 
-    static final int FLAG_SHUTDOWN = 8;
-
     private final static int SO_BROADCAST = 32;
 
     final static int IP_MULTICAST_ADD = 19;
@@ -75,8 +69,6 @@
 
     private byte[] ipaddress = { 0, 0, 0, 0 };
 
-    private int ttl = 1;
-
     private INetworkSystem netImpl = Platform.getNetworkSystem();
 
     private volatile boolean isNativeConnected;
@@ -160,41 +152,18 @@
         } else if (optID == SocketOptions.IP_TOS) {
             return Integer.valueOf(trafficClass);
         } else {
-            // Call the native first so there will be
-            // an exception if the socket if closed.
-            Object result = netImpl.getSocketOption(fd, optID);
-            if (optID == SocketOptions.IP_MULTICAST_IF
-                    && (netImpl.getSocketFlags() & MULTICAST_IF) != 0) {
-                try {
-                    return InetAddress.getByAddress(ipaddress);
-                } catch (UnknownHostException e) {
-                    return null;
-                }
-            }
-            return result;
+            return netImpl.getSocketOption(fd, optID);
         }
     }
 
     @Override
     public int getTimeToLive() throws IOException {
-        // Call the native first so there will be an exception if the socket if
-        // closed.
-        int result = (((Byte) getOption(IP_MULTICAST_TTL)).byteValue()) & 0xFF;
-        if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
-            return ttl;
-        }
-        return result;
+        return getTTL() & 0xff;
     }
 
     @Override
     public byte getTTL() throws IOException {
-        // Call the native first so there will be an exception if the socket if
-        // closed.
-        byte result = ((Byte) getOption(IP_MULTICAST_TTL)).byteValue();
-        if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
-            return (byte) ttl;
-        }
-        return result;
+        return ((Byte) getOption(IP_MULTICAST_TTL)).byteValue();
     }
 
     @Override
@@ -293,13 +262,11 @@
         if (optID == SocketOptions.SO_REUSEADDR) {
             optID = REUSEADDR_AND_REUSEPORT;
         }
-
         if (optID == SocketOptions.SO_TIMEOUT) {
             receiveTimeout = ((Integer) val).intValue();
         } else {
-            int flags = netImpl.getSocketFlags();
             try {
-                netImpl.setSocketOption(fd, optID | (flags << 16), val);
+                netImpl.setSocketOption(fd, optID, val);
             } catch (SocketException e) {
                 // we don't throw an exception for IP_TOS even if the platform
                 // won't let us set the requested value
@@ -307,24 +274,6 @@
                     throw e;
                 }
             }
-            if (optID == SocketOptions.IP_MULTICAST_IF && (flags & MULTICAST_IF) != 0) {
-                InetAddress inet = (InetAddress) val;
-                if (NetUtil.bytesToInt(inet.getAddress(), 0) == 0 || inet.isLoopbackAddress()) {
-                    ipaddress = ((InetAddress) val).getAddress();
-                } else {
-                    InetAddress local = null;
-                    try {
-                        local = InetAddress.getLocalHost();
-                    } catch (UnknownHostException e) {
-                        throw new SocketException("getLocalHost(): " + e.toString());
-                    }
-                    if (inet.equals(local)) {
-                        ipaddress = ((InetAddress) val).getAddress();
-                    } else {
-                        throw new SocketException(val + " != getLocalHost(): " + local);
-                    }
-                }
-            }
             /*
              * save this value as it is actually used differently for IPv4 and
              * IPv6 so we cannot get the value using the getOption. The option
@@ -341,20 +290,13 @@
     }
 
     @Override
-    public void setTimeToLive(int ttl) throws java.io.IOException {
-        // BEGIN android-changed: native code wants an int anyway
+    public void setTimeToLive(int ttl) throws IOException {
         setOption(IP_MULTICAST_TTL, Integer.valueOf(ttl));
-        // END android-changed
-        if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
-            this.ttl = ttl;
-        }
     }
 
     @Override
-    public void setTTL(byte ttl) throws java.io.IOException {
-        // BEGIN android-changed: remove duplication
+    public void setTTL(byte ttl) throws IOException {
         setTimeToLive(ttl);
-        // END android-changed
     }
 
     @Override
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
index 09b61da..e7c6c77 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
@@ -45,16 +45,6 @@
  */
 public class PlainSocketImpl extends SocketImpl {
 
-    // Const copy from socket
-
-    static final int MULTICAST_IF = 1;
-
-    static final int MULTICAST_TTL = 2;
-
-    static final int TCP_NODELAY = 4;
-
-    static final int FLAG_SHUTDOWN = 8;
-
     // For SOCKS support. A SOCKS bind() uses the last
     // host connected to in its request.
     static private InetAddress lastConnectedAddress;
@@ -65,8 +55,6 @@
 
     private static Field localportField;
 
-    private boolean tcpNoDelay = true;
-
     /**
      * used to store the trafficClass value which is simply returned as the
      * value that was set. We also need it to pass it to methods that specify an
@@ -173,10 +161,10 @@
     protected synchronized int available() throws IOException {
         // we need to check if the input has been shutdown. If so
         // we should return that there is no data to be read
-        if (shutdownInput == true) {
+        if (shutdownInput) {
             return 0;
         }
-        return netImpl.availableStream(fd);
+        return Platform.getFileSystem().ioctlAvailable(fd);
     }
 
     @Override
@@ -195,12 +183,6 @@
     protected void close() throws IOException {
         synchronized (fd) {
             if (fd.valid()) {
-                if ((netImpl.getSocketFlags() & FLAG_SHUTDOWN) != 0) {
-                    try {
-                        shutdownOutput();
-                    } catch (Exception e) {
-                    }
-                }
                 netImpl.socketClose(fd);
                 fd = new FileDescriptor();
             }
@@ -209,9 +191,7 @@
 
     @Override
     protected void connect(String aHost, int aPort) throws IOException {
-        // BEGIN android-changed: remove useless IPv6 check.
-        connect(netImpl.getHostByName(aHost), aPort);
-        // END android-changed
+        connect(InetAddress.getByName(aHost), aPort);
     }
 
     @Override
@@ -289,14 +269,7 @@
         } else if (optID == SocketOptions.IP_TOS) {
             return Integer.valueOf(trafficClass);
         } else {
-            // Call the native first so there will be
-            // an exception if the socket if closed.
-            Object result = netImpl.getSocketOption(fd, optID);
-            if (optID == SocketOptions.TCP_NODELAY
-                    && (netImpl.getSocketFlags() & TCP_NODELAY) != 0) {
-                return Boolean.valueOf(tcpNoDelay);
-            }
-            return result;
+            return netImpl.getSocketOption(fd, optID);
         }
     }
 
@@ -315,7 +288,7 @@
             // server during the bind.
             return;
         }
-        netImpl.listenStreamSocket(fd, backlog);
+        netImpl.listen(fd, backlog);
     }
 
     @Override
@@ -325,10 +298,6 @@
         } else {
             try {
                 netImpl.setSocketOption(fd, optID, val);
-                if (optID == SocketOptions.TCP_NODELAY
-                        && (netImpl.getSocketFlags() & TCP_NODELAY) != 0) {
-                    tcpNoDelay = ((Boolean) val).booleanValue();
-                }
             } catch (SocketException e) {
                 // we don't throw an exception for IP_TOS even if the platform
                 // won't let us set the requested value
@@ -377,9 +346,7 @@
         if (null == proxyName) {
             proxyName = addr.getAddress().getHostAddress();
         }
-        // BEGIN android-changed: remove useless IPv6 check.
-        return netImpl.getHostByName(proxyName);
-        // END android-changed
+        return InetAddress.getByName(proxyName);
     }
 
     /**
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
index bee1557..f04ea02 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
@@ -112,7 +112,7 @@
     // END android-deleted
     
     // BEGIN android-added
-    public int ioctlAvailable(int fileDescriptor) throws IOException;
+    public int ioctlAvailable(FileDescriptor fileDescriptor) throws IOException;
     // END android-added
     
 }
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
index bc56f68..64da5f7 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
@@ -45,9 +45,6 @@
      */
     public final int SOCKET_CONNECT_STEP_CHECK = 1;
 
-    /*
-     * socket accept
-     */
     public void accept(FileDescriptor fdServer, SocketImpl newSocket,
             FileDescriptor fdnewSocket, int timeout) throws IOException;
 
@@ -63,30 +60,17 @@
     public int write(FileDescriptor fd, byte[] data, int offset, int count)
             throws IOException;
     
-    // BEGIN android-changed
-    //     added offset parameter
     public int writeDirect(FileDescriptor fd, int address, int offset, int count)
             throws IOException;
-    // END android-changed
 
-    // BEGIN android-removed
-    // public int writev(FileDescriptor fd, Object[] buffers, int[] offsets,
-    //         int[] counts, int length) throws IOException;
-    // END android-removed
+    public void setNonBlocking(FileDescriptor aFD, boolean block) throws IOException;
 
-    public void setNonBlocking(FileDescriptor aFD, boolean block)
-            throws IOException;
-
-    // BEGIN android-changed (we always throw on error, the value returned was always 0)
     public void connect(FileDescriptor aFD, int trafficClass,
             InetAddress inetAddress, int port) throws IOException;
-    // END android-changed
 
-    // BEGIN android-changed
     public int connectWithTimeout(FileDescriptor aFD, int timeout,
             int trafficClass, InetAddress hostname, int port, int step,
             byte[] context) throws IOException;
-    // END android-changed
 
     public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
             int length, int port, boolean bindToDevice, int trafficClass,
@@ -129,11 +113,6 @@
     public void connectDatagram(FileDescriptor aFD, int port, int trafficClass,
             InetAddress inetAddress) throws SocketException;
 
-    // BEGIN android-removed
-    // public int receiveStream(FileDescriptor aFD, byte[] data, int offset,
-    //         int count, int timeout) throws IOException;
-    // END android-removed
-
     public void shutdownInput(FileDescriptor descriptor) throws IOException;
 
     public void shutdownOutput(FileDescriptor descriptor) throws IOException;
@@ -142,22 +121,13 @@
 
     public void sendUrgentData(FileDescriptor fd, byte value);
 
-    public int availableStream(FileDescriptor aFD) throws SocketException;
-
-    // BEGIN android-removed
-    // public void acceptStreamSocket(FileDescriptor fdServer,
-    //         SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
-    //         throws IOException;
-    // END android-removed
-
     public void createServerStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
             throws SocketException;
 
     public void createStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
             throws SocketException;
     
-    public void listenStreamSocket(FileDescriptor aFD, int backlog)
-            throws SocketException;
+    public void listen(FileDescriptor aFD, int backlog) throws SocketException;
 
     public void connectStreamWithTimeoutSocket(FileDescriptor aFD, int aport,
             int timeout, int trafficClass, InetAddress inetAddress)
@@ -166,9 +136,7 @@
     public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
             int length, int port, InetAddress inetAddress) throws IOException;
 
-    // BEGIN android-changed: remove useless IPv6 check.
     public InetAddress getSocketLocalAddress(FileDescriptor aFD);
-    // END android-changed
 
     /**
      * Select the given file descriptors for read and write operations.
@@ -204,7 +172,6 @@
             int numReadable, int numWritable, long timeout, int[] flags)
             throws SocketException;
 
-    // BEGIN android-changed: remove useless IPv6 check.
     /*
      * Query the IP stack for the local port to which this socket is bound.
      * 
@@ -212,7 +179,6 @@
      * @return int the local port to which the socket is bound
      */
     public int getSocketLocalPort(FileDescriptor aFD);
-    // END android-changed
 
     /*
      * Query the IP stack for the nominated socket option.
@@ -236,38 +202,16 @@
     public void setSocketOption(FileDescriptor aFD, int opt, Object optVal)
             throws SocketException;
 
-    public int getSocketFlags();
-
-    /*
-     * Close the socket in the IP stack.
-     * 
-     * @param aFD the socket descriptor
-     */
+    // TODO: change OSFileSystem.close to take a FileDescriptor, and lose this duplicate.
     public void socketClose(FileDescriptor aFD) throws IOException;
 
-    public InetAddress getHostByAddr(byte[] addr) throws UnknownHostException;
-
-    // BEGIN android-changed: remove useless IPv6 check.
-    public InetAddress getHostByName(String addr) throws UnknownHostException;
-    // END android-changed
-
+    // TODO: change the single caller so that recvConnectedDatagram
+    // can mutate the InetAddress as a side-effect.
     public void setInetAddress(InetAddress sender, byte[] address);
 
-    // BEGIN android-added
-    public String byteArrayToIpString(byte[] address)
-            throws UnknownHostException;
+    public String byteArrayToIpString(byte[] address) throws UnknownHostException;
 
-    public byte[] ipStringToByteArray(String address)
-            throws UnknownHostException;
-    // END android-added
-
-    // BEGIN android-removed
-    // public boolean isReachableByICMP(InetAddress dest,InetAddress source,int ttl,int timeout);
-    // END android-removed
+    public byte[] ipStringToByteArray(String address) throws UnknownHostException;
 
     public Channel inheritedChannel();
-
-    // BEGIN android-removed: we do this statically, when we start the VM.
-    // public void oneTimeInitialization(boolean jcl_supports_ipv6);
-    // END android-removed
 }
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
index 13ca3ab..1f8eb4a 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
@@ -182,6 +182,6 @@
     // END android-deleted
 
     // BEGIN android-added
-    public native int ioctlAvailable(int fileDescriptor) throws IOException;
+    public native int ioctlAvailable(FileDescriptor fileDescriptor) throws IOException;
     // END android-added
 }
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
index 7c5cf66..4f2d47d 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
@@ -15,13 +15,6 @@
  *  limitations under the License.
  */
 
-// BEGIN android-note
-// Address length was changed from long to int for performance reasons.
-// Harmony implements INetworkSystem's methods with native methods; Android
-// implements them with Java that call through to native wrappers.
-// TODO: change the native code to eliminate the wrappers
-// END android-note
-
 package org.apache.harmony.luni.platform;
 
 import java.io.FileDescriptor;
@@ -32,403 +25,96 @@
 import java.net.SocketImpl;
 import java.net.UnknownHostException;
 import java.nio.channels.Channel;
-// BEGIN android-removed
-// import java.nio.channels.SelectableChannel;
-// END android-removed
 
 /**
  * This wraps native code that implements the INetworkSystem interface.
+ * Address length was changed from long to int for performance reasons.
  */
 final class OSNetworkSystem implements INetworkSystem {
+    private static final OSNetworkSystem singleton = new OSNetworkSystem();
 
-    private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
-    private static final int ERRORCODE_SOCKET_INTERRUPTED = -208;
-
-    private static final int INETADDR_REACHABLE = 0;
-
-    // private static boolean isNetworkInited = false; android-removed
-
-    private static OSNetworkSystem singleton = new OSNetworkSystem();
-
-    /**
-     * Answers the unique instance of the OSNetworkSystem.
-     *
-     * @return the network system interface instance
-     */
     public static OSNetworkSystem getOSNetworkSystem() {
         return singleton;
     }
 
-    // Can not be instantiated.
     private OSNetworkSystem() {
-        super();
     }
 
-    public void accept(FileDescriptor fdServer, SocketImpl newSocket,
-            FileDescriptor fdnewSocket, int timeout) throws IOException {
-        acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
-    }
+    public native void accept(FileDescriptor fdServer, SocketImpl newSocket,
+            FileDescriptor fdnewSocket, int timeout) throws IOException;
 
-    static native void acceptSocketImpl(FileDescriptor fdServer,
-            SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
-            throws IOException;
+    public native void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException;
 
-    // BEGIN android-removed
-    // public void acceptStreamSocket(FileDescriptor fdServer,
-    //         SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
-    //         throws IOException {
-    //     acceptStreamSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
-    // }
-
-    // static native void acceptStreamSocketImpl(FileDescriptor fdServer,
-    //         SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
-    //         throws IOException;
-    // END android-removed
-
-    public int availableStream(FileDescriptor fd) throws SocketException {
-        return availableStreamImpl(fd);
-    }
-
-    static native int availableStreamImpl(FileDescriptor aFD) throws SocketException;
-
-    /**
-     * Associates a local address with a socket.
-     *
-     * @param fd
-     *            the socket descriptor
-     * @param port
-     *            the port number
-     * @param inetAddress
-     *            address to bind
-     * @throws SocketException
-     *             thrown if bind operation fails
-     */
-    public void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
-        socketBindImpl(fd, port, inetAddress);
-    }
-
-    static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException;
-
-    // BEGIN android-changed (removed unused return value and useless native method)
     public void connect(FileDescriptor fd, int trafficClass,
             InetAddress inetAddress, int port) throws IOException{
-        connectStreamWithTimeoutSocketImpl(fd, port, 0, trafficClass, inetAddress);
-    }
-    // END android-changed
-
-    public void connectDatagram(FileDescriptor fd, int port,
-            int trafficClass, InetAddress inetAddress) throws SocketException {
-        connectDatagramImpl2(fd, port, trafficClass, inetAddress);
+        connectStreamWithTimeoutSocket(fd, port, 0, trafficClass, inetAddress);
     }
 
-    static native void connectDatagramImpl2(FileDescriptor aFD, int port,
+    public native void connectDatagram(FileDescriptor fd, int port,
             int trafficClass, InetAddress inetAddress) throws SocketException;
 
-    public void connectStreamWithTimeoutSocket(FileDescriptor aFD,
-            int aport, int timeout, int trafficClass, InetAddress inetAddress)
-            throws IOException {
-        connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
-                inetAddress);
-    }
-
-    static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
-            int aport, int timeout, int trafficClass, InetAddress inetAddress)
+    public native void connectStreamWithTimeoutSocket(FileDescriptor fd,
+            int port, int timeout, int trafficClass, InetAddress inetAddress)
             throws IOException;
 
-    // BEGIN android-changed
-    // changed context from Long to byte[]
-    public int connectWithTimeout(FileDescriptor fd, int timeout,
+    public native int connectWithTimeout(FileDescriptor fd, int timeout,
             int trafficClass, InetAddress inetAddress, int port, int step,
-            byte[] context) throws IOException {
-        return connectWithTimeoutSocketImpl(fd, timeout, trafficClass,
-                inetAddress, port, step, context);
-    }
+            byte[] context) throws IOException;
 
-    static native int connectWithTimeoutSocketImpl(FileDescriptor aFD,
-            int timeout, int trafficClass, InetAddress hostname, int port, int step,
-            byte[] context);
-    // END android-changed
-
-    public void createDatagramSocket(FileDescriptor fd,
-            boolean preferIPv4Stack) throws SocketException {
-        createDatagramSocketImpl(fd, preferIPv4Stack);
-    }
-
-    /*
-    * Allocate a datagram socket in the IP stack. The socket is associated with
-    * the <code>aFD</code>.
-    *
-    * @param aFD the FileDescriptor to associate with the socket @param
-    * preferIPv4Stack IP stack preference if underlying platform is V4/V6
-    * @exception SocketException upon an allocation error
-    */
-    static native void createDatagramSocketImpl(FileDescriptor aFD,
-            boolean preferIPv4Stack) throws SocketException;
-
-    public void createServerStreamSocket(FileDescriptor fd,
-            boolean preferIPv4Stack) throws SocketException {
-        createServerStreamSocketImpl(fd, preferIPv4Stack);
-    }
-
-    /*
-     * Answer the result of attempting to create a server stream socket in the
-     * IP stack. Any special options required for server sockets will be set by
-     * this method.
-     *
-     * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
-     * @exception SocketException if an error occurs while creating the socket
-     */
-    static native void createServerStreamSocketImpl(FileDescriptor aFD,
-            boolean preferIPv4Stack) throws SocketException;
-
-    public void createStreamSocket(FileDescriptor fd,
-            boolean preferIPv4Stack) throws SocketException {
-        createStreamSocketImpl(fd, preferIPv4Stack);
-    }
-
-    static native void createStreamSocketImpl(FileDescriptor aFD,
-            boolean preferIPv4Stack) throws SocketException;
-
-    /**
-     * Disconnect the socket to a port and address
-     *a
-     * @param fd
-     *            the FileDescriptor associated with the socket
-     *
-     * @throws SocketException
-     *             if the disconnect fails
-     */
-    public void disconnectDatagram(FileDescriptor fd)
-            throws SocketException {
-        disconnectDatagramImpl(fd);
-    }
-
-    static native void disconnectDatagramImpl(FileDescriptor aFD)
+    // TODO: preferIPv4Stack is ignored.
+    public native void createDatagramSocket(FileDescriptor fd, boolean preferIPv4Stack)
             throws SocketException;
 
-    public InetAddress getHostByAddr(byte[] ipAddress)
-            throws UnknownHostException {
-        // BEGIN android-changed
-        // Wallpaper fix for http://b/1851257. This  is a layering violation,
-        // but at least the method has the right return type.
-        // TODO: Fix the socket code to remove this method altogether.
-        return InetAddress.getByAddress(ipAddress);
-        // END android-changed
-    }
-    // BEGIN android-removed
-    // static native InetAddress getHostByAddrImpl(byte[] addr)
-    //         throws UnknownHostException;
-    // END android-removed
-
-    // BEGIN android-changed: remove useless IPv6 check.
-    public InetAddress getHostByName(String hostName) throws UnknownHostException {
-        return InetAddress.getByName(hostName);
-    }
-    // END android-changed
-
-    // BEGIN android-removed
-    // static native InetAddress getHostByNameImpl(String addr) throws UnknownHostException;
-    // END android-removed
-
-    public int getSocketFlags() {
-        return getSocketFlagsImpl();
-    }
-
-    public native String byteArrayToIpString(byte[] address)
-            throws UnknownHostException;
-
-    public native byte[] ipStringToByteArray(String address)
-            throws UnknownHostException;
-
-    static native int getSocketFlagsImpl();
-
-    public InetAddress getSocketLocalAddress(FileDescriptor fd) {
-        return getSocketLocalAddressImpl(fd);
-    }
-    static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD);
-
-    public int getSocketLocalPort(FileDescriptor aFD) {
-        return getSocketLocalPortImpl(aFD);
-    }
-    static native int getSocketLocalPortImpl(FileDescriptor aFD);
-
-    /**
-     * Query the IP stack for the nominated socket option.
-     *
-     * @param fd
-     *            the socket descriptor
-     * @param opt
-     *            the socket option type
-     * @return the nominated socket option value
-     * @throws SocketException
-     *             if the option is invalid
-     */
-    public Object getSocketOption(FileDescriptor fd, int opt)
-            throws SocketException {
-        return getSocketOptionImpl(fd, opt);
-    }
-
-    static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
+    // TODO: preferIPv4Stack is ignored.
+    public native void createServerStreamSocket(FileDescriptor fd, boolean preferIPv4Stack)
             throws SocketException;
 
-    public native Channel inheritedChannel();
-
-    // BEGIN android-removed
-    // public boolean isReachableByICMP(final InetAddress dest,
-    //         InetAddress source, final int ttl, final int timeout) {
-    //     return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
-    //     timeout);
-    // }
-
-    // native int isReachableByICMPImpl(InetAddress addr,
-    //         InetAddress local, int ttl, int timeout);
-    // END android-removed
-
-    public void listenStreamSocket(FileDescriptor aFD, int backlog)
-            throws SocketException {
-        listenStreamSocketImpl(aFD, backlog);
-    }
-
-    static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
+    // TODO: preferIPv4Stack is ignored.
+    public native void createStreamSocket(FileDescriptor fd, boolean preferIPv4Stack)
             throws SocketException;
 
-    // BEGIN android-removed: we do this statically, when we start the VM.
-    // public void oneTimeInitialization(boolean jcl_supports_ipv6);
-    // native void oneTimeInitializationImpl(boolean jcl_supports_ipv6);
-    // END android-removed
+    public native void disconnectDatagram(FileDescriptor fd) throws SocketException;
 
-    /**
-     * Peek on the socket, update <code>sender</code> address and answer the
-     * sender port.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param sender
-     *            an InetAddress, to be updated with the sender's address
-     * @param receiveTimeout
-     *            the maximum length of time the socket should block, reading
-     * @return the sender port
-     *
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int peekDatagram(FileDescriptor fd, InetAddress sender,
-            int receiveTimeout) throws IOException {
-        return peekDatagramImpl(fd, sender, receiveTimeout);
+    public native String byteArrayToIpString(byte[] address) throws UnknownHostException;
+
+    public native byte[] ipStringToByteArray(String address) throws UnknownHostException;
+
+    public native InetAddress getSocketLocalAddress(FileDescriptor fd);
+
+    public native int getSocketLocalPort(FileDescriptor fd);
+
+    public native Object getSocketOption(FileDescriptor fd, int opt) throws SocketException;
+
+    public Channel inheritedChannel() {
+        // Android never has stdin/stdout connected to a socket.
+        return null;
     }
 
-    static native int peekDatagramImpl(FileDescriptor aFD,
-            InetAddress sender, int receiveTimeout) throws IOException;
+    public native void listen(FileDescriptor fd, int backlog) throws SocketException;
 
-    /**
-     * Read available bytes from the given file descriptor into a byte array.
-     *
-     * The read has an optional timeout parameter, which if non-zero is the
-     * length of time that the read will wait on a select call to see if any
-     * bytes are available for reading. If the timeout expires the method
-     * returns zero to indicate no bytes were read.
-     *
-     * @param fd
-     *            the socket file descriptor to read
-     * @param data
-     *            the byte array in which to store the results
-     * @param offset
-     *            the offset into the byte array in which to start reading the
-     *            results
-     * @param count
-     *            the maximum number of bytes to read
-     * @param timeout
-     *            the length of time to wait for the bytes, in milliseconds; or
-     *            zero to indicate no timeout applied. When there is no timeout
-     *            applied the read may block based upon socket options.
-     * @return number of bytes read, or zero if there were no bytes available
-     *         before the timeout occurred, or -1 to indicate the socket is
-     *         closed
-     * @throws IOException
-     *             if an underlying socket exception occurred
-     */
+    public native int peekDatagram(FileDescriptor fd, InetAddress sender, int receiveTimeout)
+            throws IOException;
+
     public int read(FileDescriptor fd, byte[] data, int offset, int count,
             int timeout) throws IOException {
-        // BEGIN android-added safety!
         if (offset < 0 || count < 0 || offset > data.length - count) {
             throw new IllegalArgumentException("data.length=" + data.length + " offset=" + offset +
                     " count=" + count);
         }
-        // END android-added
         return readSocketImpl(fd, data, offset, count, timeout);
     }
 
     static native int readSocketImpl(FileDescriptor aFD, byte[] data,
             int offset, int count, int timeout) throws IOException;
 
-    /**
-     * Read available bytes from the given file descriptor into OS memory at a
-     * given address.
-     *
-     * @param fd
-     *            the socket file descriptor to read
-     * @param address
-     *            the address of the memory in which to store the results
-     * @param count
-     *            the maximum number of bytes to read
-     * @param timeout
-     *            the length of time to wait for the bytes, in milliseconds
-     * @return number of bytes read, or zero if there were no bytes available
-     *         before the timeout occurred, or -1 to indicate the socket is
-     *         closed
-     * @throws IOException
-     *             if an underlying socket exception occurred
-     */
-    public int readDirect(FileDescriptor fd, int address, int count,
-            int timeout) throws IOException {
-        return readSocketDirectImpl(fd, address, count, timeout);
-    }
+    public native int readDirect(FileDescriptor fd, int address, int count, int timeout)
+            throws IOException;
 
-    static native int readSocketDirectImpl(FileDescriptor aFD, int address, int count,
-            int timeout) throws IOException;
-
-    /**
-     * Receive data on the socket into the specified buffer. The packet fields
-     * <code>data</code> & <code>length</code> are passed in addition to
-     * <code>packet</code> to eliminate the JNI field access calls.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param packet
-     *            the DatagramPacket to receive into
-     * @param data
-     *            the data buffer of the packet
-     * @param offset
-     *            the offset in the data buffer
-     * @param length
-     *            the length of the data buffer in the packet
-     * @param receiveTimeout
-     *            the maximum length of time the socket should block, reading
-     * @param peek
-     *            indicates to peek at the data
-     * @return number of data received
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
+    public native int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
             byte[] data, int offset, int length, int receiveTimeout,
-            boolean peek) throws IOException {
-        return receiveDatagramImpl(fd, packet, data, offset, length,
-                receiveTimeout, peek);
-    }
+            boolean peek) throws IOException;
 
-    static native int receiveDatagramImpl(FileDescriptor aFD,
-            DatagramPacket packet, byte[] data, int offset, int length,
-            int receiveTimeout, boolean peek) throws IOException;
-
-    public int receiveDatagramDirect(FileDescriptor fd,
-            DatagramPacket packet, int address, int offset, int length,
-            int receiveTimeout, boolean peek) throws IOException {
-        return receiveDatagramDirectImpl(fd, packet, address, offset, length,
-                receiveTimeout, peek);
-    }
-
-    static native int receiveDatagramDirectImpl(FileDescriptor aFD,
+    public native int receiveDatagramDirect(FileDescriptor fd,
             DatagramPacket packet, int address, int offset, int length,
             int receiveTimeout, boolean peek) throws IOException;
 
@@ -455,28 +141,14 @@
      * @throws IOException
      *             upon an read error or timeout
      */
-    public int recvConnectedDatagram(FileDescriptor fd,
-            DatagramPacket packet, byte[] data, int offset, int length,
-            int receiveTimeout, boolean peek) throws IOException {
-        return recvConnectedDatagramImpl(fd, packet, data, offset, length,
-                receiveTimeout, peek);
-    }
-
-    static native int recvConnectedDatagramImpl(FileDescriptor aFD,
+    public native int recvConnectedDatagram(FileDescriptor fd,
             DatagramPacket packet, byte[] data, int offset, int length,
             int receiveTimeout, boolean peek) throws IOException;
 
-    public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
-            int offset, int length, int receiveTimeout, boolean peek)
-            throws IOException {
-        return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
-    }
-
-    static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
+    public native int recvConnectedDatagramDirect(FileDescriptor fd,
             DatagramPacket packet, int address, int offset, int length,
             int receiveTimeout, boolean peek) throws IOException;
 
-
     public boolean select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
             int numReadable, int numWritable, long timeout, int[] flags)
             throws SocketException {
@@ -489,287 +161,55 @@
             return true;
         }
 
-        assert validateFDs(readFDs, writeFDs, numReadable, numWritable) : "Invalid file descriptor arrays"; //$NON-NLS-1$
-
-        // BEGIN android-changed: handle errors in native code
         return selectImpl(readFDs, writeFDs, numReadable, numWritable, flags, timeout);
-        // END android-changed
     }
 
-    // BEGIN android-changed: return type (we throw in native code, with descriptive errors)
     static native boolean selectImpl(FileDescriptor[] readfd,
             FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
             long timeout);
-    // END android-changed
 
-    /**
-     * Send the <code>data</code> to the address and port to which the was
-     * connected and <code>port</code>.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param data
-     *            the data buffer of the packet
-     * @param offset
-     *            the offset in the data buffer
-     * @param length
-     *            the length of the data buffer in the packet
-     * @param bindToDevice
-     *            not used, current kept in case needed as was the case for
-     *            sendDatagramImpl
-     * @return number of data send
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
-            int offset, int length, boolean bindToDevice) throws IOException {
-        return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
-    }
+    // TODO: bindToDevice is unused.
+    public native int sendConnectedDatagram(FileDescriptor fd, byte[] data,
+            int offset, int length, boolean bindToDevice) throws IOException;
 
-    static native int sendConnectedDatagramImpl(FileDescriptor fd,
-            byte[] data, int offset, int length, boolean bindToDevice)
-            throws IOException;
-
-    public int sendConnectedDatagramDirect(FileDescriptor fd,
-            int address, int offset, int length, boolean bindToDevice)
-            throws IOException {
-        return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
-    }
-    static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
+    // TODO: bindToDevice is unused.
+    public native int sendConnectedDatagramDirect(FileDescriptor fd,
             int address, int offset, int length, boolean bindToDevice)
             throws IOException;
 
-    /**
-     * Send the <code>data</code> to the nominated target <code>address</code>
-     * and <code>port</code>. These values are derived from the DatagramPacket
-     * to reduce the field calls within JNI.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param data
-     *            the data buffer of the packet
-     * @param offset
-     *            the offset in the data buffer
-     * @param length
-     *            the length of the data buffer in the packet
-     * @param port
-     *            the target host port
-     * @param bindToDevice
-     *            if bind to device
-     * @param trafficClass
-     *            the traffic class to be used when the datagram is sent
-     * @param inetAddress
-     *            address to connect to.
-     * @return number of data send
-     *
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
-            int length, int port, boolean bindToDevice, int trafficClass,
-            InetAddress inetAddress) throws IOException {
-        return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
-                trafficClass, inetAddress);
-    }
-
-    static native int sendDatagramImpl(FileDescriptor fd, byte[] data, int offset,
+    // TODO: bindToDevice is unused.
+    public native int sendDatagram(FileDescriptor fd, byte[] data, int offset,
             int length, int port, boolean bindToDevice, int trafficClass,
             InetAddress inetAddress) throws IOException;
 
-    public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
-            int length, int port, InetAddress inetAddress) throws IOException {
-        return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
-    }
+    public native int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
+            int length, int port, InetAddress inetAddress) throws IOException;
 
-    static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
-            int offset, int length, int port, InetAddress inetAddress) throws IOException;
-
-
-    public int sendDatagramDirect(FileDescriptor fd, int address,
-            int offset, int length, int port, boolean bindToDevice,
-            int trafficClass, InetAddress inetAddress) throws IOException {
-        return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
-                trafficClass, inetAddress);
-    }
-
-    static native int sendDatagramDirectImpl(FileDescriptor fd, int address,
+    // TODO: bindToDevice is unused.
+    public native int sendDatagramDirect(FileDescriptor fd, int address,
             int offset, int length, int port, boolean bindToDevice,
             int trafficClass, InetAddress inetAddress) throws IOException;
 
-    public void sendUrgentData(FileDescriptor fd, byte value) {
-        sendUrgentDataImpl(fd, value);
-    }
+    public native void sendUrgentData(FileDescriptor fd, byte value);
 
-    static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
+    public native void setInetAddress(InetAddress sender, byte[] address);
 
-    public void setInetAddress(InetAddress sender, byte[] address) {
-        setInetAddressImpl(sender, address);
-    }
+    public native void setNonBlocking(FileDescriptor fd, boolean block) throws IOException;
 
-    native void setInetAddressImpl(InetAddress sender, byte[] address);
+    public native void setSocketOption(FileDescriptor fd, int opt, Object optVal)
+            throws SocketException;
 
-    public void setNonBlocking(FileDescriptor fd, boolean block)
-            throws IOException {
-        setNonBlockingImpl(fd, block);
-    }
+    public native void shutdownInput(FileDescriptor fd) throws IOException;
 
-    static native void setNonBlockingImpl(FileDescriptor aFD, boolean block);
+    public native void shutdownOutput(FileDescriptor fd) throws IOException;
 
-    /**
-     * Set the nominated socket option in the IP stack.
-     *
-     * @param aFD
-     *            the socket descriptor @param opt the option selector @param
-     *            optVal the nominated option value
-     *
-     * @throws SocketException
-     *             if the option is invalid or cannot be set
-     */
-    public void setSocketOption(FileDescriptor aFD, int opt,
-            Object optVal) throws SocketException {
-        setSocketOptionImpl(aFD, opt, optVal);
-    }
+    public native void socketClose(FileDescriptor fd) throws IOException;
 
-    static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
-            Object optVal) throws SocketException;
+    public native boolean supportsUrgentData(FileDescriptor fd);
 
-    public void shutdownInput(FileDescriptor descriptor) throws IOException {
-        shutdownInputImpl(descriptor);
-    }
-
-    private native void shutdownInputImpl(FileDescriptor descriptor)
+    public native int write(FileDescriptor fd, byte[] data, int offset, int count)
             throws IOException;
 
-    public void shutdownOutput(FileDescriptor fd) throws IOException {
-        shutdownOutputImpl(fd);
-    }
-
-    private native void shutdownOutputImpl(FileDescriptor descriptor)
+    public native int writeDirect(FileDescriptor fd, int address, int offset, int count)
             throws IOException;
-    /**
-     * Close the socket in the IP stack.
-     *
-     * @param fd
-     *            the socket descriptor
-     */
-    public void socketClose(FileDescriptor fd) throws IOException {
-        socketCloseImpl(fd);
-    }
-
-    static native void socketCloseImpl(FileDescriptor fD);
-
-    public boolean supportsUrgentData(FileDescriptor fd) {
-        return supportsUrgentDataImpl(fd);
-    }
-
-    static native boolean supportsUrgentDataImpl(FileDescriptor fd);
-
-    /*
-    * Used to check if the file descriptor arrays are valid before passing them
-    * into the select native call.
-    */
-    private boolean validateFDs(FileDescriptor[] readFDs,
-            FileDescriptor[] writeFDs) {
-        for (FileDescriptor fd : readFDs) {
-            // Also checks fd not null
-            if (!fd.valid()) {
-                return false;
-            }
-        }
-        for (FileDescriptor fd : writeFDs) {
-            if (!fd.valid()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean validateFDs(FileDescriptor[] readFDs,
-            FileDescriptor[] writeFDs, int countRead, int countWrite) {
-        for (int i = 0; i < countRead; ++i) {
-            // Also checks fd not null
-            if (!readFDs[i].valid()) {
-                return false;
-            }
-        }
-        for (int i = 0; i < countWrite; ++i) {
-            if (!writeFDs[i].valid()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Write bytes from a byte array to a socket.
-     *
-     * @param fd
-     *            the socket on which to write the bytes
-     * @param data
-     *            the array containing the bytes to be written
-     * @param offset
-     *            the offset in the byte array from which to take the bytes
-     * @param count
-     *            the maximum number of bytes to be written. Callers are trusted
-     *            not to send values of length+count that are larger than
-     *            data.length
-     * @return the actual number of bytes written, which will be between zero
-     *         and count
-     * @throws IOException
-     *             if there is an underlying socket problem
-     */
-    public int write(FileDescriptor fd, byte[] data, int offset, int count)
-            throws IOException {
-        return writeSocketImpl(fd, data, offset, count);
-    }
-
-    static native int writeSocketImpl(FileDescriptor fd, byte[] data, int offset,
-            int count) throws IOException;
-
-
-    /**
-     * Write bytes from the given address to a socket.
-     *
-     * @param fd
-     *            the socket on which to write the bytes
-     * @param address
-     *            the start address of the bytes to be written
-     * @param count
-     *            the maximum number of bytes to be written
-     * @return the actual number of bytes written, which will be between zero
-     *         and count
-     * @throws IOException
-     *             if there is an underlying socket problem
-     */
-    public int writeDirect(FileDescriptor fd, int address, int offset, int count)
-            throws IOException {
-        return writeSocketDirectImpl(fd, address, offset, count);
-    }
-
-    static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count)
-            throws IOException;
-
-    // BEGIN android-removed
-    // /**
-    //  * Write given buffers to a socket. The given buffers is a Object array, the
-    //  * element of array must be direct buffer or a byte array to be written.
-    //  *
-    //  * @param fd
-    //  *            the socket on which to write the bytes
-    //  * @param buffers
-    //  *            the element of array must be direct buffer or a byte array to
-    //  *            be written
-    //  * @param offsets
-    //  *            the index of the first byte to be write
-    //  * @param counts
-    //  *            the maximum number of bytes to be written
-    //  * @param length
-    //  *            the size of buffer array
-    //  * @return the actual number of bytes written
-    //  * @throws IOException
-    //  *             if there is an underlying socket problem
-    //  */
-    // public native int writev(FileDescriptor fd, Object[] buffers,
-    //         int[] offsets, int[] counts, int length) throws IOException;
-    // END android-removed
 }
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
index b6cbcef..2c7d605 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
+++ b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
@@ -15,38 +15,13 @@
 
 # External Messages for EN locale
 K0006=Negative index specified
-K0007=attempt to write after finish
-K0008=Cannot read version
-K0009=Missing version string\: {0}
-K000a=Entry is not named
-K000b=Invalid attribute {0}
-K000c=cannot resolve subclasses
-K000d=Unknown attribute
-K000e=Cannot add attributes to empty string
-K0014=Unquoted {0} in suffix\: {1}
-K0015=Unexpected {0} in fraction\: {1}
-K0016=Unexpected {0} in {1}
-K0017=Missing pattern before {0} in {1}
-K0018=Missing exponent format {0}
-K0019=Unterminated quote {0}
-K001a=Missing grouping format {0}
-K001b=Invalid exponent format {0}
-K001c=Invalid pattern char {0} in {1}
-K001d=Invalid argument number
-K001e=Missing element format
-K001f=Unknown element format
-K0020=Unknown format
-K002b=Unknown pattern character - '{0}'
-K002c=Access denied {0}
 K002e=Offset out of bounds \: {0}
 K002f=Arguments out of bounds
 K0032=Address null or destination port out of range
-K0033=Unknown socket type
 K0034=Packet address mismatch with connected address
 K0035=Zero or negative buffer size
 K0036=Invalid negative timeout
 K0037=Connection already established
-K0038=No host name provided
 K0039=Attempted to join a non-multicast group
 K003a=Attempted to leave a non-multicast group
 K003c=TimeToLive out of bounds
@@ -54,7 +29,6 @@
 K003e=SOCKS connection failed\: {0}
 K003f=Unable to connect to SOCKS server\: {0}
 K0040=Invalid SOCKS client.
-K0041=Socket implementation does not support SOCKS.
 K0042=Socket implementation factory already set
 K0044=The factory has already been set
 K0045=Attempted to set a negative SoLinger
@@ -67,19 +41,11 @@
 K004c=Package is sealed
 K004d=Does not support writing to the input stream
 K004e=Duplicate Factory
-K004f=rounding necessary
-K0050=wrong rounding mode
 K0051=scale value < than zero
 K0052=Array index out of range\: {0}
-K0053=Package {0} already defined.
 K0055=String index out of range\: {0}
-K0056=Already destroyed
-K0057=Has threads
 K0058=size must be > 0
 K0059=Stream is closed
-# // BEGIN android-deleted
-# // K005a=Mark has been invalidated.
-# // END android-deleted
 K005b=BufferedReader is closed
 K005c=Invalid Mark.
 K005d=Writer is closed.
@@ -90,9 +56,7 @@
 K0063=Third byte at {0} does not match UTF8 Specification
 K0064=Second or third byte at {0} does not match UTF8 Specification
 K0065=Input at {0} does not match UTF8 Specification
-K0066=Entry already exists: {0}
 K0068=String is too long
-K0069=File cannot compare to non File
 K006a=time must be positive
 K006b=Prefix must be at least 3 characters
 K006c=FileDescriptor is null
@@ -102,11 +66,9 @@
 K0070=InputStreamReader is closed.
 K0071=Error fetching SUID\: {0}
 K0072={0} computing SHA-1 / SUID
-K0073=OutputStreamWriter is closed.
 K0074=Not connected
 K0075=InputStream is closed
 K0076=Pipe broken
-K0077=Crc mismatch
 K0078=Pipe is closed
 K0079=Already connected
 K007a=Pipe already connected
@@ -117,13 +79,6 @@
 K0081=Mode must be one of "r" or "rw"
 K0083=StringReader is closed.
 K0084=can only instantiate one BootstrapClassLoader
-K0086=Referenced reflect object is no longer valid
-K0087=Referenced reflect object is no longer valid\: {0}
-K0088=Incorrect end of BER tag
-K0089=Unknown type\: {0}
-K008a=Read {0} bytes trying to read {1} bytes from {2}
-K008b=Position\: {0}
-K008c=Invalid Base64 char\:{0}
 K008d=This protocol does not support input
 K008e=Does not support output
 K008f=This method does not support writing\: {0}
@@ -139,20 +94,13 @@
 K0099=Unable to configure data port
 K009a=Unable to store file
 K009b=Unable to set transfer type
-K00a2=Parsing policy file\: {0}, expected quoted {1}, found unquoted\: {2}
-K00a3=Parsing policy file\: {0}, found unexpected\: {1}
 K00a4=Content-Length underflow
 K00a5=Invalid parameter - {0}
-K00a8=Parsing policy file\: {0}, invalid codesource URL\: {1}
-K00ab=No active entry
-K00ae=Size mismatch
 K00af=Invalid proxy port\: {0}
 K00b0=Proxy port out of range
 K00b1=Invalid port number
 K00b2=Content-Length exceeded
 K00b3=Unknown protocol\: {0}
-K00b6=No entries
-K00b7=File is closed
 K00c1=Illegal character
 K00cd=Failure to connect to SOCKS server.
 K00ce=Unable to connect to identd to verify user.
@@ -168,65 +116,27 @@
 K00d9=Callback object cannot be null
 K00da=Incompatible class (SUID)\: {0} but expected {1}
 K00dc=IllegalAccessException
-K00e3=Could not create specified security manager\: {0}
-K00e4=Key usage is critical and cannot be used for digital signature purposes.
 K00e5=month\: {0}
 K00e6=day of month\: {0}
 K00e7=day of week\: {0}
 K00e8=time\: {0}
 K00e9=DST offset\: {0}
 K00ea=era\: {0}
-K00eb={0} failed verification of {1}
-K00ec={0} has invalid digest for {1} in {2}
 K00ed={0} is not an interface
 K00ee={0} is not visible from class loader
 K00ef={0} appears more than once
 K00f0=non-public interfaces must be in the same package
 K00f1=not a proxy instance
-K00f2=the methods named {0} must have the same return type
 K00f3=Timer was cancelled
 K00f5=Illegal delay to start the TimerTask
 K00f6=TimerTask is scheduled already
 K00f7=TimerTask is cancelled
 K00f8=day of week in month\: {0}
-K00f9=min or max digit count too large
-K00fa=min digits greater than max digits
-K00fb=min or max digits negative
 K00fc=Jar entry not specified
-K00fd=Invalid keystore
-K00fe=Incorrect password
-K0185=The alias already exists for a key entry.
-K018f=Can't convert to BMPString \: {0}
-K0190=No data to decode
-K0191=Invalid size, must be a multiple of 64 from 512 to 1024
-K0193=An identity with this name already exists in this scope
-K0194=An identity in the scope has the same public key
-K0195=The existing public key and the one contained in the certificate do not match.
-K0196=Certificate is missing
 K0199=Count out of range
-K01a0=End of stream condition
-K01a4=Already shutting down
-K01a5=Illegal shutdown hook\: {0}
-K01a6=Invalid filter
-K01a7=Name too long: {0}
-K01b3=Incorrect number of arguments
-K01b4=Cannot convert {0} to {1}
 K01b6=Cannot find \!/
-K01c1=File is a Directory
-K01c2=Cannot create\: {0}
-K01c3=Unable to open\: {0}
-K01c4=Invalid zip file\: {0}
-K01c6=No Main-Class specified in manifest\: {0}
-K01d1=Signers of '{0}' do not match signers of other classes in package
-K01d2={1} - protected system package '{0}'
-K01ec=key size must be a multiple of 8 bits
-K01ed=key size must be at least 512 bits
 K01fe=Incomplete % sequence at\: {0}
 K01ff=Invalid % sequence ({0}) at\: {1}
-K0220=UTFDataFormatException
-K0222=No Manifest found in jar file\: {0}
-K0300=Unsupported encoding
-K0301=Not signed data
 K0302=Relative path
 K0303=Scheme-specific part expected
 K0304=Authority expected
@@ -249,7 +159,6 @@
 K0316=SocketAddress {0} not supported
 K0317=Host is unresolved\: {0}
 K0318=SocketAddress is null
-K0319=Exception in thread "{0}"\ 
 K031a=URI is not absolute\: {0}
 K031b=URI is not hierarchical\: {0}
 K031c=Expected file scheme in URI\: {0}
@@ -260,25 +169,19 @@
 K0321=Socket input is shutdown
 K0322=Not a supported ISO 4217 Currency Code\: {0}
 K0323=Not a supported ISO 3166 Country locale\: {0}
-K0324=Needs dictionary
 K0325=Port out of range\: {0}
 K0326={0} at index {1}\: {2}
 K0327={0}\: {1}
-K0328=Certificate not yet valid
-K0329=Certificate expired
 K0330=interface name is null
 K0331=address is null
 K0332=Invalid IP Address is neither 4 or 16 bytes\: {0}
 K0333=Urgent data not supported
 K0334=Cannot set network interface with null
 K0335=No addresses associated with Interface
-K0337=null type not allowed
 K0338=Address not associated with an interface - not set
 K0339=Invalid IP Address is neither 4 or 16 bytes
 K0340={0} incompatible with {1}
 K0342=Scheme expected
-K0344=Not a valid {0}, subclass should override readResolve()
-K0346=Unmatched braces in the pattern
 K0347=seek position is negative
 K0348=Format specifier '{0}'
 K0349=Conversion is '{0}'
@@ -286,10 +189,8 @@
 K034b=url and proxy can not be null
 K034c=proxy should not be null
 K034d=method has not been implemented yet
-K034e=Build rules empty
 K0351=format is null
 K0352=package is sealed
-KA000=Line too long
 KA001=Argument must not be null
 KA002=Unshared read of back reference
 KA003=different mode already set
@@ -301,7 +202,6 @@
 KA009=CharsetName is illegal
 KA00a=File is null
 KA00b=InputStream is null
-KA00c=Readable is null
 KA00d=ReadableByteChannel is null
 KA00e=Radix {0} is less than Character.MIN_RADIX or greater than Character.MAX_RADIX
 KA00f=Socket output is shutdown
@@ -321,10 +221,8 @@
 KA023=Proxy is null or invalid type
 KA024=One of urls is null
 KA025=Method has not been implemented
-KA026=JAR entry {0} not found in {1}
 KA027=Inputstream of the JarURLConnection has been closed
 KA028=Cannot set protocol version when stream in use
-KA029=Can't find resource for bundle {0}, key {1}
 KA030=Write end dead
 K0031=Length out of bounds \: {0}
 K0032=Source size {0} does not fit into destination
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/LocaleCache.java b/luni/src/main/java/org/apache/harmony/luni/util/LocaleCache.java
index 7b9957d..98b3f9b 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/LocaleCache.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/LocaleCache.java
@@ -18,7 +18,6 @@
 package org.apache.harmony.luni.util;
 
 import java.text.NumberFormat;
-import java.text.DecimalFormatSymbols;
 import java.util.Locale;
 
 /**
diff --git a/luni/src/main/java/org/apache/harmony/misc/internal/nls/Messages.java b/luni/src/main/java/org/apache/harmony/misc/internal/nls/Messages.java
deleted file mode 100644
index 128545b..0000000
--- a/luni/src/main/java/org/apache/harmony/misc/internal/nls/Messages.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-package org.apache.harmony.misc.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.misc.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (English) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.misc.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/luni/src/main/java/org/apache/harmony/misc/internal/nls/messages.properties b/luni/src/main/java/org/apache/harmony/misc/internal/nls/messages.properties
deleted file mode 100644
index 3c2e838..0000000
--- a/luni/src/main/java/org/apache/harmony/misc/internal/nls/messages.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# messages for EN locale
-misc.0=bad elemSize
-misc.1=Non primitive type {0}
-misc.2=array is already locked/pinned
-misc.3=lock failed
-misc.4=not an array Class
-misc.5=User code is not allowed to get accessors, caller class: {0}
-misc.6=Failed to get UTF-16 support, this is a bug
diff --git a/luni/src/main/native/ifaddrs-android.h b/luni/src/main/native/ifaddrs-android.h
index eb4b69a..b66bf69 100644
--- a/luni/src/main/native/ifaddrs-android.h
+++ b/luni/src/main/native/ifaddrs-android.h
@@ -17,8 +17,13 @@
 #ifndef IFADDRS_ANDROID_H_included
 #define IFADDRS_ANDROID_H_included
 
+#include <arpa/inet.h>
 #include <cstring>
+#include <errno.h>
+#include <net/if.h>
+#include <netinet/in.h>
 #include <new>
+#include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <stdio.h>
@@ -43,11 +48,14 @@
     // Interface flags.
     unsigned int ifa_flags;
 
-    // Interface address.
+    // Interface network address.
     sockaddr* ifa_addr;
 
+    // Interface netmask.
+    sockaddr* ifa_netmask;
+
     ifaddrs(ifaddrs* next)
-    : ifa_next(next), ifa_name(NULL), ifa_flags(0), ifa_addr(NULL)
+    : ifa_next(next), ifa_name(NULL), ifa_flags(0), ifa_addr(NULL), ifa_netmask(NULL)
     {
     }
 
@@ -55,6 +63,7 @@
         delete ifa_next;
         delete[] ifa_name;
         delete ifa_addr;
+        delete ifa_netmask;
     }
 
     // Sadly, we can't keep the interface index for portability with BSD.
@@ -91,17 +100,47 @@
     // stitch the two bits together into the sockaddr that's part of
     // our portable interface.
     void setAddress(int family, void* data, size_t byteCount) {
+        // Set the address proper...
         sockaddr_storage* ss = new sockaddr_storage;
-        ss->ss_family = family;
-        if (family == AF_INET) {
-            void* dst = &reinterpret_cast<sockaddr_in*>(ss)->sin_addr;
-            memcpy(dst, data, byteCount);
-        } else if (family == AF_INET6) {
-            void* dst = &reinterpret_cast<sockaddr_in6*>(ss)->sin6_addr;
-            memcpy(dst, data, byteCount);
-        }
+        memset(ss, 0, sizeof(*ss));
         ifa_addr = reinterpret_cast<sockaddr*>(ss);
+        ss->ss_family = family;
+        uint8_t* dst = sockaddrBytes(family, ss);
+        memcpy(dst, data, byteCount);
     }
+
+    // Netlink gives us the prefix length as a bit count. We need to turn
+    // that into a BSD-compatible netmask represented by a sockaddr*.
+    void setNetmask(int family, size_t prefixLength) {
+        // ...and work out the netmask from the prefix length.
+        sockaddr_storage* ss = new sockaddr_storage;
+        memset(ss, 0, sizeof(*ss));
+        ifa_netmask = reinterpret_cast<sockaddr*>(ss);
+        ss->ss_family = family;
+        uint8_t* dst = sockaddrBytes(family, ss);
+        memset(dst, 0xff, prefixLength / 8);
+        if ((prefixLength % 8) != 0) {
+            dst[prefixLength/8] = (0xff << (8 - (prefixLength % 8)));
+        }
+    }
+
+    // Returns a pointer to the first byte in the address data (which is
+    // stored in network byte order).
+    uint8_t* sockaddrBytes(int family, sockaddr_storage* ss) {
+        if (family == AF_INET) {
+            sockaddr_in* ss4 = reinterpret_cast<sockaddr_in*>(ss);
+            return reinterpret_cast<uint8_t*>(&ss4->sin_addr);
+        } else if (family == AF_INET6) {
+            sockaddr_in6* ss6 = reinterpret_cast<sockaddr_in6*>(ss);
+            return reinterpret_cast<uint8_t*>(&ss6->sin6_addr);
+        }
+        return NULL;
+    }
+
+private:
+    // Disallow copy and assignment.
+    ifaddrs(const ifaddrs&);
+    void operator=(const ifaddrs&);
 };
 
 // FIXME: use iovec instead.
@@ -167,6 +206,7 @@
                                     return -1;
                                 }
                                 (*result)->setAddress(family, RTA_DATA(rta), RTA_PAYLOAD(rta));
+                                (*result)->setNetmask(family, address->ifa_prefixlen);
                             }
                         }
                         rta = RTA_NEXT(rta, ifaPayloadLength);
diff --git a/luni/src/main/native/java_io_Console.cpp b/luni/src/main/native/java_io_Console.cpp
new file mode 100644
index 0000000..fdaafaf
--- /dev/null
+++ b/luni/src/main/native/java_io_Console.cpp
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "JNIHelp.h"
+
+#include <errno.h>
+#include <termios.h>
+#include <unistd.h>
+
+static jboolean java_io_Console_isatty(JNIEnv* env, jclass, jint fd) {
+    return TEMP_FAILURE_RETRY(isatty(fd));
+}
+
+static jint java_io_Console_setEcho(JNIEnv* env, jclass, jboolean on, jint previousState) {
+    termios state;
+    if (TEMP_FAILURE_RETRY(tcgetattr(STDIN_FILENO, &state)) == -1) {
+        jniThrowIOException(env, errno);
+        return 0;
+    }
+    if (on) {
+        state.c_lflag = previousState;
+    } else {
+        previousState = state.c_lflag;
+        state.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+    }
+    if (TEMP_FAILURE_RETRY(tcsetattr(STDIN_FILENO, TCSAFLUSH, &state)) == -1){
+        jniThrowIOException(env, errno);
+        return 0;
+    }
+    return previousState;
+}
+
+static JNINativeMethod gMethods[] = {
+    { "isatty", "(I)Z", (void*) java_io_Console_isatty },
+    { "setEchoImpl", "(ZI)I", (void*) java_io_Console_setEcho },
+};
+int register_java_io_Console(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/io/Console", gMethods, NELEM(gMethods));
+}
diff --git a/luni/src/main/native/java_io_File.cpp b/luni/src/main/native/java_io_File.cpp
index ed25ce7..dc25057 100644
--- a/luni/src/main/native/java_io_File.cpp
+++ b/luni/src/main/native/java_io_File.cpp
@@ -15,22 +15,22 @@
  *  limitations under the License.
  */
 
-#include "AndroidSystemNatives.h"
 #include "JNIHelp.h"
 #include "LocalArray.h"
 #include "ScopedByteArray.h"
 #include "ScopedFd.h"
 
-#include <string.h>
-#include <fcntl.h>
-#include <time.h>
-#include <utime.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
 
 // BEGIN android-note: this file has been extensively rewritten to
 // remove fixed-length buffers, buffer overruns, duplication, and
@@ -105,12 +105,17 @@
     return (access(&path[0], F_OK) == 0);
 }
 
-static jboolean java_io_File_isReadableImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
+static jboolean java_io_File_canExecuteImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
+    ScopedByteArray path(env, pathBytes);
+    return (access(&path[0], X_OK) == 0);
+}
+
+static jboolean java_io_File_canReadImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
     ScopedByteArray path(env, pathBytes);
     return (access(&path[0], R_OK) == 0);
 }
 
-static jboolean java_io_File_isWritableImpl(JNIEnv* env, jobject recv, jbyteArray pathBytes) {
+static jboolean java_io_File_canWriteImpl(JNIEnv* env, jobject recv, jbyteArray pathBytes) {
     ScopedByteArray path(env, pathBytes);
     return (access(&path[0], W_OK) == 0);
 }
@@ -128,7 +133,7 @@
             // An error occurred.
             return pathBytes;
         }
-        if (len < buf.size() - 1) {
+        if (static_cast<size_t>(len) < buf.size() - 1) {
             // The buffer was big enough.
             // TODO: why do we bother with the NUL termination? (if you change this, remove the "- 1"s above.)
             buf[len] = '\0'; // readlink(2) doesn't NUL-terminate.
@@ -158,17 +163,59 @@
     return (utime(&path[0], &times) == 0);
 }
 
-static jboolean java_io_File_setReadOnlyImpl(JNIEnv* env, jobject recv, jbyteArray pathBytes) {
+static jboolean doChmod(JNIEnv* env, jbyteArray pathBytes, mode_t mask, bool set) {
     ScopedByteArray path(env, pathBytes);
-
     struct stat sb;
     if (stat(&path[0], &sb) == -1) {
         return JNI_FALSE;
     }
+    mode_t newMode = set ? (sb.st_mode | mask) : (sb.st_mode & ~mask);
+    return (chmod(&path[0], newMode) == 0);
+}
 
-    // Strictly, this is set-not-writable (i.e. we leave the execute
-    // bits untouched), but that's deliberate.
-    return (chmod(&path[0], sb.st_mode & ~0222) == 0);
+static jboolean java_io_File_setExecutableImpl(JNIEnv* env, jobject, jbyteArray pathBytes,
+        jboolean set, jboolean ownerOnly) {
+    return doChmod(env, pathBytes, ownerOnly ? S_IXUSR : (S_IXUSR | S_IXGRP | S_IXOTH), set);
+}
+
+static jboolean java_io_File_setReadableImpl(JNIEnv* env, jobject, jbyteArray pathBytes,
+        jboolean set, jboolean ownerOnly) {
+    return doChmod(env, pathBytes, ownerOnly ? S_IRUSR : (S_IRUSR | S_IRGRP | S_IROTH), set);
+}
+
+static jboolean java_io_File_setWritableImpl(JNIEnv* env, jobject, jbyteArray pathBytes,
+        jboolean set, jboolean ownerOnly) {
+    return doChmod(env, pathBytes, ownerOnly ? S_IWUSR : (S_IWUSR | S_IWGRP | S_IWOTH), set);
+}
+
+static bool doStatFs(JNIEnv* env, jbyteArray pathBytes, struct statfs& sb) {
+    ScopedByteArray path(env, pathBytes);
+    int rc = statfs(&path[0], &sb);
+    return (rc != -1);
+}
+
+static jlong java_io_File_getFreeSpace(JNIEnv* env, jobject, jbyteArray pathBytes) {
+    struct statfs sb;
+    if (!doStatFs(env, pathBytes, sb)) {
+        return 0;
+    }
+    return sb.f_bfree * sb.f_bsize; // free block count * block size in bytes.
+}
+
+static jlong java_io_File_getTotalSpace(JNIEnv* env, jobject, jbyteArray pathBytes) {
+    struct statfs sb;
+    if (!doStatFs(env, pathBytes, sb)) {
+        return 0;
+    }
+    return sb.f_blocks * sb.f_bsize; // total block count * block size in bytes.
+}
+
+static jlong java_io_File_getUsableSpace(JNIEnv* env, jobject, jbyteArray pathBytes) {
+    struct statfs sb;
+    if (!doStatFs(env, pathBytes, sb)) {
+        return 0;
+    }
+    return sb.f_bavail * sb.f_bsize; // non-root free block count * block size in bytes.
 }
 
 // Iterates over the filenames in the given directory.
@@ -205,6 +252,10 @@
     DIR* mDirStream;
     dirent mEntry;
     bool mIsBad;
+
+    // Disallow copy and assignment.
+    ScopedReaddir(const ScopedReaddir&);
+    void operator=(const ScopedReaddir&);
 };
 
 // DirEntry and DirEntries is a minimal equivalent of std::forward_list
@@ -262,6 +313,10 @@
 private:
     size_t mSize;
     DirEntry* mHead;
+
+    // Disallow copy and assignment.
+    DirEntries(const DirEntries&);
+    void operator=(const DirEntries&);
 };
 
 // Reads the directory referred to by 'pathBytes', adding each directory entry
@@ -339,25 +394,29 @@
 }
 
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "createNewFileImpl",  "([B)Z",  (void*) java_io_File_createNewFileImpl },
-    { "deleteImpl",         "([B)Z",  (void*) java_io_File_deleteImpl },
-    { "existsImpl",         "([B)Z",  (void*) java_io_File_existsImpl },
+    { "canExecuteImpl",     "([B)Z", (void*) java_io_File_canExecuteImpl },
+    { "canReadImpl",        "([B)Z", (void*) java_io_File_canReadImpl },
+    { "canWriteImpl",       "([B)Z", (void*) java_io_File_canWriteImpl },
+    { "createNewFileImpl",  "([B)Z", (void*) java_io_File_createNewFileImpl },
+    { "deleteImpl",         "([B)Z", (void*) java_io_File_deleteImpl },
+    { "existsImpl",         "([B)Z", (void*) java_io_File_existsImpl },
     { "getCanonImpl",       "([B)[B", (void*) java_io_File_getCanonImpl },
+    { "getFreeSpaceImpl",   "([B)J", (void*) java_io_File_getFreeSpace },
     { "getLinkImpl",        "([B)[B", (void*) java_io_File_getLinkImpl },
-    { "isDirectoryImpl",    "([B)Z",  (void*) java_io_File_isDirectoryImpl },
-    { "isFileImpl",         "([B)Z",  (void*) java_io_File_isFileImpl },
-    { "isReadableImpl",     "([B)Z",  (void*) java_io_File_isReadableImpl },
-    { "isWritableImpl",     "([B)Z",  (void*) java_io_File_isWritableImpl },
-    { "lastModifiedImpl",   "([B)J",  (void*) java_io_File_lastModifiedImpl },
-    { "lengthImpl",         "([B)J",  (void*) java_io_File_lengthImpl },
+    { "getTotalSpaceImpl",  "([B)J", (void*) java_io_File_getTotalSpace },
+    { "getUsableSpaceImpl", "([B)J", (void*) java_io_File_getUsableSpace },
+    { "isDirectoryImpl",    "([B)Z", (void*) java_io_File_isDirectoryImpl },
+    { "isFileImpl",         "([B)Z", (void*) java_io_File_isFileImpl },
+    { "lastModifiedImpl",   "([B)J", (void*) java_io_File_lastModifiedImpl },
+    { "lengthImpl",         "([B)J", (void*) java_io_File_lengthImpl },
     { "listImpl",           "([B)[Ljava/lang/String;", (void*) java_io_File_listImpl },
-    { "mkdirImpl",          "([B)Z",  (void*) java_io_File_mkdirImpl },
-    { "renameToImpl",       "([B[B)Z",(void*) java_io_File_renameToImpl },
+    { "mkdirImpl",          "([B)Z", (void*) java_io_File_mkdirImpl },
+    { "renameToImpl",       "([B[B)Z", (void*) java_io_File_renameToImpl },
+    { "setExecutableImpl",  "([BZZ)Z", (void*) java_io_File_setExecutableImpl },
+    { "setReadableImpl",    "([BZZ)Z", (void*) java_io_File_setReadableImpl },
+    { "setWritableImpl",    "([BZZ)Z", (void*) java_io_File_setWritableImpl },
     { "setLastModifiedImpl","([BJ)Z", (void*) java_io_File_setLastModifiedImpl },
-    { "setReadOnlyImpl",    "([B)Z",  (void*) java_io_File_setReadOnlyImpl },
 };
 int register_java_io_File(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/io/File",
-            gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/io/File", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_io_FileDescriptor.c b/luni/src/main/native/java_io_FileDescriptor.c
index 897e688..075e19b 100644
--- a/luni/src/main/native/java_io_FileDescriptor.c
+++ b/luni/src/main/native/java_io_FileDescriptor.c
@@ -185,15 +185,10 @@
     setFd(env, fileDescriptor, value);
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "oneTimeInitialization", "()V",              nativeClassInit },
     { "syncImpl",           "()V",                 fd_sync }
 };
 int register_java_io_FileDescriptor(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/io/FileDescriptor",
-        gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/io/FileDescriptor", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_io_ObjectInputStream.c b/luni/src/main/native/java_io_ObjectInputStream.c
index 3519055..0aa56b0 100644
--- a/luni/src/main/native/java_io_ObjectInputStream.c
+++ b/luni/src/main/native/java_io_ObjectInputStream.c
@@ -16,7 +16,6 @@
  */
 
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 
 static void java_setFieldBool (JNIEnv * env, jclass clazz, 
                                          jobject targetObject, 
@@ -244,11 +243,7 @@
     }
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "setField",          
         "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;J)V",
         (void*) java_setFieldLong },
@@ -282,6 +277,5 @@
 
 };
 int register_java_io_ObjectInputStream(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/io/ObjectInputStream",
-                gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/io/ObjectInputStream", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_io_ObjectOutputStream.c b/luni/src/main/native/java_io_ObjectOutputStream.c
index e465bc2..d6432c7 100644
--- a/luni/src/main/native/java_io_ObjectOutputStream.c
+++ b/luni/src/main/native/java_io_ObjectOutputStream.c
@@ -16,7 +16,6 @@
  */
 
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 
 static jlong java_getFieldLong(JNIEnv * env, jclass clazz,
                                               jobject targetObject,
@@ -205,11 +204,7 @@
     }
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "getFieldLong",   
     	"(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;)J",
     	(void*) java_getFieldLong },
@@ -240,7 +235,5 @@
 
 };
 int register_java_io_ObjectOutputStream(JNIEnv* env) {
-	return jniRegisterNativeMethods(env, "java/io/ObjectOutputStream",
-                gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/io/ObjectOutputStream", gMethods, NELEM(gMethods));
 }
-
diff --git a/luni/src/main/native/java_io_ObjectStreamClass.c b/luni/src/main/native/java_io_ObjectStreamClass.c
index c3fb518..935ff37 100644
--- a/luni/src/main/native/java_io_ObjectStreamClass.c
+++ b/luni/src/main/native/java_io_ObjectStreamClass.c
@@ -16,7 +16,6 @@
  */
 
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 
 static jobject java_io_osc_getFieldSignature(JNIEnv * env, jclass clazz,
                                                   jobject reflectField) {
@@ -109,11 +108,7 @@
   // dummy to stay compatible to harmony
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "getFieldSignature",       
     	"(Ljava/lang/reflect/Field;)Ljava/lang/String;",
     	(void*) java_io_osc_getFieldSignature },
@@ -129,6 +124,5 @@
     	(void*) java_io_osc_oneTimeInitialization }
 };
 int register_java_io_ObjectStreamClass(JNIEnv* env) {
-	return jniRegisterNativeMethods(env, "java/io/ObjectStreamClass",
-                gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/io/ObjectStreamClass", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_lang_Character.cpp b/luni/src/main/native/java_lang_Character.cpp
deleted file mode 100644
index c1324d6..0000000
--- a/luni/src/main/native/java_lang_Character.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-//  java_lang_Character.cpp
-//  Android
-//
-//  Copyright 2006 The Android Open Source Project
-//
-#include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
-
-//#define LOG_TAG "Character"
-//#include "utils/Log.h"
-#include "utils/AndroidUnicode.h"
-
-#include <stdlib.h>
-
-
-using namespace android;
-
-/*
- * native private static int nativeGetData(int c)
- */
-static jint getData(JNIEnv* env, jclass clazz, jint val)
-{
-    return Unicode::getPackedData(val);
-}
-
-/*
- * native private static int nativeToLower(int c)
- */
-static jint toLower(JNIEnv* env, jclass clazz, jint val)
-{
-    return Unicode::toLower(val);
-}
-
-/*
- * native private static int nativeToUpper(int c)
- */
-static jint toUpper(JNIEnv* env, jclass clazz, jint val)
-{
-    return Unicode::toUpper(val);
-}
-
-/*
- * native private static int nativeNumericValue(int c)
- */
-static jint numericValue(JNIEnv* env, jclass clazz, jint val)
-{
-    return Unicode::getNumericValue(val);
-}
-
-/*
- * native private static int nativeToTitle(int c)
- */
-static jint toTitle(JNIEnv* env, jclass clazz, jint val)
-{
-    return Unicode::toTitle(val);
-}
-
-/*
- * JNI registration
- */
-static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "nativeGetData",          "(I)I",     (void*) getData },
-    { "nativeToLower",          "(I)I",     (void*) toLower },
-    { "nativeToUpper",          "(I)I",     (void*) toUpper },
-    { "nativeNumericValue",     "(I)I",     (void*) numericValue },
-    { "nativeToTitle",          "(I)I",     (void*) toTitle },
-};
-int register_java_lang_Character(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/lang/Character",
-        gMethods, NELEM(gMethods));
-}
-
diff --git a/luni/src/main/native/java_lang_Double.c b/luni/src/main/native/java_lang_Double.c
index fd4b7f1..9cc0869 100644
--- a/luni/src/main/native/java_lang_Double.c
+++ b/luni/src/main/native/java_lang_Double.c
@@ -60,18 +60,11 @@
     return d.d;
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "doubleToLongBits",       "(D)J",     doubleToLongBits },
     { "doubleToRawLongBits",    "(D)J",     doubleToRawLongBits },
     { "longBitsToDouble",       "(J)D",     longBitsToDouble },
 };
-int register_java_lang_Double(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/lang/Double",
-                gMethods, NELEM(gMethods));
+int register_java_lang_Double(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/lang/Double", gMethods, NELEM(gMethods));
 }
-
diff --git a/luni/src/main/native/java_lang_Float.c b/luni/src/main/native/java_lang_Float.c
index 2a7af21..6426495 100644
--- a/luni/src/main/native/java_lang_Float.c
+++ b/luni/src/main/native/java_lang_Float.c
@@ -68,18 +68,11 @@
     return f.f;
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "floatToIntBits",         "(F)I",     floatToIntBits },
     { "floatToRawIntBits",      "(F)I",     floatToRawBits },
     { "intBitsToFloat",         "(I)F",     intBitsToFloat },
 };
-int register_java_lang_Float(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/lang/Float",
-        gMethods, NELEM(gMethods));
+int register_java_lang_Float(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/lang/Float", gMethods, NELEM(gMethods));
 }
-
diff --git a/luni/src/main/native/java_lang_Math.c b/luni/src/main/native/java_lang_Math.c
index a3a69dd..2092c2d 100644
--- a/luni/src/main/native/java_lang_Math.c
+++ b/luni/src/main/native/java_lang_Math.c
@@ -159,46 +159,46 @@
     return nextafterf(a, b);
 }
 
-/*
- * JNI registration.
- */
+static jdouble copySign(JNIEnv* env, jclass clazz, jdouble a, jdouble b) {
+    // Our StrictMath.copySign delegates to Math.copySign, so we need to treat NaN as positive.
+    return copysign(a, isnan(b) ? 1.0 : b);
+}
+
+static jfloat copySign_f(JNIEnv* env, jclass clazz, jfloat a, jfloat b) {
+    // Our StrictMath.copySign delegates to Math.copySign, so we need to treat NaN as positive.
+    return copysignf(a, isnan(b) ? 1.0 : b);
+}
+
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "sin",    "(D)D", jsin },
-    { "cos",    "(D)D", jcos },
-    { "tan",    "(D)D", jtan },
-
-    { "asin",   "(D)D", jasin },
-    { "acos",   "(D)D", jacos },
-    { "atan",   "(D)D", jatan },
-
-    { "exp",    "(D)D", jexp },
-    { "log",    "(D)D", jlog },
-    { "sqrt",   "(D)D", jsqrt },
-
     { "IEEEremainder", "(DD)D", jieee_remainder },
-
-    { "floor",  "(D)D", jfloor },
-    { "ceil",   "(D)D", jceil },
-    { "rint",   "(D)D", jrint },
-
+    { "acos",   "(D)D", jacos },
+    { "asin",   "(D)D", jasin },
+    { "atan",   "(D)D", jatan },
     { "atan2",  "(DD)D", jatan2 },
-    { "pow",    "(DD)D", jpow },
-
-    { "sinh",   "(D)D", jsinh },
-    { "cosh",   "(D)D", jcosh },
-    { "tanh",   "(D)D", jtanh },
-    { "log10",  "(D)D", jlog10 },
     { "cbrt",   "(D)D", jcbrt },
+    { "ceil",   "(D)D", jceil },
+    { "copySign",  "(DD)D", copySign },
+    { "copySign",  "(FF)F", copySign_f },
+    { "cos",    "(D)D", jcos },
+    { "cosh",   "(D)D", jcosh },
+    { "exp",    "(D)D", jexp },
     { "expm1",  "(D)D", jexpm1 },
+    { "floor",  "(D)D", jfloor },
     { "hypot",  "(DD)D", jhypot },
+    { "log",    "(D)D", jlog },
+    { "log10",  "(D)D", jlog10 },
     { "log1p",  "(D)D", jlog1p },
     { "nextafter",  "(DD)D", jnextafter },
     { "nextafterf",  "(FF)F", jnextafterf },
+    { "pow",    "(DD)D", jpow },
+    { "rint",   "(D)D", jrint },
+    { "sin",    "(D)D", jsin },
+    { "sinh",   "(D)D", jsinh },
+    { "sqrt",   "(D)D", jsqrt },
+    { "tan",    "(D)D", jtan },
+    { "tanh",   "(D)D", jtanh },
 };
 
-int register_java_lang_Math(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/lang/Math", gMethods,
-        NELEM(gMethods));
+int register_java_lang_Math(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/lang/Math", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_lang_StrictMath.c b/luni/src/main/native/java_lang_StrictMath.c
index 7d335f7..651e2dd 100644
--- a/luni/src/main/native/java_lang_StrictMath.c
+++ b/luni/src/main/native/java_lang_StrictMath.c
@@ -8,7 +8,7 @@
 
 #include <stdlib.h>
 /* This static way is the "best" way to integrate fdlibm without a conflict
- * into the android envoirement 
+ * into the android environment.
  */
 
 /* #include "fltconst.h" */
@@ -184,46 +184,34 @@
     return arg1;
 }
 
-/*
- * JNI registration.
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "sin",    "(D)D", jsin },
-    { "cos",    "(D)D", jcos },
-    { "tan",    "(D)D", jtan },
-
-    { "asin",   "(D)D", jasin },
-    { "acos",   "(D)D", jacos },
-    { "atan",   "(D)D", jatan },
-
-    { "exp",    "(D)D", jexp },
-    { "log",    "(D)D", jlog },
-    { "sqrt",   "(D)D", jsqrt2 },
-
     { "IEEEremainder", "(DD)D", jieee_remainder },
-
-    { "floor",  "(D)D", jfloor },
-    { "ceil",   "(D)D", jceil },
-    { "rint",   "(D)D", jrint },
-
+    { "acos",   "(D)D", jacos },
+    { "asin",   "(D)D", jasin },
+    { "atan",   "(D)D", jatan },
     { "atan2",  "(DD)D", jatan2 },
-    { "pow",    "(DD)D", jpow },
-
-    { "sinh",   "(D)D", jsinh },
-    { "cosh",   "(D)D", jcosh },
-    { "tanh",   "(D)D", jtanh },
-    { "log10",  "(D)D", jlog10 },
     { "cbrt",   "(D)D", jcbrt },
+    { "ceil",   "(D)D", jceil },
+    { "cos",    "(D)D", jcos },
+    { "cosh",   "(D)D", jcosh },
+    { "exp",    "(D)D", jexp },
     { "expm1",  "(D)D", jexpm1 },
+    { "floor",  "(D)D", jfloor },
     { "hypot",  "(DD)D", jhypot },
+    { "log",    "(D)D", jlog },
+    { "log10",  "(D)D", jlog10 },
     { "log1p",  "(D)D", jlog1p },
     { "nextafter",  "(DD)D", jnextafter },
     { "nextafterf",  "(FF)F", jnextafterf },
+    { "pow",    "(DD)D", jpow },
+    { "rint",   "(D)D", jrint },
+    { "sin",    "(D)D", jsin },
+    { "sinh",   "(D)D", jsinh },
+    { "sqrt",   "(D)D", jsqrt2 },
+    { "tan",    "(D)D", jtan },
+    { "tanh",   "(D)D", jtanh },
 };
 
-int register_java_lang_StrictMath(JNIEnv* env)
-{
-    return jniRegisterNativeMethods(env, "java/lang/StrictMath", gMethods,
-        NELEM(gMethods));
+int register_java_lang_StrictMath(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "java/lang/StrictMath", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/java_net_InetAddress.cpp b/luni/src/main/native/java_net_InetAddress.cpp
index 04c18af..2fc575ae 100644
--- a/luni/src/main/native/java_net_InetAddress.cpp
+++ b/luni/src/main/native/java_net_InetAddress.cpp
@@ -83,8 +83,7 @@
         // Count results so we know how to size the output array.
         int addressCount = 0;
         for (addrInfo = addressList; addrInfo; addrInfo = addrInfo->ai_next) {
-            if (addrInfo->ai_family == AF_INET ||
-                addrInfo->ai_family == AF_INET6) {
+            if (addrInfo->ai_family == AF_INET || addrInfo->ai_family == AF_INET6) {
                 addressCount++;
             }
         }
@@ -94,7 +93,7 @@
         if (addressArray == NULL) {
             // Appropriate exception will be thrown.
             LOGE("getaddrinfo: could not allocate array of size %i", addressCount);
-            freeaddrinfo(addrInfo);
+            freeaddrinfo(addressList);
             return NULL;
         }
 
@@ -109,20 +108,17 @@
                 // Find the raw address length and start pointer.
                 case AF_INET6:
                     addressLength = 16;
-                    rawAddress =
-                        &((struct sockaddr_in6*) address)->sin6_addr.s6_addr;
+                    rawAddress = &((struct sockaddr_in6*) address)->sin6_addr.s6_addr;
                     logIpString(addrInfo, name);
                     break;
                 case AF_INET:
                     addressLength = 4;
-                    rawAddress =
-                        &((struct sockaddr_in*) address)->sin_addr.s_addr;
+                    rawAddress = &((struct sockaddr_in*) address)->sin_addr.s_addr;
                     logIpString(addrInfo, name);
                     break;
                 default:
                     // Unknown address family. Skip this address.
-                    LOGE("getaddrinfo: Unknown address family %d",
-                         addrInfo->ai_family);
+                    LOGE("getaddrinfo: Unknown address family %d", addrInfo->ai_family);
                     continue;
             }
 
@@ -130,13 +126,11 @@
             jbyteArray bytearray = env->NewByteArray(addressLength);
             if (bytearray == NULL) {
                 // Out of memory error will be thrown on return.
-                LOGE("getaddrinfo: Can't allocate %d-byte array",
-                     addressLength);
+                LOGE("getaddrinfo: Can't allocate %d-byte array", addressLength);
                 addressArray = NULL;
                 break;
             }
-            env->SetByteArrayRegion(bytearray, 0, addressLength,
-                                    (jbyte*) rawAddress);
+            env->SetByteArrayRegion(bytearray, 0, addressLength, (jbyte*) rawAddress);
             env->SetObjectArrayElement(addressArray, index, bytearray);
             env->DeleteLocalRef(bytearray);
             index++;
@@ -146,8 +140,7 @@
         jniThrowException(env, "java/lang/SecurityException",
             "Permission denied (maybe missing INTERNET permission)");
     } else {
-        jniThrowException(env, "java/net/UnknownHostException",
-                gai_strerror(result));
+        jniThrowException(env, "java/net/UnknownHostException", gai_strerror(result));
     }
 
     if (addressList) {
@@ -221,17 +214,12 @@
     return env->NewStringUTF(name);
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "getaddrinfo", "(Ljava/lang/String;)[[B", (void*) InetAddress_getaddrinfo },
     { "gethostname", "()Ljava/lang/String;", (void*) InetAddress_gethostname  },
     { "getnameinfo", "([B)Ljava/lang/String;", (void*) InetAddress_getnameinfo },
 };
-
-extern "C" int register_java_net_InetAddress(JNIEnv* env) {
+int register_java_net_InetAddress(JNIEnv* env) {
     jclass tempClass = env->FindClass("[B");
     if (tempClass) {
         byteArrayClass = (jclass) env->NewGlobalRef(tempClass);
diff --git a/luni/src/main/native/java_net_NetworkInterface.cpp b/luni/src/main/native/java_net_NetworkInterface.cpp
index 420c045..16b4619 100644
--- a/luni/src/main/native/java_net_NetworkInterface.cpp
+++ b/luni/src/main/native/java_net_NetworkInterface.cpp
@@ -15,9 +15,9 @@
  *  limitations under the License.
  */
 
-#include "AndroidSystemNatives.h"
 #include "JNIHelp.h"
 #include "jni.h"
+#include "ScopedFd.h"
 
 #include <errno.h>
 #include <netinet/in.h>
@@ -30,7 +30,7 @@
 
 #include <net/if.h> // Note: Can't appear before <sys/socket.h> on OS X.
 
-#ifdef ANDROID
+#ifdef HAVE_ANDROID_OS
 #include "ifaddrs-android.h"
 #else
 #include <ifaddrs.h>
@@ -52,6 +52,11 @@
     }
     
     ifaddrs* list;
+
+private:
+    // Disallow copy and assignment.
+    ScopedInterfaceAddresses(const ScopedInterfaceAddresses&);
+    void operator=(const ScopedInterfaceAddresses&);
 };
 
 // TODO: add a header file for shared utilities like this.
@@ -64,27 +69,34 @@
             jniStrError(errno, buf, sizeof(buf)));
 }
 
-static jobject makeInterfaceAddress(JNIEnv* env, jint interfaceIndex, const char* name, sockaddr_storage* ss) {
+static jobject makeInterfaceAddress(JNIEnv* env, jint interfaceIndex, ifaddrs* ifa) {
     jclass clazz = env->FindClass("java/net/InterfaceAddress");
     if (clazz == NULL) {
         return NULL;
     }
-    jmethodID constructor = env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;Ljava/net/InetAddress;)V");
+    jmethodID constructor = env->GetMethodID(clazz, "<init>",
+            "(ILjava/lang/String;Ljava/net/InetAddress;Ljava/net/InetAddress;)V");
     if (constructor == NULL) {
         return NULL;
     }
-    jobject javaName = env->NewStringUTF(name);
+    jobject javaName = env->NewStringUTF(ifa->ifa_name);
     if (javaName == NULL) {
         return NULL;
     }
-    jobject javaAddress = socketAddressToInetAddress(env, ss);
+    sockaddr_storage* addr = reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr);
+    jobject javaAddress = socketAddressToInetAddress(env, addr);
     if (javaAddress == NULL) {
         return NULL;
     }
-    return env->NewObject(clazz, constructor, interfaceIndex, javaName, javaAddress);
+    sockaddr_storage* mask = reinterpret_cast<sockaddr_storage*>(ifa->ifa_netmask);
+    jobject javaMask = socketAddressToInetAddress(env, mask);
+    if (javaMask == NULL) {
+        return NULL;
+    }
+    return env->NewObject(clazz, constructor, interfaceIndex, javaName, javaAddress, javaMask);
 }
 
-static jobjectArray getInterfaceAddresses(JNIEnv* env, jclass) {
+static jobjectArray getAllInterfaceAddressesImpl(JNIEnv* env, jclass) {
     // Get the list of interface addresses.
     ScopedInterfaceAddresses addresses;
     if (!addresses.init()) {
@@ -128,8 +140,7 @@
             continue;
         }
         // Make a new InterfaceAddress, and insert it into the array.
-        sockaddr_storage* ss = reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr);
-        jobject element = makeInterfaceAddress(env, interfaceIndex, ifa->ifa_name, ss);
+        jobject element = makeInterfaceAddress(env, interfaceIndex, ifa);
         if (element == NULL) {
             return NULL;
         }
@@ -142,11 +153,89 @@
     return result;
 }
 
+static bool doIoctl(JNIEnv* env, jstring name, int request, ifreq& ifr) {
+    // Copy the name into the ifreq structure, if there's room...
+    jsize nameLength = env->GetStringLength(name);
+    if (nameLength >= IFNAMSIZ) {
+        errno = ENAMETOOLONG;
+        jniThrowSocketException(env);
+        return false;
+    }
+    memset(&ifr, 0, sizeof(ifr));
+    env->GetStringUTFRegion(name, 0, nameLength, ifr.ifr_name);
+
+    // ...and do the ioctl.
+    ScopedFd fd(socket(AF_INET, SOCK_DGRAM, 0));
+    if (fd.get() == -1) {
+        jniThrowSocketException(env);
+        return false;
+    }
+    int rc = ioctl(fd.get(), request, &ifr);
+    if (rc == -1) {
+        jniThrowSocketException(env);
+        return false;
+    }
+    return true;
+}
+
+static jboolean hasFlag(JNIEnv* env, jstring name, int flag) {
+    ifreq ifr;
+    doIoctl(env, name, SIOCGIFFLAGS, ifr); // May throw.
+    return (ifr.ifr_flags & flag) != 0;
+}
+
+static jbyteArray getHardwareAddressImpl(JNIEnv* env, jclass, jstring name, jint index) {
+    ifreq ifr;
+    if (!doIoctl(env, name, SIOCGIFHWADDR, ifr)) {
+        return NULL;
+    }
+    jbyte bytes[IFHWADDRLEN];
+    bool isEmpty = true;
+    for (int i = 0; i < IFHWADDRLEN; ++i) {
+        bytes[i] = ifr.ifr_hwaddr.sa_data[i];
+        if (bytes[i] != 0) {
+            isEmpty = false;
+        }
+    }
+    if (isEmpty) {
+        return NULL;
+    }
+    jbyteArray result = env->NewByteArray(IFHWADDRLEN);
+    env->SetByteArrayRegion(result, 0, IFHWADDRLEN, bytes);
+    return result;
+}
+
+static jint getMTUImpl(JNIEnv* env, jclass, jstring name, jint index) {
+    ifreq ifr;
+    doIoctl(env, name, SIOCGIFMTU, ifr); // May throw.
+    return ifr.ifr_mtu;
+}
+
+static jboolean isLoopbackImpl(JNIEnv* env, jclass, jstring name, jint index) {
+    return hasFlag(env, name, IFF_LOOPBACK);
+}
+
+static jboolean isPointToPointImpl(JNIEnv* env, jclass, jstring name, jint index) {
+    return hasFlag(env, name, IFF_POINTOPOINT); // Unix API typo!
+}
+
+static jboolean isUpImpl(JNIEnv* env, jclass, jstring name, jint index) {
+    return hasFlag(env, name, IFF_UP);
+}
+
+static jboolean supportsMulticastImpl(JNIEnv* env, jclass, jstring name, jint index) {
+    return hasFlag(env, name, IFF_MULTICAST);
+}
+
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "getInterfaceAddresses", "()[Ljava/net/InterfaceAddress;", (void*) getInterfaceAddresses },
+    { "getAllInterfaceAddressesImpl", "()[Ljava/net/InterfaceAddress;", (void*) getAllInterfaceAddressesImpl },
+    { "getHardwareAddressImpl", "(Ljava/lang/String;I)[B", (void*) getHardwareAddressImpl },
+    { "getMTUImpl", "(Ljava/lang/String;I)I", (void*) getMTUImpl },
+    { "isLoopbackImpl", "(Ljava/lang/String;I)Z", (void*) isLoopbackImpl },
+    { "isPointToPointImpl", "(Ljava/lang/String;I)Z", (void*) isPointToPointImpl },
+    { "isUpImpl", "(Ljava/lang/String;I)Z", (void*) isUpImpl },
+    { "supportsMulticastImpl", "(Ljava/lang/String;I)Z", (void*) supportsMulticastImpl },
 };
 int register_java_net_NetworkInterface(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "java/net/NetworkInterface",
-            gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "java/net/NetworkInterface", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp
index 3100767..af82efc 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSFileSystem.cpp
@@ -38,7 +38,6 @@
 #define HyOpenSync      128
 #define SHARED_LOCK_TYPE 1L
 
-#include "AndroidSystemNatives.h"
 #include "JNIHelp.h"
 #include "LocalArray.h"
 #include "ScopedByteArray.h"
@@ -450,7 +449,7 @@
     return rc;
 }
 
-static jint harmony_io_ioctlAvailable(JNIEnv*env, jobject, jint fd) {
+static jint harmony_io_ioctlAvailable(JNIEnv*env, jobject, jobject fileDescriptor) {
     /*
      * On underlying platforms Android cares about (read "Linux"),
      * ioctl(fd, FIONREAD, &avail) is supposed to do the following:
@@ -476,6 +475,10 @@
      * actually read some amount of data and caused the cursor to be
      * advanced.
      */
+    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+    if (fd == -1) {
+        return -1;
+    }
     int avail = 0;
     int rc = ioctl(fd, FIONREAD, &avail);
     if (rc >= 0) {
@@ -497,15 +500,11 @@
     return (jint) avail;
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "close",              "(I)V",       (void*) harmony_io_close },
     { "fflush",             "(IZ)V",      (void*) harmony_io_fflush },
     { "getAllocGranularity","()I",        (void*) harmony_io_getAllocGranularity },
-    { "ioctlAvailable",     "(I)I",       (void*) harmony_io_ioctlAvailable },
+    { "ioctlAvailable", "(Ljava/io/FileDescriptor;)I", (void*) harmony_io_ioctlAvailable },
     { "lockImpl",           "(IJJIZ)I",   (void*) harmony_io_lockImpl },
     { "openImpl",           "([BI)I",     (void*) harmony_io_openImpl },
     { "readDirect",         "(IIII)J",    (void*) harmony_io_readDirect },
@@ -520,8 +519,7 @@
     { "writeImpl",          "(I[BII)J",   (void*) harmony_io_writeImpl },
     { "writev",             "(I[I[I[II)J",(void*) harmony_io_writev },
 };
-int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv* _env) {
-    return jniRegisterNativeMethods(_env,
-            "org/apache/harmony/luni/platform/OSFileSystem", gMethods,
+int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "org/apache/harmony/luni/platform/OSFileSystem", gMethods,
             NELEM(gMethods));
 }
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp
index 1d63faf..d1dafdb 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSMemory.cpp
@@ -15,8 +15,8 @@
  */
 
 #define LOG_TAG "OSMemory"
+
 #include "JNIHelp.h"
-#include "AndroidSystemNatives.h"
 #include "utils/misc.h"
 #include "utils/Log.h"
 #include <sys/mman.h>
@@ -535,11 +535,7 @@
     return msync((void *)address, size, MS_SYNC);
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
     { "isLittleEndianImpl", "()Z",     (void*) harmony_nio_littleEndian },
     { "getPointerSizeImpl", "()I",     (void*) harmony_nio_getPointerSizeImpl },
     { "malloc",             "(I)I",    (void*) harmony_nio_mallocImpl },
@@ -570,7 +566,7 @@
     { "isLoadedImpl",       "(IJ)Z",   (void*) harmony_nio_isLoadedImpl },
     { "flushImpl",          "(IJ)I",   (void*) harmony_nio_flushImpl }
 };
-int register_org_apache_harmony_luni_platform_OSMemory(JNIEnv *_env) {
+int register_org_apache_harmony_luni_platform_OSMemory(JNIEnv* env) {
     /*
      * We need to call VMRuntime.trackExternal{Allocation,Free}.  Cache
      * method IDs and a reference to the singleton.
@@ -579,16 +575,16 @@
     jmethodID method_getRuntime;
     jclass clazz;
 
-    clazz = _env->FindClass(kVMRuntimeName);
+    clazz = env->FindClass(kVMRuntimeName);
     if (clazz == NULL) {
         LOGE("Unable to find class %s\n", kVMRuntimeName);
         return -1;
     }
-    gIDCache.method_trackExternalAllocation = _env->GetMethodID(clazz,
+    gIDCache.method_trackExternalAllocation = env->GetMethodID(clazz,
         "trackExternalAllocation", "(J)Z");
-    gIDCache.method_trackExternalFree = _env->GetMethodID(clazz,
+    gIDCache.method_trackExternalFree = env->GetMethodID(clazz,
         "trackExternalFree", "(J)V");
-    method_getRuntime = _env->GetStaticMethodID(clazz,
+    method_getRuntime = env->GetStaticMethodID(clazz,
         "getRuntime", "()Ldalvik/system/VMRuntime;");
 
     if (gIDCache.method_trackExternalAllocation == NULL ||
@@ -599,17 +595,13 @@
         return -1;
     }
 
-    jobject instance = _env->CallStaticObjectMethod(clazz, method_getRuntime);
+    jobject instance = env->CallStaticObjectMethod(clazz, method_getRuntime);
     if (instance == NULL) {
         LOGE("Unable to obtain VMRuntime instance\n");
         return -1;
     }
-    gIDCache.runtimeInstance = _env->NewGlobalRef(instance);
+    gIDCache.runtimeInstance = env->NewGlobalRef(instance);
 
-    /*
-     * Register methods.
-     */
-    return jniRegisterNativeMethods(_env,
-                "org/apache/harmony/luni/platform/OSMemory",
-                gMethods, NELEM(gMethods));
+    return jniRegisterNativeMethods(env, "org/apache/harmony/luni/platform/OSMemory",
+            gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index 4680ca6..0dbb070 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -23,7 +23,6 @@
 
 #define LOG_TAG "OSNetworkSystem"
 
-#include "AndroidSystemNatives.h"
 #include "JNIHelp.h"
 #include "LocalArray.h"
 #include "jni.h"
@@ -331,38 +330,70 @@
     return byteArrayToInetAddress(env, byteArray);
 }
 
-/**
- * Converts an IPv4 address to an IPv4-mapped IPv6 address if fd is an IPv6
- * socket.
- * @param fd the socket.
- * @param sin_ss the address.
- * @param sin6_ss scratch space where we can store the mapped address if necessary.
- * @param mapUnspecified if true, convert 0.0.0.0 to ::ffff:0:0; if false, to ::
- * @return either sin_ss or sin6_ss, depending on which the caller should use.
- */
-static const sockaddr* convertIpv4ToMapped(int fd,
-        const sockaddr_storage* sin_ss, sockaddr_storage* sin6_ss, bool mapUnspecified) {
-    // We need to map if we have an IPv4 address but an IPv6 socket.
-    bool needsMapping = (sin_ss->ss_family == AF_INET && getSocketAddressFamily(fd) == AF_INET6);
-    if (!needsMapping) {
-        return reinterpret_cast<const sockaddr*>(sin_ss);
+// Handles translating between IPv4 and IPv6 addresses so -- where possible --
+// we can use either class of address with either an IPv4 or IPv6 socket.
+class CompatibleSocketAddress {
+public:
+    // Constructs an address corresponding to 'ss' that's compatible with 'fd'.
+    CompatibleSocketAddress(int fd, const sockaddr_storage& ss, bool mapUnspecified) {
+        const int desiredFamily = getSocketAddressFamily(fd);
+        if (ss.ss_family == AF_INET6) {
+            if (desiredFamily == AF_INET6) {
+                // Nothing to do.
+                mCompatibleAddress = reinterpret_cast<const sockaddr*>(&ss);
+            } else {
+                sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&mTmp);
+                const sockaddr_in6* sin6 = reinterpret_cast<const sockaddr_in6*>(&ss);
+                memset(sin, 0, sizeof(*sin));
+                sin->sin_family = AF_INET;
+                sin->sin_port = sin6->sin6_port;
+                if (IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr)) {
+                    // We have an IPv6-mapped IPv4 address, but need plain old IPv4.
+                    // Unmap the mapped address in ss into an IPv6 address in mTmp.
+                    memcpy(&sin->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12], 4);
+                    mCompatibleAddress = reinterpret_cast<const sockaddr*>(&mTmp);
+                } else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
+                    // Translate the IPv6 loopback address to the IPv4 one.
+                    sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+                    mCompatibleAddress = reinterpret_cast<const sockaddr*>(&mTmp);
+                } else {
+                    // We can't help you. We return what you gave us, and assume you'll
+                    // get a sensible error when you use the address.
+                    mCompatibleAddress = reinterpret_cast<const sockaddr*>(&ss);
+                }
+            }
+        } else /* ss.ss_family == AF_INET */ {
+            if (desiredFamily == AF_INET) {
+                // Nothing to do.
+                mCompatibleAddress = reinterpret_cast<const sockaddr*>(&ss);
+            } else {
+                // We have IPv4 and need IPv6.
+                // Map the IPv4 address in ss into an IPv6 address in mTmp.
+                const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(&ss);
+                sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(&mTmp);
+                memset(sin6, 0, sizeof(*sin6));
+                sin6->sin6_family = AF_INET6;
+                sin6->sin6_port = sin->sin_port;
+                // TODO: mapUnspecified was introduced because kernels < 2.6.31 don't allow
+                // you to bind to ::ffff:0.0.0.0. When we move to something >= 2.6.31, we
+                // should make the code behave as if mapUnspecified were always true, and
+                // remove the parameter.
+                if (sin->sin_addr.s_addr != 0 || mapUnspecified) {
+                    memset(&(sin6->sin6_addr.s6_addr[10]), 0xff, 2);
+                }
+                memcpy(&sin6->sin6_addr.s6_addr[12], &sin->sin_addr.s_addr, 4);
+                mCompatibleAddress = reinterpret_cast<const sockaddr*>(&mTmp);
+            }
+        }
     }
-    // Map the IPv4 address in sin_ss into an IPv6 address in sin6_ss.
-    const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(sin_ss);
-    sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(sin6_ss);
-    memset(sin6, 0, sizeof(*sin6));
-    sin6->sin6_family = AF_INET6;
-    sin6->sin6_port = sin->sin_port;
-    // TODO: mapUnspecified was introduced because kernels < 2.6.31 don't allow
-    // you to bind to ::ffff:0.0.0.0. When we move to something >= 2.6.31, we
-    // should make the code behave as if mapUnspecified were always true, and
-    // remove the parameter.
-    if (sin->sin_addr.s_addr != 0 || mapUnspecified) {
-        memset(&(sin6->sin6_addr.s6_addr[10]), 0xff, 2);
+    // Returns a pointer to an address compatible with the socket.
+    const sockaddr* get() const {
+        return mCompatibleAddress;
     }
-    memcpy(&sin6->sin6_addr.s6_addr[12], &sin->sin_addr.s_addr, 4);
-    return reinterpret_cast<const sockaddr*>(sin6_ss);
-}
+private:
+    const sockaddr* mCompatibleAddress;
+    sockaddr_storage mTmp;
+};
 
 /**
  * Converts an InetAddress object and port number to a native address structure.
@@ -424,7 +455,7 @@
  *
  * @return a string with the textual representation of the address.
  */
-static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jclass,
+static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jobject,
         jbyteArray byteArray) {
     if (byteArray == NULL) {
         jniThrowNullPointerException(env, NULL);
@@ -478,7 +509,7 @@
  *
  * @throws UnknownHostException the IP address was invalid.
  */
-static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jclass,
+static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jobject,
         jstring javaString) {
     if (javaString == NULL) {
         jniThrowNullPointerException(env, NULL);
@@ -926,9 +957,8 @@
  * @param socketAddress the address to connect to
  */
 static int doConnect(int fd, const sockaddr_storage* socketAddress) {
-    sockaddr_storage tmp;
-    const sockaddr* realAddress = convertIpv4ToMapped(fd, socketAddress, &tmp, true);
-    return TEMP_FAILURE_RETRY(connect(fd, realAddress, sizeof(sockaddr_storage)));
+    const CompatibleSocketAddress compatibleAddress(fd, *socketAddress, true);
+    return TEMP_FAILURE_RETRY(connect(fd, compatibleAddress.get(), sizeof(sockaddr_storage)));
 }
 
 /**
@@ -1442,12 +1472,12 @@
         return -1;
     }
 
-    int sock;
-    sock = socket(PF_INET6, type, 0);
-    if (sock < 0 && errno == EAFNOSUPPORT) {
+    // Try IPv6 but fall back to IPv4...
+    int sock = socket(PF_INET6, type, 0);
+    if (sock == -1 && errno == EAFNOSUPPORT) {
         sock = socket(PF_INET, type, 0);
     }
-    if (sock < 0) {
+    if (sock == -1) {
         jniThrowSocketException(env, errno);
         return sock;
     }
@@ -1455,22 +1485,16 @@
     return sock;
 }
 
-static void osNetworkSystem_createStreamSocketImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jboolean preferIPv4Stack) {
-    // LOGD("ENTER createSocketImpl");
+static void osNetworkSystem_createStreamSocket(JNIEnv* env, jobject, jobject fileDescriptor, jboolean) {
     createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
 }
 
-static void osNetworkSystem_createDatagramSocketImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jboolean preferIPv4Stack) {
-    // LOGD("ENTER createDatagramSocketImpl");
-    createSocketFileDescriptor(env, fileDescriptor, SOCK_DGRAM);
+static void osNetworkSystem_createDatagramSocket(JNIEnv* env, jobject, jobject fd, jboolean) {
+    createSocketFileDescriptor(env, fd, SOCK_DGRAM);
 }
 
-static jint osNetworkSystem_readSocketDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_readDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jint address, jint count, jint timeout) {
-    // LOGD("ENTER readSocketDirectImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return 0;
@@ -1512,16 +1536,14 @@
     }
     jint address =
             static_cast<jint>(reinterpret_cast<uintptr_t>(bytes + offset));
-    int result = osNetworkSystem_readSocketDirectImpl(env, clazz,
+    int result = osNetworkSystem_readDirect(env, NULL,
             fileDescriptor, address, count, timeout);
     env->ReleaseByteArrayElements(byteArray, bytes, 0);
     return result;
 }
 
-static jint osNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_writeDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jint address, jint offset, jint count) {
-    // LOGD("ENTER writeSocketDirectImpl");
-
     if (count <= 0) {
         return 0;
     }
@@ -1546,25 +1568,21 @@
     return bytesSent;
 }
 
-static jint osNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_write(JNIEnv* env, jobject,
         jobject fileDescriptor, jbyteArray byteArray, jint offset, jint count) {
-    // LOGD("ENTER writeSocketImpl");
-
     jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
     if (bytes == NULL) {
         return -1;
     }
     jint address = static_cast<jint>(reinterpret_cast<uintptr_t>(bytes));
-    int result = osNetworkSystem_writeSocketDirectImpl(env, clazz,
+    int result = osNetworkSystem_writeDirect(env, NULL,
             fileDescriptor, address, offset, count);
     env->ReleaseByteArrayElements(byteArray, bytes, 0);
     return result;
 }
 
-static void osNetworkSystem_setNonBlockingImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_setNonBlocking(JNIEnv* env, jobject,
         jobject fileDescriptor, jboolean nonblocking) {
-    // LOGD("ENTER setNonBlockingImpl");
-
     int handle;
     if (!jniGetFd(env, fileDescriptor, handle)) {
         return;
@@ -1577,11 +1595,9 @@
     }
 }
 
-static jint osNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jint timeout, jint trafficClass,
+static jint osNetworkSystem_connectWithTimeout(JNIEnv* env,
+        jobject, jobject fileDescriptor, jint timeout, jint trafficClass,
         jobject inetAddr, jint port, jint step, jbyteArray passContext) {
-    // LOGD("ENTER connectWithTimeoutSocketImpl");
-
     sockaddr_storage address;
     if (!inetAddressToSocketAddress(env, inetAddr, port, &address)) {
         return -1;
@@ -1626,11 +1642,9 @@
     return result;
 }
 
-static void osNetworkSystem_connectStreamWithTimeoutSocketImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jint remotePort, jint timeout,
+static void osNetworkSystem_connectStreamWithTimeoutSocket(JNIEnv* env,
+        jobject, jobject fileDescriptor, jint remotePort, jint timeout,
         jint trafficClass, jobject inetAddr) {
-    // LOGD("ENTER connectStreamWithTimeoutSocketImpl");
-
     int result = 0;
     struct sockaddr_storage address;
     jbyte *context = NULL;
@@ -1760,10 +1774,8 @@
     }
 }
 
-static void osNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jint port, jobject inetAddress) {
-    // LOGD("ENTER socketBindImpl");
-
+static void osNetworkSystem_bind(JNIEnv* env, jobject, jobject fileDescriptor,
+        jobject inetAddress, jint port) {
     sockaddr_storage socketAddress;
     if (!inetAddressToSocketAddress(env, inetAddress, port, &socketAddress)) {
         return;
@@ -1774,65 +1786,26 @@
         return;
     }
 
-    sockaddr_storage tmp;
-    const sockaddr* realAddress = convertIpv4ToMapped(fd, &socketAddress, &tmp, false);
-    int rc = TEMP_FAILURE_RETRY(bind(fd, realAddress, sizeof(sockaddr_storage)));
+    const CompatibleSocketAddress compatibleAddress(fd, socketAddress, false);
+    int rc = TEMP_FAILURE_RETRY(bind(fd, compatibleAddress.get(), sizeof(sockaddr_storage)));
     if (rc == -1) {
         jniThrowBindException(env, errno);
     }
 }
 
-static void osNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jint backlog) {
-    // LOGD("ENTER listenStreamSocketImpl");
-
-    int handle;
-    if (!jniGetFd(env, fileDescriptor, handle)) {
+static void osNetworkSystem_listen(JNIEnv* env, jobject, jobject fileDescriptor, jint backlog) {
+    int fd;
+    if (!jniGetFd(env, fileDescriptor, fd)) {
         return;
     }
 
-    int rc = listen(handle, backlog);
+    int rc = listen(fd, backlog);
     if (rc == -1) {
         jniThrowSocketException(env, errno);
-        return;
     }
 }
 
-static jint osNetworkSystem_availableStreamImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor) {
-    // LOGD("ENTER availableStreamImpl");
-
-    int handle;
-    if (!jniGetFd(env, fileDescriptor, handle)) {
-        return 0;
-    }
-
-    int result;
-    do {
-        result = selectWait(handle, 1);
-
-        if (SOCKERR_TIMEOUT == result) {
-            // The read operation timed out, so answer 0 bytes available
-            return 0;
-        } else if (SOCKERR_INTERRUPTED == result) {
-            continue;
-        } else if (0 > result) {
-            throwSocketException(env, result);
-            return 0;
-        }
-    } while (SOCKERR_INTERRUPTED == result);
-
-    char message[2048];
-    result = recv(handle, (jbyte *) message, sizeof(message), MSG_PEEK);
-
-    if (0 > result) {
-        jniThrowSocketException(env, errno);
-        return 0;
-    }
-    return result;
-}
-
-static void osNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass,
+static void osNetworkSystem_accept(JNIEnv* env, jobject,
         jobject serverFileDescriptor,
         jobject newSocket, jobject clientFileDescriptor, jint timeout) {
     // LOGD("ENTER acceptSocketImpl");
@@ -1883,19 +1856,15 @@
     jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd);
 }
 
-static jboolean osNetworkSystem_supportsUrgentDataImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor) {
-    // LOGD("ENTER supportsUrgentDataImpl");
-
+static jboolean osNetworkSystem_supportsUrgentData(JNIEnv* env,
+        jobject, jobject fileDescriptor) {
     // TODO(enh): do we really need to exclude the invalid file descriptor case?
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
     return (fd == -1) ? JNI_FALSE : JNI_TRUE;
 }
 
-static void osNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_sendUrgentData(JNIEnv* env, jobject,
         jobject fileDescriptor, jbyte value) {
-    // LOGD("ENTER sendUrgentDataImpl");
-
     int handle;
     if (!jniGetFd(env, fileDescriptor, handle)) {
         return;
@@ -1907,10 +1876,8 @@
     }
 }
 
-static void osNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass,
+static void osNetworkSystem_connectDatagram(JNIEnv* env, jobject,
         jobject fileDescriptor, jint port, jint trafficClass, jobject inetAddress) {
-    // LOGD("ENTER connectDatagramImpl2");
-
     sockaddr_storage sockAddr;
     if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) {
         return;
@@ -1927,36 +1894,32 @@
     }
 }
 
-static void osNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass,
+static void osNetworkSystem_disconnectDatagram(JNIEnv* env, jobject,
         jobject fileDescriptor) {
-    // LOGD("ENTER disconnectDatagramImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return;
     }
 
-    sockaddr_storage sockAddr;
-    memset(&sockAddr, 0, sizeof(sockAddr));
-    sockAddr.ss_family = AF_UNSPEC;
-
-    int result = doConnect(fd, &sockAddr);
-    if (result < 0) {
+    // To disconnect a datagram socket, we connect to a bogus address with
+    // the family AF_UNSPEC.
+    sockaddr_storage ss;
+    memset(&ss, 0, sizeof(ss));
+    ss.ss_family = AF_UNSPEC;
+    const sockaddr* sa = reinterpret_cast<const sockaddr*>(&ss);
+    int rc = TEMP_FAILURE_RETRY(connect(fd, sa, sizeof(ss)));
+    if (rc == -1) {
         jniThrowSocketException(env, errno);
     }
 }
 
-static void osNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject,
+static void osNetworkSystem_setInetAddress(JNIEnv* env, jobject,
         jobject sender, jbyteArray address) {
-    // LOGD("ENTER setInetAddressImpl");
-    
     env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address);
 }
 
-static jint osNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_peekDatagram(JNIEnv* env, jobject,
         jobject fileDescriptor, jobject sender, jint receiveTimeout) {
-    // LOGD("ENTER peekDatagramImpl");
-
     int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
     if (result < 0) {
         return 0;
@@ -1983,15 +1946,13 @@
     if (sender == NULL) {
         return -1;
     }
-    osNetworkSystem_setInetAddressImpl(env, NULL, sender, senderAddressArray);
+    osNetworkSystem_setInetAddress(env, NULL, sender, senderAddressArray);
     return getSocketAddressPort(&sockAddr);
 }
 
-static jint osNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_receiveDatagramDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jobject packet, jint address, jint offset,
         jint length, jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveDatagramDirectImpl");
-
     int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
     if (result < 0) {
         return 0;
@@ -2031,11 +1992,9 @@
     return (jint) actualLength;
 }
 
-static jint osNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_receiveDatagram(JNIEnv* env, jobject,
         jobject fd, jobject packet, jbyteArray data, jint offset, jint length,
         jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveDatagramImpl");
-
     int localLength = (length < 65536) ? length : 65536;
     jbyte *bytes = (jbyte*) malloc(localLength);
     if (bytes == NULL) {
@@ -2044,7 +2003,7 @@
         return 0;
     }
 
-    int actualLength = osNetworkSystem_receiveDatagramDirectImpl(env, clazz, fd,
+    int actualLength = osNetworkSystem_receiveDatagramDirect(env, NULL, fd,
             packet, (jint)bytes, 0, localLength, receiveTimeout, peek);
 
     if (actualLength > 0) {
@@ -2055,11 +2014,10 @@
     return actualLength;
 }
 
-static jint osNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jobject packet,
+static jint osNetworkSystem_recvConnectedDatagramDirect(JNIEnv* env,
+        jobject, jobject fileDescriptor, jobject packet,
         jint address, jint offset, jint length,
         jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveConnectedDatagramDirectImpl");
 
     int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
     if (result < 0) {
@@ -2085,11 +2043,9 @@
     return actualLength;
 }
 
-static jint osNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_recvConnectedDatagram(JNIEnv* env, jobject,
         jobject fd, jobject packet, jbyteArray data, jint offset, jint length,
         jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveConnectedDatagramImpl");
-
     int localLength = (length < 65536) ? length : 65536;
     jbyte *bytes = (jbyte*) malloc(localLength);
     if (bytes == NULL) {
@@ -2098,8 +2054,8 @@
         return 0;
     }
 
-    int actualLength = osNetworkSystem_recvConnectedDatagramDirectImpl(env,
-            clazz, fd, packet, (jint)bytes, 0, localLength,
+    int actualLength = osNetworkSystem_recvConnectedDatagramDirect(env,
+            NULL, fd, packet, (jint)bytes, 0, localLength,
             receiveTimeout, peek);
 
     if (actualLength > 0) {
@@ -2110,12 +2066,10 @@
     return actualLength;
 }
 
-static jint osNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendDatagramDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jint address, jint offset, jint length,
         jint port,
         jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
-    // LOGD("ENTER sendDatagramDirectImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return -1;
@@ -2141,26 +2095,21 @@
     return bytesSent;
 }
 
-static jint osNetworkSystem_sendDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendDatagram(JNIEnv* env, jobject,
         jobject fd, jbyteArray data, jint offset, jint length, jint port,
         jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
-    // LOGD("ENTER sendDatagramImpl");
-
     jbyte *bytes = env->GetByteArrayElements(data, NULL);
-    int actualLength = osNetworkSystem_sendDatagramDirectImpl(env, clazz, fd,
+    int actualLength = osNetworkSystem_sendDatagramDirect(env, NULL, fd,
             (jint)bytes, offset, length, port, bindToDevice, trafficClass,
             inetAddress);
     env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
-
     return actualLength;
 }
 
-static jint osNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor,
+static jint osNetworkSystem_sendConnectedDatagramDirect(JNIEnv* env,
+        jobject, jobject fileDescriptor,
         jint address, jint offset, jint length,
         jboolean bindToDevice) {
-    // LOGD("ENTER sendConnectedDatagramDirectImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return 0;
@@ -2179,30 +2128,25 @@
     return bytesSent;
 }
 
-static jint osNetworkSystem_sendConnectedDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendConnectedDatagram(JNIEnv* env, jobject,
         jobject fd, jbyteArray data, jint offset, jint length,
         jboolean bindToDevice) {
-    // LOGD("ENTER sendConnectedDatagramImpl");
-
     jbyte *bytes = env->GetByteArrayElements(data, NULL);
-    int actualLength = osNetworkSystem_sendConnectedDatagramDirectImpl(env,
-            clazz, fd, (jint)bytes, offset, length, bindToDevice);
+    int actualLength = osNetworkSystem_sendConnectedDatagramDirect(env,
+            NULL, fd, (jint)bytes, offset, length, bindToDevice);
     env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
 
     return actualLength;
 }
 
-static void osNetworkSystem_createServerStreamSocketImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) {
-    // LOGD("ENTER createServerStreamSocketImpl");
-
-    int handle = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
-    if (handle < 0) {
-        return;
+static void osNetworkSystem_createServerStreamSocket(JNIEnv* env, jobject,
+        jobject fileDescriptor, jboolean) {
+    int fd = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
+    if (fd != -1) {
+        // TODO: we could actually do this in Java. (and check for errors!)
+        int value = 1;
+        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
     }
-
-    int value = 1;
-    setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
 }
 
 static void doShutdown(JNIEnv* env, jobject fileDescriptor, int how) {
@@ -2216,21 +2160,17 @@
     }
 }
 
-static void osNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject,
-        jobject fileDescriptor) {
-    doShutdown(env, fileDescriptor, SHUT_RD);
+static void osNetworkSystem_shutdownInput(JNIEnv* env, jobject, jobject fd) {
+    doShutdown(env, fd, SHUT_RD);
 }
 
-static void osNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject,
-        jobject fileDescriptor) {
-    doShutdown(env, fileDescriptor, SHUT_WR);
+static void osNetworkSystem_shutdownOutput(JNIEnv* env, jobject, jobject fd) {
+    doShutdown(env, fd, SHUT_WR);
 }
 
-static jint osNetworkSystem_sendDatagramImpl2(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendDatagram2(JNIEnv* env, jobject,
         jobject fileDescriptor, jbyteArray data, jint offset, jint length,
         jint port, jobject inetAddress) {
-    // LOGD("ENTER sendDatagramImpl2");
-
     sockaddr_storage sockAddr;
     if (inetAddress != NULL) {
         if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) {
@@ -2271,6 +2211,10 @@
     return totalBytesSent;
 }
 
+static bool isValidFd(int fd) {
+    return fd >= 0 && fd < FD_SETSIZE;
+}
+
 static bool initFdSet(JNIEnv* env, jobjectArray fdArray, jint count, fd_set* fdSet, int* maxFd) {
     for (int i = 0; i < count; ++i) {
         jobject fileDescriptor = env->GetObjectArrayElement(fdArray, i);
@@ -2279,7 +2223,7 @@
         }
         
         const int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-        if (fd < 0 || fd > 1024) {
+        if (!isValidFd(fd)) {
             LOGE("selectImpl: ignoring invalid fd %i", fd);
             continue;
         }
@@ -2307,9 +2251,7 @@
         }
         
         const int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-        const bool valid = fd >= 0 && fd < 1024;
-
-        if (valid && FD_ISSET(fd, &fdSet)) {
+        if (isValidFd(fd) && FD_ISSET(fd, &fdSet)) {
             flagArray[i + offset] = op;
         } else {
             flagArray[i + offset] = SOCKET_OP_NONE;
@@ -2318,7 +2260,7 @@
     return true;
 }
 
-static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass clazz,
+static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass,
         jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC,
         jint countWriteC, jintArray outFlags, jlong timeoutMs) {
     // LOGD("ENTER selectImpl");
@@ -2369,10 +2311,8 @@
     return okay;
 }
 
-static jobject osNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env,
-        jclass, jobject fileDescriptor) {
-    // LOGD("ENTER getSocketLocalAddressImpl");
-
+static jobject osNetworkSystem_getSocketLocalAddress(JNIEnv* env,
+        jobject, jobject fileDescriptor) {
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return NULL;
@@ -2392,10 +2332,8 @@
     return socketAddressToInetAddress(env, &addr);
 }
 
-static jint osNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass,
+static jint osNetworkSystem_getSocketLocalPort(JNIEnv* env, jobject,
         jobject fileDescriptor) {
-    // LOGD("ENTER getSocketLocalPortImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return 0;
@@ -2415,10 +2353,8 @@
     return getSocketAddressPort(&addr);
 }
 
-static jobject osNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz,
+static jobject osNetworkSystem_getSocketOption(JNIEnv* env, jobject,
         jobject fileDescriptor, jint anOption) {
-    // LOGD("ENTER getSocketOptionImpl");
-
     int intValue = 0;
     socklen_t intSize = sizeof(int);
     int result;
@@ -2630,10 +2566,8 @@
 
 }
 
-static void osNetworkSystem_setSocketOptionImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_setSocketOption(JNIEnv* env, jobject,
         jobject fileDescriptor, jint anOption, jobject optVal) {
-    // LOGD("ENTER setSocketOptionImpl");
-
     int result;
     int intVal;
     socklen_t intSize = sizeof(int);
@@ -2888,17 +2822,7 @@
     }
 }
 
-static jint osNetworkSystem_getSocketFlagsImpl(JNIEnv* env, jclass clazz) {
-    // LOGD("ENTER getSocketFlagsImpl");
-
-    // Not implemented by harmony
-    return 0;
-}
-
-static void osNetworkSystem_socketCloseImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor) {
-    // LOGD("ENTER socketCloseImpl");
-
+static void osNetworkSystem_socketClose(JNIEnv* env, jobject, jobject fileDescriptor) {
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return;
@@ -2909,63 +2833,48 @@
     close(fd);
 }
 
-static jobject osNetworkSystem_inheritedChannel(JNIEnv* env, jobject obj) {
-    // Android never has stdin/stdout connected to a socket.
-    return NULL;
-}
-
-/*
- * JNI registration.
- */
 static JNINativeMethod gMethods[] = {
-    /* name, signature, funcPtr */
-    { "createStreamSocketImpl",            "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createStreamSocketImpl             },
-    { "createDatagramSocketImpl",          "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createDatagramSocketImpl           },
-    { "readSocketImpl",                    "(Ljava/io/FileDescriptor;[BIII)I",                                         (void*) osNetworkSystem_readSocketImpl                     },
-    { "readSocketDirectImpl",              "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_readSocketDirectImpl               },
-    { "writeSocketImpl",                   "(Ljava/io/FileDescriptor;[BII)I",                                          (void*) osNetworkSystem_writeSocketImpl                    },
-    { "writeSocketDirectImpl",             "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_writeSocketDirectImpl              },
-    { "setNonBlockingImpl",                "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_setNonBlockingImpl                 },
-    { "connectWithTimeoutSocketImpl",      "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I",                  (void*) osNetworkSystem_connectWithTimeoutSocketImpl       },
-    { "connectStreamWithTimeoutSocketImpl","(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V",                     (void*) osNetworkSystem_connectStreamWithTimeoutSocketImpl },
-    { "socketBindImpl",                    "(Ljava/io/FileDescriptor;ILjava/net/InetAddress;)V",                       (void*) osNetworkSystem_socketBindImpl                     },
-    { "listenStreamSocketImpl",            "(Ljava/io/FileDescriptor;I)V",                                             (void*) osNetworkSystem_listenStreamSocketImpl             },
-    { "availableStreamImpl",               "(Ljava/io/FileDescriptor;)I",                                              (void*) osNetworkSystem_availableStreamImpl                },
-    { "acceptSocketImpl",                  "(Ljava/io/FileDescriptor;Ljava/net/SocketImpl;Ljava/io/FileDescriptor;I)V",(void*) osNetworkSystem_acceptSocketImpl                   },
-    { "supportsUrgentDataImpl",            "(Ljava/io/FileDescriptor;)Z",                                              (void*) osNetworkSystem_supportsUrgentDataImpl             },
-    { "sendUrgentDataImpl",                "(Ljava/io/FileDescriptor;B)V",                                             (void*) osNetworkSystem_sendUrgentDataImpl                 },
-    { "connectDatagramImpl2",              "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V",                      (void*) osNetworkSystem_connectDatagramImpl2               },
-    { "disconnectDatagramImpl",            "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_disconnectDatagramImpl             },
-    { "peekDatagramImpl",                  "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I",                       (void*) osNetworkSystem_peekDatagramImpl                   },
-    { "receiveDatagramImpl",               "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_receiveDatagramImpl                },
-    { "receiveDatagramDirectImpl",         "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_receiveDatagramDirectImpl          },
-    { "recvConnectedDatagramImpl",         "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_recvConnectedDatagramImpl          },
-    { "recvConnectedDatagramDirectImpl",   "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_recvConnectedDatagramDirectImpl    },
-    { "sendDatagramImpl",                  "(Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I",                 (void*) osNetworkSystem_sendDatagramImpl                   },
-    { "sendDatagramDirectImpl",            "(Ljava/io/FileDescriptor;IIIIZILjava/net/InetAddress;)I",                  (void*) osNetworkSystem_sendDatagramDirectImpl             },
-    { "sendConnectedDatagramImpl",         "(Ljava/io/FileDescriptor;[BIIZ)I",                                         (void*) osNetworkSystem_sendConnectedDatagramImpl          },
-    { "sendConnectedDatagramDirectImpl",   "(Ljava/io/FileDescriptor;IIIZ)I",                                          (void*) osNetworkSystem_sendConnectedDatagramDirectImpl    },
-    { "createServerStreamSocketImpl",      "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createServerStreamSocketImpl       },
-    { "shutdownInputImpl",                 "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownInputImpl                  },
-    { "shutdownOutputImpl",                "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownOutputImpl                 },
-    { "sendDatagramImpl2",                 "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I",                   (void*) osNetworkSystem_sendDatagramImpl2                  },
-    { "selectImpl",                        "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z",               (void*) osNetworkSystem_selectImpl                         },
-    { "getSocketLocalAddressImpl",         "(Ljava/io/FileDescriptor;)Ljava/net/InetAddress;",                         (void*) osNetworkSystem_getSocketLocalAddressImpl          },
-    { "getSocketLocalPortImpl",            "(Ljava/io/FileDescriptor;)I",                                              (void*) osNetworkSystem_getSocketLocalPortImpl             },
-    { "getSocketOptionImpl",               "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;",                            (void*) osNetworkSystem_getSocketOptionImpl                },
-    { "setSocketOptionImpl",               "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V",                           (void*) osNetworkSystem_setSocketOptionImpl                },
-    { "getSocketFlagsImpl",                "()I",                                                                      (void*) osNetworkSystem_getSocketFlagsImpl                 },
-    { "socketCloseImpl",                   "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_socketCloseImpl                    },
-    { "setInetAddressImpl",                "(Ljava/net/InetAddress;[B)V",                                              (void*) osNetworkSystem_setInetAddressImpl                 },
-    { "inheritedChannel",                  "()Ljava/nio/channels/Channel;",                                            (void*) osNetworkSystem_inheritedChannel                   },
-    { "byteArrayToIpString",               "([B)Ljava/lang/String;",                                                   (void*) osNetworkSystem_byteArrayToIpString                },
-    { "ipStringToByteArray",               "(Ljava/lang/String;)[B",                                                   (void*) osNetworkSystem_ipStringToByteArray                },
+    { "accept",                            "(Ljava/io/FileDescriptor;Ljava/net/SocketImpl;Ljava/io/FileDescriptor;I)V",(void*) osNetworkSystem_accept },
+    { "bind",                              "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V",                       (void*) osNetworkSystem_bind },
+    { "byteArrayToIpString",               "([B)Ljava/lang/String;",                                                   (void*) osNetworkSystem_byteArrayToIpString },
+    { "connectDatagram",                   "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V",                      (void*) osNetworkSystem_connectDatagram },
+    { "connectStreamWithTimeoutSocket",    "(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V",                     (void*) osNetworkSystem_connectStreamWithTimeoutSocket },
+    { "connectWithTimeout",                "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I",                  (void*) osNetworkSystem_connectWithTimeout },
+    { "createDatagramSocket",              "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createDatagramSocket },
+    { "createServerStreamSocket",          "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createServerStreamSocket },
+    { "createStreamSocket",                "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createStreamSocket },
+    { "disconnectDatagram",                "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_disconnectDatagram },
+    { "getSocketLocalAddress",             "(Ljava/io/FileDescriptor;)Ljava/net/InetAddress;",                         (void*) osNetworkSystem_getSocketLocalAddress },
+    { "getSocketLocalPort",                "(Ljava/io/FileDescriptor;)I",                                              (void*) osNetworkSystem_getSocketLocalPort },
+    { "getSocketOption",                   "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;",                            (void*) osNetworkSystem_getSocketOption },
+    { "ipStringToByteArray",               "(Ljava/lang/String;)[B",                                                   (void*) osNetworkSystem_ipStringToByteArray },
+    { "listen",                            "(Ljava/io/FileDescriptor;I)V",                                             (void*) osNetworkSystem_listen },
+    { "peekDatagram",                      "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I",                       (void*) osNetworkSystem_peekDatagram },
+    { "readDirect",                        "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_readDirect },
+    { "readSocketImpl",                    "(Ljava/io/FileDescriptor;[BIII)I",                                         (void*) osNetworkSystem_readSocketImpl },
+    { "receiveDatagramDirect",             "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_receiveDatagramDirect },
+    { "receiveDatagram",                   "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_receiveDatagram },
+    { "recvConnectedDatagramDirect",       "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_recvConnectedDatagramDirect },
+    { "recvConnectedDatagram",             "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_recvConnectedDatagram },
+    { "selectImpl",                        "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z",               (void*) osNetworkSystem_selectImpl },
+    { "sendConnectedDatagramDirect",       "(Ljava/io/FileDescriptor;IIIZ)I",                                          (void*) osNetworkSystem_sendConnectedDatagramDirect },
+    { "sendConnectedDatagram",             "(Ljava/io/FileDescriptor;[BIIZ)I",                                         (void*) osNetworkSystem_sendConnectedDatagram },
+    { "sendDatagramDirect",                "(Ljava/io/FileDescriptor;IIIIZILjava/net/InetAddress;)I",                  (void*) osNetworkSystem_sendDatagramDirect },
+    { "sendDatagram",                      "(Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I",                 (void*) osNetworkSystem_sendDatagram },
+    { "sendDatagram2",                     "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I",                   (void*) osNetworkSystem_sendDatagram2 },
+    { "sendUrgentData",                    "(Ljava/io/FileDescriptor;B)V",                                             (void*) osNetworkSystem_sendUrgentData },
+    { "setInetAddress",                    "(Ljava/net/InetAddress;[B)V",                                              (void*) osNetworkSystem_setInetAddress },
+    { "setNonBlocking",                    "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_setNonBlocking },
+    { "setSocketOption",                   "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V",                           (void*) osNetworkSystem_setSocketOption },
+    { "shutdownInput",                     "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownInput },
+    { "shutdownOutput",                    "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownOutput },
+    { "socketClose",                       "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_socketClose },
+    { "supportsUrgentData",                "(Ljava/io/FileDescriptor;)Z",                                              (void*) osNetworkSystem_supportsUrgentData },
+    { "writeDirect",                       "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_writeDirect },
+    { "write",                             "(Ljava/io/FileDescriptor;[BII)I",                                          (void*) osNetworkSystem_write },
 };
-
 int register_org_apache_harmony_luni_platform_OSNetworkSystem(JNIEnv* env) {
     return initCachedFields(env) && jniRegisterNativeMethods(env,
-            "org/apache/harmony/luni/platform/OSNetworkSystem",
-            gMethods,
-            NELEM(gMethods));
+            "org/apache/harmony/luni/platform/OSNetworkSystem", gMethods, NELEM(gMethods));
 }
 // END android-changed
diff --git a/luni/src/main/native/org_apache_harmony_luni_util_NumberConvert.c b/luni/src/main/native/org_apache_harmony_luni_util_NumberConvert.c
index 70761fb..496fe6f 100644
--- a/luni/src/main/native/org_apache_harmony_luni_util_NumberConvert.c
+++ b/luni/src/main/native/org_apache_harmony_luni_util_NumberConvert.c
@@ -271,21 +271,13 @@
 
   fid = (*env)->GetFieldID (env, clazz, "firstK", "I");
   (*env)->SetIntField (env, inst, fid, firstK);
-
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* NAME,                          SIGNATURE,               FUNCPTR */
     { "bigIntDigitGeneratorInstImpl", "(JIZZI)V"              ,
         Java_org_apache_harmony_luni_util_NumberConverter_bigIntDigitGeneratorInstImpl },
 };
-
-int register_org_apache_harmony_luni_util_NumberConvert(JNIEnv *env)
-{
-    return jniRegisterNativeMethods(env,
-               "org/apache/harmony/luni/util/NumberConverter",
+int register_org_apache_harmony_luni_util_NumberConvert(JNIEnv *env) {
+    return jniRegisterNativeMethods(env, "org/apache/harmony/luni/util/NumberConverter",
                 gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c b/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
index 80f2bee..daef934 100644
--- a/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
+++ b/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
@@ -589,19 +589,13 @@
   return 0.0;
 }
 
-/*
- * JNI registration
- */
 static JNINativeMethod gMethods[] = {
-    /* NAME,          SIGNATURE,                FUNCPTR */
     { "parseFltImpl", "(Ljava/lang/String;I)F",
         Java_org_apache_harmony_luni_util_FloatingPointParser_parseFltImpl },
     { "parseDblImpl", "(Ljava/lang/String;I)D",
         Java_org_apache_harmony_luni_util_FloatingPointParser_parseDblImpl },
 };
-int register_org_apache_harmony_luni_util_fltparse(JNIEnv *env)
-{
-    return jniRegisterNativeMethods(env,
-               "org/apache/harmony/luni/util/FloatingPointParser",
+int register_org_apache_harmony_luni_util_fltparse(JNIEnv *env) {
+    return jniRegisterNativeMethods(env, "org/apache/harmony/luni/util/FloatingPointParser",
                 gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index f0287cf..a562e4c 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -3,6 +3,7 @@
 # or BUILD_*_LIBRARY.
 
 LOCAL_SRC_FILES := \
+	java_io_Console.cpp \
 	java_io_File.cpp \
 	java_io_FileDescriptor.c \
 	java_io_ObjectInputStream.c \
diff --git a/luni/src/test/java/com/google/coretests/XmlReportPrinter.java b/luni/src/test/java/com/google/coretests/XmlReportPrinter.java
index edd9a12..f098b3a 100644
--- a/luni/src/test/java/com/google/coretests/XmlReportPrinter.java
+++ b/luni/src/test/java/com/google/coretests/XmlReportPrinter.java
@@ -225,7 +225,7 @@
                 serializer.attribute(ns, ATTR_MESSAGE, t.getMessage());
             }
             serializer.attribute(ns, ATTR_TYPE, t.getClass().getName());
-            serializer.text(BaseTestRunner.getFilteredTrace(t));
+            serializer.text(sanitize(BaseTestRunner.getFilteredTrace(t)));
             serializer.endTag(ns, type);
 
             serializer.endTag(ns, TESTCASE);
@@ -246,5 +246,12 @@
         @Override public int hashCode() {
             return name.hashCode() ^ className.hashCode();
         }
+
+        /**
+         * Returns the text in a format that is safe for use in an XML document.
+         */
+        private static String sanitize(String text) {
+            return text.replace("\0", "<\\0>");
+        }
     }
 }
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java b/luni/src/test/java/com/ibm/icu4jni/util/AllTests.java
similarity index 85%
rename from icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
rename to luni/src/test/java/com/ibm/icu4jni/util/AllTests.java
index 1b95075..2db1dcc 100644
--- a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
+++ b/luni/src/test/java/com/ibm/icu4jni/util/AllTests.java
@@ -21,8 +21,8 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
-        suite.addTestSuite(com.ibm.icu4jni.util.ResourcesTest.class);
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(ICUTest.class);
         return suite;
     }
 }
diff --git a/luni/src/test/java/com/ibm/icu4jni/util/ICUTest.java b/luni/src/test/java/com/ibm/icu4jni/util/ICUTest.java
new file mode 100644
index 0000000..f8797b3
--- /dev/null
+++ b/luni/src/test/java/com/ibm/icu4jni/util/ICUTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.ibm.icu4jni.util;
+
+import java.util.Locale;
+
+public class ICUTest extends junit.framework.TestCase {
+    public void test_getISOLanguages() throws Exception {
+        // Check that corrupting our array doesn't affect other callers.
+        assertNotNull(ICU.getISOLanguages()[0]);
+        ICU.getISOLanguages()[0] = null;
+        assertNotNull(ICU.getISOLanguages()[0]);
+    }
+
+    public void test_getISOCountries() throws Exception {
+        // Check that corrupting our array doesn't affect other callers.
+        assertNotNull(ICU.getISOCountries()[0]);
+        ICU.getISOCountries()[0] = null;
+        assertNotNull(ICU.getISOCountries()[0]);
+    }
+
+    public void test_getAvailableLocales() throws Exception {
+        // Check that corrupting our array doesn't affect other callers.
+        assertNotNull(ICU.getAvailableLocales()[0]);
+        ICU.getAvailableLocales()[0] = null;
+        assertNotNull(ICU.getAvailableLocales()[0]);
+    }
+
+    public void test_getKnownTimezones() throws Exception {
+        // Check that corrupting our array doesn't affect other callers.
+        assertNotNull(ICU.getKnownTimezones()[0]);
+        ICU.getKnownTimezones()[0] = null;
+        assertNotNull(ICU.getKnownTimezones()[0]);
+    }
+
+    public void test_getDisplayTimeZones() throws Exception {
+        // Check that corrupting our array doesn't affect other callers.
+        assertNotNull(ICU.getDisplayTimeZones(null)[0]);
+        ICU.getDisplayTimeZones(null)[0] = null;
+        assertNotNull(ICU.getDisplayTimeZones(null)[0]);
+        // getDisplayTimezones actually returns a String[][] rather than a String[].
+        assertNotNull(ICU.getDisplayTimeZones(null)[0][0]);
+        ICU.getDisplayTimeZones(null)[0][0] = null;
+        assertNotNull(ICU.getDisplayTimeZones(null)[0][0]);
+    }
+
+    public void test_localeFromString() throws Exception {
+        // localeFromString is pretty lenient. Some of these can't be round-tripped
+        // through Locale.toString.
+        assertEquals(Locale.ENGLISH, ICU.localeFromString("en"));
+        assertEquals(Locale.ENGLISH, ICU.localeFromString("en_"));
+        assertEquals(Locale.ENGLISH, ICU.localeFromString("en__"));
+        assertEquals(Locale.US, ICU.localeFromString("en_US"));
+        assertEquals(Locale.US, ICU.localeFromString("en_US_"));
+        assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US"));
+        assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US_"));
+        assertEquals(new Locale("", "", "POSIX"), ICU.localeFromString("__POSIX"));
+        assertEquals(new Locale("aa", "BB", "CC"), ICU.localeFromString("aa_BB_CC"));
+    }
+}
diff --git a/luni/src/test/java/java/io/AllTests.java b/luni/src/test/java/java/io/AllTests.java
index 5e25922..43a28e0 100644
--- a/luni/src/test/java/java/io/AllTests.java
+++ b/luni/src/test/java/java/io/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(java.io.FileTest.class);
         return suite;
     }
diff --git a/luni/src/test/java/java/io/FileTest.java b/luni/src/test/java/java/io/FileTest.java
index 0518c26..423b404 100644
--- a/luni/src/test/java/java/io/FileTest.java
+++ b/luni/src/test/java/java/io/FileTest.java
@@ -78,6 +78,7 @@
         // The behavior of the empty filename is an odd mixture.
         File f = new File("");
         // Mostly it behaves like an invalid path...
+        assertFalse(f.canExecute());
         assertFalse(f.canRead());
         assertFalse(f.canWrite());
         try {
@@ -107,7 +108,10 @@
         assertFalse(f.mkdirs());
         assertFalse(f.renameTo(f));
         assertFalse(f.setLastModified(123));
+        assertFalse(f.setExecutable(true));
         assertFalse(f.setReadOnly());
+        assertFalse(f.setReadable(true));
+        assertFalse(f.setWritable(true));
         // ...but sometimes it behaves like "user.dir".
         String cwd = System.getProperty("user.dir");
         assertEquals(new File(cwd), f.getAbsoluteFile());
diff --git a/luni/src/test/java/java/lang/AllTests.java b/luni/src/test/java/java/lang/AllTests.java
index a40ef3a..f1c1c72 100644
--- a/luni/src/test/java/java/lang/AllTests.java
+++ b/luni/src/test/java/java/lang/AllTests.java
@@ -21,9 +21,11 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(java.lang.FloatTest.class);
         suite.addTestSuite(java.lang.ProcessBuilderTest.class);
+        suite.addTestSuite(StringTest.class);
+        suite.addTestSuite(SystemTest.class);
         return suite;
     }
 }
diff --git a/luni/src/test/java/java/lang/StringTest.java b/luni/src/test/java/java/lang/StringTest.java
new file mode 100644
index 0000000..300449b
--- /dev/null
+++ b/luni/src/test/java/java/lang/StringTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+public class StringTest extends TestCase {
+    public void testIsEmpty() {
+        assertTrue("".isEmpty());
+        assertFalse("x".isEmpty());
+    }
+
+    // The evil decoder keeps hold of the CharBuffer it wrote to.
+    private static final class EvilCharsetDecoder extends CharsetDecoder {
+        private static char[] chars;
+        public EvilCharsetDecoder(Charset cs) {
+            super(cs, 1.0f, 1.0f);
+        }
+        protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+            chars = out.array();
+            int inLength = in.remaining();
+            for (int i = 0; i < inLength; ++i) {
+                in.put((byte) 'X');
+                out.put('Y');
+            }
+            return CoderResult.UNDERFLOW;
+        }
+        public static void corrupt() {
+            for (int i = 0; i < chars.length; ++i) {
+                chars[i] = '$';
+            }
+        }
+    }
+
+    // The evil encoder tries to write to the CharBuffer it was given to
+    // read from.
+    private static final class EvilCharsetEncoder extends CharsetEncoder {
+        public EvilCharsetEncoder(Charset cs) {
+            super(cs, 1.0f, 1.0f);
+        }
+        protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+            int inLength = in.remaining();
+            for (int i = 0; i < inLength; ++i) {
+                in.put('x');
+                out.put((byte) 'y');
+            }
+            return CoderResult.UNDERFLOW;
+        }
+    }
+
+    private static final Charset EVIL_CHARSET = new Charset("evil", null) {
+        public boolean contains(Charset charset) { return false; }
+        public CharsetEncoder newEncoder() { return new EvilCharsetEncoder(this); }
+        public CharsetDecoder newDecoder() { return new EvilCharsetDecoder(this); }
+    };
+
+    public void testGetBytes() {
+        Charset cs = Charset.forName("UTF-8");
+        byte[] expected = new byte[] {(byte) 'h', (byte) 'i'};
+        assertTrue(Arrays.equals(expected, "hi".getBytes(cs)));
+    }
+
+    public void testGetBytes_MaliciousCharset() {
+        try {
+            String s = "hi";
+            // Check that our encoder can't write to the input CharBuffer
+            // it was given.
+            s.getBytes(EVIL_CHARSET);
+            fail(); // We shouldn't have got here!
+        } catch (ReadOnlyBufferException expected) {
+            // We caught you trying to be naughty!
+        }
+    }
+
+    public void testStringFromCharset() {
+        Charset cs = Charset.forName("UTF-8");
+        byte[] bytes = new byte[] {(byte) 'h', (byte) 'i'};
+        assertEquals("hi", new String(bytes, cs));
+    }
+
+    public void testStringFromCharset_MaliciousCharset() {
+        Charset cs = EVIL_CHARSET;
+        byte[] bytes = new byte[] {(byte) 'h', (byte) 'i'};
+        final String result = new String(bytes, cs);
+        assertEquals("YY", result); // (Our decoder always outputs 'Y's.)
+        // Check that even if the decoder messes with the output CharBuffer
+        // after we've created a string from it, it doesn't affect the string.
+        EvilCharsetDecoder.corrupt();
+        assertEquals("YY", result);
+    }
+}
diff --git a/luni/src/test/java/java/lang/SystemTest.java b/luni/src/test/java/java/lang/SystemTest.java
new file mode 100644
index 0000000..b6fc5de
--- /dev/null
+++ b/luni/src/test/java/java/lang/SystemTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.lang;
+
+import junit.framework.TestCase;
+
+public class SystemTest extends TestCase {
+
+    public void testArrayCopyTargetNotArray() {
+        try {
+            System.arraycopy(new char[5], 0, "Hello", 0, 3);
+            fail();
+        } catch (ArrayStoreException e) {
+            assertEquals("source and destination must be arrays, but were "
+                    + "[C and Ljava/lang/String;", e.getMessage());
+        }
+    }
+
+    public void testArrayCopySourceNotArray() {
+        try {
+            System.arraycopy("Hello", 0, new char[5], 0, 3);
+            fail();
+        } catch (ArrayStoreException e) {
+            assertEquals("source and destination must be arrays, but were "
+                    + "Ljava/lang/String; and [C", e.getMessage());
+        }
+    }
+
+    public void testArrayCopyArrayTypeMismatch() {
+        try {
+            System.arraycopy(new char[5], 0, new Object[5], 0, 3);
+            fail();
+        } catch (ArrayStoreException e) {
+            assertEquals("source and destination arrays are incompatible: "
+                    + "[C and [Ljava/lang/Object;", e.getMessage());
+        }
+    }
+
+    public void testArrayCopyElementTypeMismatch() {
+        try {
+            System.arraycopy(new Object[] { null, 5, "hello" }, 0,
+                    new Integer[] { 1, 2, 3, null, null }, 0, 3);
+            fail();
+        } catch (ArrayStoreException e) {
+            assertEquals("source[2] of type Ljava/lang/String; cannot be "
+                    + "stored in destination array of type [Ljava/lang/Integer;",
+                    e.getMessage());
+        }
+    }
+}
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java b/luni/src/test/java/java/math/AllTests.java
similarity index 76%
copy from icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
copy to luni/src/test/java/java/math/AllTests.java
index 1b95075..f182e01 100644
--- a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
+++ b/luni/src/test/java/java/math/AllTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.ibm.icu4jni.util;
+package java.math;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
-        suite.addTestSuite(com.ibm.icu4jni.util.ResourcesTest.class);
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(java.math.BigIntegerTest.class);
         return suite;
     }
 }
diff --git a/luni/src/test/java/java/math/BigIntegerTest.java b/luni/src/test/java/java/math/BigIntegerTest.java
new file mode 100644
index 0000000..e4dd7b1
--- /dev/null
+++ b/luni/src/test/java/java/math/BigIntegerTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.math;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+public class BigIntegerTest extends junit.framework.TestCase {
+    // http://code.google.com/p/android/issues/detail?id=7036
+    public void test_invalidBigIntegerStringConversions() {
+        // Check we don't disallow related reasonable strings...
+        new BigInteger("1", 10);
+        new BigInteger("1a", 16);
+        new BigInteger("-1", 10);
+        new BigInteger("-1a", 16);
+        new BigInteger("\u0661", 10);
+        new BigInteger("\u0661a", 16);
+        new BigInteger("-\u0661", 10);
+        new BigInteger("-\u0661a", 16);
+        // This is allowed from Java 7 on.
+        new BigInteger("+1");
+        // Now check the invalid cases...
+        try {
+            new BigInteger("-a"); // no digits from other bases.
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        try {
+            new BigInteger("-1a"); // no trailing digits from other bases.
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        try {
+            new BigInteger("-1 hello"); // no trailing junk at all.
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        try {
+            new BigInteger("--1"); // only one sign.
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        try {
+            new BigInteger(""); // at least one digit.
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+        try {
+            new BigInteger("-"); // at least one digit, even after a sign.
+            fail();
+        } catch (NumberFormatException expected) {
+        }
+    }
+}
diff --git a/luni/src/test/java/java/net/AllTests.java b/luni/src/test/java/java/net/AllTests.java
index 3731af4..226e2c3 100644
--- a/luni/src/test/java/java/net/AllTests.java
+++ b/luni/src/test/java/java/net/AllTests.java
@@ -21,9 +21,11 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
-        suite.addTestSuite(java.net.SocketTest.class);
-        suite.addTestSuite(java.net.URLConnectionTest.class);
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(IDNTest.class);
+        suite.addTestSuite(SocketTest.class);
+        suite.addTestSuite(URLConnectionTest.class);
+        suite.addTestSuite(UriTest.class);
         return suite;
     }
 }
diff --git a/luni/src/test/java/java/net/IDNTest.java b/luni/src/test/java/java/net/IDNTest.java
new file mode 100644
index 0000000..5a9bf8a
--- /dev/null
+++ b/luni/src/test/java/java/net/IDNTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class IDNTest extends junit.framework.TestCase {
+    private static String makePunyString(int xCount) {
+        StringBuilder s = new StringBuilder();
+        s.append("xn--bcher");
+        for (int i = 0; i < xCount; ++i) {
+            s.append('x');
+        }
+        s.append("-kva");
+        return s.toString();
+    }
+
+    public void test_toUnicode_failures() {
+        // This is short enough to work...
+        assertEquals("b\u00fccher", IDN.toUnicode(makePunyString(0)));
+        // This is too long, and the RI just returns the input string...
+        String longInput = makePunyString(512);
+        assertEquals(longInput, IDN.toUnicode(longInput));
+    }
+}
diff --git a/luni/src/test/java/java/net/URLConnectionTest.java b/luni/src/test/java/java/net/URLConnectionTest.java
index c5fd43f..cf23b77 100644
--- a/luni/src/test/java/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/java/net/URLConnectionTest.java
@@ -18,33 +18,27 @@
 
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
-
-import tests.support.Support_PortManager;
 import tests.support.Support_TestWebServer;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 public class URLConnectionTest extends junit.framework.TestCase {
-    private int port;
-    private Support_TestWebServer server;
+    private int mPort;
+    private Support_TestWebServer mServer;
     
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        port = Support_PortManager.getNextPort();
-        server = new Support_TestWebServer();
-        server.initServer(port, false);
+        mServer = new Support_TestWebServer();
+        mPort = mServer.initServer(0, false);
     }
     
     @Override
-    public void tearDown()throws Exception {
+    public void tearDown() throws Exception {
         super.tearDown();
-        server.close();
+        mServer.close();
     }
     
     private String readFirstLine() throws Exception {
-        URLConnection connection = new URL("http://localhost:" + port + "/test1").openConnection();
+        URLConnection connection = new URL("http://localhost:" + mPort + "/test1").openConnection();
         BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
         String result = in.readLine();
         in.close();
@@ -55,9 +49,17 @@
     // recycled connection doesn't get the unread tail of the first request's response.
     // http://code.google.com/p/android/issues/detail?id=2939
     public void test_2939() throws Exception {
-        server.setChunked(true);
-        server.setMaxChunkSize(8);
+        mServer.setChunked(true);
+        mServer.setMaxChunkSize(8);
         assertTrue(readFirstLine().equals("<html>"));
         assertTrue(readFirstLine().equals("<html>"));
+        assertEquals(1, mServer.getNumAcceptedConnections());
+    }
+
+    public void testConnectionsArePooled() throws Exception {
+        readFirstLine();
+        readFirstLine();
+        readFirstLine();
+        assertEquals(1, mServer.getNumAcceptedConnections());
     }
 }
diff --git a/luni/src/test/java/java/net/UriTest.java b/luni/src/test/java/java/net/UriTest.java
new file mode 100644
index 0000000..05da50a
--- /dev/null
+++ b/luni/src/test/java/java/net/UriTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import junit.framework.TestCase;
+
+public class UriTest extends TestCase {
+
+    /**
+     * Regression test for http://b/issue?id=2604061
+     */
+    public void testParsingDotAsHostname() throws URISyntaxException {
+        assertEquals(null, new URI("http://./").getHost());
+    }
+
+    public void testSquareBracketsWithIPv4() throws URISyntaxException {
+        try {
+            new URI("http://[192.168.0.1]/");
+            fail();
+        } catch (URISyntaxException e) {
+        }
+    }
+
+    public void testSquareBracketsWithHostname() throws URISyntaxException {
+        try {
+            new URI("http://[google.com]/");
+            fail();
+        } catch (URISyntaxException e) {
+        }
+    }
+
+    public void testIPv6WithoutSquareBrackets() throws URISyntaxException {
+        assertEquals(null, new URI("http://fe80::1234/").getHost());
+    }
+}
diff --git a/luni/src/test/java/java/nio/charset/AllTests.java b/luni/src/test/java/java/nio/charset/AllTests.java
index 6f45162..67957d4 100644
--- a/luni/src/test/java/java/nio/charset/AllTests.java
+++ b/luni/src/test/java/java/nio/charset/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(java.nio.charset.CharsetDecoderTest.class);
         return suite;
     }
diff --git a/luni/src/test/java/java/text/AllTests.java b/luni/src/test/java/java/text/AllTests.java
index efb27da..240b745 100644
--- a/luni/src/test/java/java/text/AllTests.java
+++ b/luni/src/test/java/java/text/AllTests.java
@@ -21,8 +21,11 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(java.text.CollatorTest.class);
+        suite.addTestSuite(java.text.DateFormatSymbolsTest.class);
         suite.addTestSuite(java.text.DecimalFormatTest.class);
+        suite.addTestSuite(java.text.DecimalFormatSymbolsTest.class);
         suite.addTestSuite(java.text.NormalizerTest.class);
         suite.addTestSuite(java.text.NumberFormatTest.class);
         return suite;
diff --git a/luni/src/test/java/java/text/CollatorTest.java b/luni/src/test/java/java/text/CollatorTest.java
new file mode 100644
index 0000000..5cded0a
--- /dev/null
+++ b/luni/src/test/java/java/text/CollatorTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text;
+
+import java.util.Locale;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CollatorTest extends junit.framework.TestCase {
+    public void test_setStrengthI() throws Exception {
+        Collator collator = Collator.getInstance();
+        collator.setStrength(Collator.PRIMARY);
+        assertEquals(Collator.PRIMARY, collator.getStrength());
+        collator.setStrength(Collator.SECONDARY);
+        assertEquals(Collator.SECONDARY, collator.getStrength());
+        collator.setStrength(Collator.TERTIARY);
+        assertEquals(Collator.TERTIARY, collator.getStrength());
+        collator.setStrength(Collator.IDENTICAL);
+        assertEquals(Collator.IDENTICAL, collator.getStrength());
+        try {
+            collator.setStrength(-1);
+            fail("IllegalArgumentException was not thrown.");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void test_stackCorruption() throws Exception {
+        // This used to crash Android.
+        Collator mColl = Collator.getInstance();
+        mColl.setStrength(Collator.PRIMARY);
+        mColl.getCollationKey("2d294f2d3739433565147655394f3762f3147312d3731641452f310");
+    }
+
+    public void test_collationKeySize() throws Exception {
+        // Test to verify that very large collation keys are not truncated.
+        StringBuilder b = new StringBuilder();
+        for (int i = 0; i < 1024; i++) {
+            b.append("0123456789ABCDEF");
+        }
+        String sixteen = b.toString();
+        b.append("_THE_END");
+        String sixteenplus = b.toString();
+
+        Collator mColl = Collator.getInstance();
+        mColl.setStrength(Collator.PRIMARY);
+
+        byte [] arr = mColl.getCollationKey(sixteen).toByteArray();
+        int len = arr.length;
+        assertTrue("Collation key not 0 terminated", arr[arr.length - 1] == 0);
+        len--;
+        String foo = new String(arr, 0, len, "iso8859-1");
+
+        arr = mColl.getCollationKey(sixteen).toByteArray();
+        len = arr.length;
+        assertTrue("Collation key not 0 terminated", arr[arr.length - 1] == 0);
+        len--;
+        String bar = new String(arr, 0, len, "iso8859-1");
+
+        assertTrue("Collation keys should differ", foo.equals(bar));
+    }
+
+    public void test_decompositionCompatibility() throws Exception {
+        Collator myCollator = Collator.getInstance();
+        myCollator.setDecomposition(Collator.NO_DECOMPOSITION);
+        assertFalse("Error: \u00e0\u0325 should not equal to a\u0325\u0300 without decomposition",
+                myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
+        myCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+        assertTrue("Error: \u00e0\u0325 should equal to a\u0325\u0300 with decomposition",
+                myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
+    }
+
+    public void testEqualsObject() throws ParseException {
+        String rule = "< a < b < c < d < e";
+        RuleBasedCollator coll = new RuleBasedCollator(rule);
+
+        assertEquals(Collator.TERTIARY, coll.getStrength());
+        // This is a harmony test, but it assumes that RuleBasedCollators default to
+        // NO_DECOMPOSITION, which isn't true on Android.
+        // assertEquals(Collator.NO_DECOMPOSITION, coll.getDecomposition());
+        RuleBasedCollator other = new RuleBasedCollator(rule);
+        assertTrue(coll.equals(other));
+
+        coll.setStrength(Collator.PRIMARY);
+        assertFalse(coll.equals(other));
+
+        coll.setStrength(Collator.TERTIARY);
+        coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+        other.setDecomposition(Collator.NO_DECOMPOSITION); // See comment above.
+        assertFalse(coll.equals(other));
+    }
+
+    public void test_Harmony_1352() throws Exception {
+        // Regression test for HARMONY-1352, that doesn't get run in the harmony test suite because
+        // of an earlier failure.
+        try {
+            new RuleBasedCollator("< a< b< c< d").getCollationElementIterator((CharacterIterator) null);
+            fail("NullPointerException expected");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    private void assertCollationElementIterator(CollationElementIterator it, Integer... offsets) {
+        for (int offset : offsets) {
+            assertEquals(offset, it.getOffset());
+            it.next();
+        }
+        assertEquals(CollationElementIterator.NULLORDER, it.next());
+    }
+
+    private void assertGetCollationElementIteratorString(Locale l, String s, Integer... offsets) {
+        RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(l);
+        assertCollationElementIterator(coll.getCollationElementIterator(s), offsets);
+    }
+
+    private void assertGetCollationElementIteratorCharacterIterator(Locale l, String s, Integer... offsets) {
+        RuleBasedCollator coll = (RuleBasedCollator) Collator.getInstance(l);
+        CharacterIterator it = new StringCharacterIterator(s);
+        assertCollationElementIterator(coll.getCollationElementIterator(it), offsets);
+    }
+
+    public void testGetCollationElementIteratorString() throws Exception {
+        assertGetCollationElementIteratorString(new Locale("es", "", "TRADITIONAL"), "cha", 0, 2, 3);
+        assertGetCollationElementIteratorString(new Locale("es", "", ""), "cha", 0, 1, 2, 3);
+        assertGetCollationElementIteratorString(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
+    }
+
+    public void testGetCollationElementIteratorCharacterIterator() throws Exception {
+        assertGetCollationElementIteratorCharacterIterator(new Locale("es", "", "TRADITIONAL"), "cha", 0, 2, 3);
+        assertGetCollationElementIteratorCharacterIterator(new Locale("es", "", ""), "cha", 0, 1, 2, 3);
+        assertGetCollationElementIteratorCharacterIterator(new Locale("de", "DE", ""), "\u00e6b", 0, 1, 1, 2);
+    }
+}
diff --git a/luni/src/test/java/java/text/DateFormatSymbolsTest.java b/luni/src/test/java/java/text/DateFormatSymbolsTest.java
new file mode 100644
index 0000000..56968b8
--- /dev/null
+++ b/luni/src/test/java/java/text/DateFormatSymbolsTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+public class DateFormatSymbolsTest extends junit.framework.TestCase {
+    private void assertLocaleIsEquivalentToRoot(Locale locale) {
+        DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale);
+        assertEquals(DateFormatSymbols.getInstance(Locale.ROOT), dfs);
+    }
+    public void test_getInstance_unknown_locale() throws Exception {
+        // TODO: we fail this test. on Android, the root locale uses GMT offsets as names.
+        // see the invalid locale test below. on the RI, the root locale uses English names.
+        assertLocaleIsEquivalentToRoot(new Locale("xx", "XX"));
+    }
+    public void test_getInstance_invalid_locale() throws Exception {
+        assertLocaleIsEquivalentToRoot(new Locale("not exist language", "not exist country"));
+    }
+}
diff --git a/luni/src/test/java/java/text/DecimalFormatSymbolsTest.java b/luni/src/test/java/java/text/DecimalFormatSymbolsTest.java
new file mode 100644
index 0000000..adc57f7
--- /dev/null
+++ b/luni/src/test/java/java/text/DecimalFormatSymbolsTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.math.BigInteger;
+import java.util.Locale;
+
+public class DecimalFormatSymbolsTest extends junit.framework.TestCase {
+    private void checkLocaleIsEquivalentToRoot(Locale locale) {
+        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
+        assertEquals(DecimalFormatSymbols.getInstance(Locale.ROOT), dfs);
+    }
+    public void test_getInstance_unknown_or_invalid_locale() throws Exception {
+        // TODO: we fail these tests because ROOT has "INF" for infinity but 'dfs' has "\u221e".
+        // On the RI, ROOT has "\u221e" too, but DecimalFormatSymbols.equals appears to be broken;
+        // it returns false for objects that -- if you compare their externally visible state --
+        // are equal. It could be that they're accidentally checking the Locale.
+        checkLocaleIsEquivalentToRoot(new Locale("xx", "XX"));
+        checkLocaleIsEquivalentToRoot(new Locale("not exist language", "not exist country"));
+    }
+}
diff --git a/luni/src/test/java/java/text/DecimalFormatTest.java b/luni/src/test/java/java/text/DecimalFormatTest.java
index 6b2eb3d..c3a2721 100644
--- a/luni/src/test/java/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/java/text/DecimalFormatTest.java
@@ -19,10 +19,21 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.util.Locale;
 
 public class DecimalFormatTest extends junit.framework.TestCase {
+    public void test_setMaximumFractionDigitsAffectsRoundingMode() throws Exception {
+        DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+        df.setMaximumFractionDigits(0);
+        df.setRoundingMode(RoundingMode.HALF_UP);
+        assertEquals("-0", df.format(-0.2));
+        df.setMaximumFractionDigits(1);
+        assertEquals("-0.2", df.format(-0.2));
+    }
+    
     // Android fails this test, truncating to 127 digits.
     public void test_setMaximumIntegerDigits() throws Exception {
         NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
@@ -34,4 +45,92 @@
         assertEquals(309, numberFormat.format(123).length());
         assertEquals(309, numberFormat.format(BigInteger.valueOf(123)).length());
     }
+    
+    // Regression test for http://b/1897917: BigDecimal does not take into account multiplier.
+    public void testBigDecimalBug1897917() {
+        // For example. the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%:
+        NumberFormat pf = NumberFormat.getPercentInstance();
+        assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
+        
+        // Test long decimal formatted in PercentInstance with various fractions.
+        String longDec = "11.2345678901234567890123456789012345678901234567890";
+        BigDecimal bd = new BigDecimal(longDec);
+        assertBigDecimalWithFraction(bd, "1,123.46%", 2);
+        assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
+        assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
+        assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
+        assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
+        
+        // Test trailing zeros.
+        assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
+        assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
+        assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
+        assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
+                "9,990,000,000,000,000,000,000,000,000,000,000");
+    }
+    
+    public void testBigDecimalTestBigIntWithMultiplier() {
+        // Big integer tests.
+        assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0,
+                "1,234,567,890,123,450");
+        assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
+                "123,456,789,012,345,678,900");
+        assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
+                "987,654,321,098,765,432,109,876,543,210");
+        
+        assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0,
+                "-1,234,567,890,123,450");
+        assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
+                "-123,456,789,012,345,678,900");
+        assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
+                "-987,654,321,098,765,432,109,876,543,210");
+    }
+    
+    public void testBigDecimalICUConsistency() {
+        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
+        df.setMaximumFractionDigits(2);
+        df.setMultiplier(2);
+        assertEquals(df.format(BigDecimal.valueOf(0.16)),
+        df.format(BigDecimal.valueOf(0.16).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0.0293)),
+        df.format(BigDecimal.valueOf(0.0293).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0.006)),
+        df.format(BigDecimal.valueOf(0.006).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0.00283)),
+        df.format(BigDecimal.valueOf(0.00283).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(1.60)),
+        df.format(BigDecimal.valueOf(1.60).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(15)),
+        df.format(BigDecimal.valueOf(15).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(170)),
+        df.format(BigDecimal.valueOf(170).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(234.56)),
+        df.format(BigDecimal.valueOf(234.56).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(0)),
+        df.format(BigDecimal.valueOf(0).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(-1)),
+        df.format(BigDecimal.valueOf(-1).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(-10000)),
+        df.format(BigDecimal.valueOf(-10000).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(-0.001)),
+        df.format(BigDecimal.valueOf(-0.001).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
+        df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
+        assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
+        df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+    }
+    
+    private void assertBigDecimalWithFraction(BigDecimal bd, String expectedResult, int fraction) {
+        NumberFormat pf = NumberFormat.getPercentInstance();
+        pf.setMaximumFractionDigits(fraction);
+        assertEquals(expectedResult, pf.format(bd));
+    }
+    
+    private void assertDecFmtWithMultiplierAndFraction(String value, int multiplier, int fraction, String expectedResult) {
+        DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
+        df.setMultiplier(multiplier);
+        df.setMaximumFractionDigits(fraction);
+        BigDecimal d = new BigDecimal(value);
+        assertEquals(expectedResult, df.format(d));
+    }
 }
diff --git a/luni/src/test/java/java/text/NumberFormatTest.java b/luni/src/test/java/java/text/NumberFormatTest.java
index 66e1759..5f1e0c5 100644
--- a/luni/src/test/java/java/text/NumberFormatTest.java
+++ b/luni/src/test/java/java/text/NumberFormatTest.java
@@ -68,4 +68,12 @@
         NumberFormat integerFormat = NumberFormat.getIntegerInstance(new Locale("ar"));
         assertEquals("#,##0;#,##0-", ((DecimalFormat) integerFormat).toPattern());
     }
+
+    public void test_numberLocalization() throws Exception {
+        Locale arabic = new Locale("ar");
+        NumberFormat nf = NumberFormat.getNumberInstance(arabic);
+        assertEquals('\u0660', new DecimalFormatSymbols(arabic).getZeroDigit());
+        assertEquals("\u0661\u066c\u0662\u0663\u0664\u066c\u0665\u0666\u0667\u066c\u0668\u0669\u0660",
+                nf.format(1234567890));
+    }
 }
diff --git a/luni/src/test/java/java/util/AllTests.java b/luni/src/test/java/java/util/AllTests.java
index 6af29d8..6680a8e 100644
--- a/luni/src/test/java/java/util/AllTests.java
+++ b/luni/src/test/java/java/util/AllTests.java
@@ -21,12 +21,16 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(java.util.CalendarTest.class);
         suite.addTestSuite(java.util.CurrencyTest.class);
         suite.addTestSuite(java.util.DateTest.class);
         suite.addTestSuite(java.util.FormatterTest.class);
+        suite.addTestSuite(java.util.LocaleTest.class);
         suite.addTestSuite(java.util.RandomTest.class);
+        suite.addTestSuite(java.util.ServiceLoaderTest.class);
         suite.addTestSuite(java.util.TimeZoneTest.class);
+        suite.addTestSuite(java.util.TreeMapTest.class);
         return suite;
     }
 }
diff --git a/luni/src/test/java/java/util/CalendarTest.java b/luni/src/test/java/java/util/CalendarTest.java
new file mode 100644
index 0000000..f9f6fbe
--- /dev/null
+++ b/luni/src/test/java/java/util/CalendarTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CalendarTest extends junit.framework.TestCase {
+    // http://code.google.com/p/android/issues/detail?id=6184
+    public void test_setTimeZone() {
+        // The specific time zones don't matter; they just have to be different so we can see that
+        // get(Calendar.ZONE_OFFSET) returns the zone offset of the time zone passed to setTimeZone.
+        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
+        assertEquals(0, cal.get(Calendar.ZONE_OFFSET));
+        TimeZone tz = java.util.TimeZone.getTimeZone("GMT+7");
+        cal.setTimeZone(tz);
+        assertEquals(25200000, cal.get(Calendar.ZONE_OFFSET));
+    }
+}
diff --git a/luni/src/test/java/java/util/CurrencyTest.java b/luni/src/test/java/java/util/CurrencyTest.java
index 16111d5..66354f5 100644
--- a/luni/src/test/java/java/util/CurrencyTest.java
+++ b/luni/src/test/java/java/util/CurrencyTest.java
@@ -31,4 +31,15 @@
         // Canada that Canadians give it a localized (to Canada) symbol.
         assertEquals("AED", Currency.getInstance("AED").getSymbol(Locale.CANADA));
     }
+
+    // Regression test to ensure that Currency.getInstance(String) throws if
+    // given an invalid ISO currency code.
+    public void test_getInstance_illegal_currency_code() throws Exception {
+        Currency.getInstance("USD");
+        try {
+            Currency.getInstance("BOGO-DOLLARS");
+            fail("expected IllegalArgumentException for invalid ISO currency code");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
 }
diff --git a/luni/src/test/java/java/util/FormatterTest.java b/luni/src/test/java/java/util/FormatterTest.java
index 1722e67..a4ade59 100644
--- a/luni/src/test/java/java/util/FormatterTest.java
+++ b/luni/src/test/java/java/util/FormatterTest.java
@@ -16,10 +16,41 @@
 
 package java.util;
 
+import java.math.BigDecimal;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
 public class FormatterTest extends junit.framework.TestCase {
+    public void test_numberLocalization() throws Exception {
+        Locale arabic = new Locale("ar");
+        // Check the fast path for %d:
+        assertEquals("12 \u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u0660 34",
+                String.format(arabic, "12 %d 34", 1234567890));
+        // And the slow path too:
+        assertEquals("12 \u0661\u066c\u0662\u0663\u0664\u066c\u0665\u0666\u0667\u066c\u0668\u0669\u0660 34",
+                String.format(arabic, "12 %,d 34", 1234567890));
+        // And three localized floating point formats:
+        assertEquals("12 \u0661\u066b\u0662\u0663\u0660e+\u0660\u0660 34",
+                String.format(arabic, "12 %.3e 34", 1.23));
+        assertEquals("12 \u0661\u066b\u0662\u0663\u0660 34",
+                String.format(arabic, "12 %.3f 34", 1.23));
+        assertEquals("12 \u0661\u066b\u0662\u0663 34",
+                String.format(arabic, "12 %.3g 34", 1.23));
+        // And date/time formatting (we assume that all time/date number formatting is done by the
+        // same code, so this is representative):
+        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT-08:00"));
+        c.setTimeInMillis(0);
+        assertEquals("12 \u0661\u0666:\u0660\u0660:\u0660\u0660 34",
+                String.format(arabic, "12 %tT 34", c));
+        // These shouldn't get localized:
+        assertEquals("1234", String.format(arabic, "1234"));
+        assertEquals("1234", String.format(arabic, "%s", "1234"));
+        assertEquals("1234", String.format(arabic, "%s", 1234));
+        assertEquals("2322", String.format(arabic, "%o", 1234));
+        assertEquals("4d2", String.format(arabic, "%x", 1234));
+        assertEquals("0x1.0p0", String.format(arabic, "%a", 1.0));
+    }
+
     // http://b/2301938
     public void test_uppercaseConversions() throws Exception {
         // In most locales, the upper-case equivalent of "i" is "I".
@@ -42,4 +73,32 @@
         // ...without screwing up conversions that don't take an argument.
         assertEquals("%", String.format(Locale.US, "%%"));
     }
+    
+    // Alleged regression tests for historical bugs. (It's unclear whether the bugs were in
+    // BigDecimal or Formatter.)
+    public void test_BigDecimalFormatting() throws Exception {
+        BigDecimal[] input = new BigDecimal[] {
+            new BigDecimal("20.00000"),
+            new BigDecimal("20.000000"),
+            new BigDecimal(".2"),
+            new BigDecimal("2"),
+            new BigDecimal("-2"),
+            new BigDecimal("200000000000000000000000"),
+            new BigDecimal("20000000000000000000000000000000000000000000000000")
+        };
+        String[] output = new String[] {
+            "20.00",
+            "20.00",
+            "0.20",
+            "2.00",
+            "-2.00",
+            "200000000000000000000000.00",
+            "20000000000000000000000000000000000000000000000000.00"
+        };
+        for (int i = 0; i < input.length; ++i) {
+            String result = String.format("%.2f", input[i]);
+            assertEquals("input=\"" + input[i] + "\", " + ",expected=" + output[i] + ",actual=" + result,
+                    output[i], result);
+        }
+    }
 }
diff --git a/luni/src/test/java/java/util/LocaleTest.java b/luni/src/test/java/java/util/LocaleTest.java
new file mode 100644
index 0000000..c8a24f1
--- /dev/null
+++ b/luni/src/test/java/java/util/LocaleTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LocaleTest extends junit.framework.TestCase {
+    public void test_getDisplayName() throws Exception {
+        // http://b/2611311; if there's no display language/country/variant, use the raw codes.
+        Locale weird = new Locale("AaBbCc", "DdEeFf", "GgHhIi");
+        assertEquals("aabbcc", weird.getLanguage());
+        assertEquals("", weird.getDisplayLanguage());
+        assertEquals("DDEEFF", weird.getCountry());
+        assertEquals("", weird.getDisplayCountry());
+        assertEquals("GgHhIi", weird.getVariant());
+        assertEquals("", weird.getDisplayVariant());
+        assertEquals("aabbcc (DDEEFF,GgHhIi)", weird.getDisplayName());
+    }
+}
diff --git a/luni/src/test/java/java/util/SerializableTester.java b/luni/src/test/java/java/util/SerializableTester.java
new file mode 100644
index 0000000..de98d96
--- /dev/null
+++ b/luni/src/test/java/java/util/SerializableTester.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+import junit.framework.AssertionFailedError;
+
+public class SerializableTester<T> {
+
+    private final String golden;
+    private final T value;
+
+    public SerializableTester(T value, String golden) {
+        this.golden = golden;
+        this.value = value;
+    }
+
+    protected void verify(T deserialized) {}
+
+    public void test() {
+        try {
+            if (golden == null || golden.length() == 0) {
+                fail("No golden value supplied! Consider using this: "
+                        + hexEncode(serialize(value)));
+            }
+
+            // just a sanity check! if this fails, verify() is probably broken
+            verify(value);
+
+            @SuppressWarnings("unchecked") // deserialize should return the proper type
+            T deserialized = (T) deserialize(hexDecode(golden));
+            assertEquals("User-constructed value doesn't equal deserialized golden value",
+                    value, deserialized);
+            verify(deserialized);
+
+            @SuppressWarnings("unchecked") // deserialize should return the proper type
+            T reserialized = (T) deserialize(serialize(value));
+            assertEquals("User-constructed value doesn't equal itself, reserialized",
+                    value, reserialized);
+            verify(reserialized);
+
+        } catch (Exception e) {
+            Error failure = new AssertionFailedError();
+            failure.initCause(e);
+            throw failure;
+        }
+    }
+
+    private byte[] serialize(Object object) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        new ObjectOutputStream(out).writeObject(object);
+        return out.toByteArray();
+    }
+
+    private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
+        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
+        Object result = in.readObject();
+        assertEquals(-1, in.read());
+        return result;
+    }
+
+    private String hexEncode(byte[] bytes) {
+        StringBuilder result = new StringBuilder(bytes.length * 2);
+        for (byte b : bytes) {
+            result.append(String.format("%02x", b));
+        }
+        return result.toString();
+    }
+
+    private byte[] hexDecode(String s) {
+        byte[] result = new byte[s.length() / 2];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = (byte) Integer.parseInt(s.substring(i*2, i*2 + 2), 16);
+        }
+        return result;
+    }
+}
+
diff --git a/luni/src/test/java/java/util/ServiceLoaderTest.java b/luni/src/test/java/java/util/ServiceLoaderTest.java
new file mode 100644
index 0000000..0f90973
--- /dev/null
+++ b/luni/src/test/java/java/util/ServiceLoaderTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ServiceLoaderTest extends junit.framework.TestCase {
+    public static interface UnimplementedInterface { }
+    public void test_noImplementations() {
+        assertFalse(ServiceLoader.load(UnimplementedInterface.class).iterator().hasNext());
+    }
+
+    public static class Impl1 implements ServiceLoaderTestInterface { }
+    public static class Impl2 implements ServiceLoaderTestInterface { }
+    public void test_implementations() {
+        ServiceLoader<ServiceLoaderTestInterface> loader = ServiceLoader.load(ServiceLoaderTestInterface.class);
+        Iterator<ServiceLoaderTestInterface> it = loader.iterator();
+        assertTrue(it.hasNext());
+        assertTrue(it.next() instanceof Impl1);
+        assertTrue(it.hasNext());
+        assertTrue(it.next() instanceof Impl2);
+        assertFalse(it.hasNext());
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/Mkdir.java b/luni/src/test/java/java/util/ServiceLoaderTestInterface.java
similarity index 71%
copy from tools/runner/java/dalvik/runner/Mkdir.java
copy to luni/src/test/java/java/util/ServiceLoaderTestInterface.java
index 46dcf08..5f43136 100644
--- a/tools/runner/java/dalvik/runner/Mkdir.java
+++ b/luni/src/test/java/java/util/ServiceLoaderTestInterface.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- *
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
+ * 
  *      http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,16 +14,11 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
-
-import java.io.File;
+package java.util;
 
 /**
- * A mkdir command.
+ * Ideally, this would have been an inner class in ServiceLoaderTest, but we need a corresponding
+ * resource file, and our build system can't cope with $ in filenames.
  */
-final class Mkdir {
-
-    public void mkdirs(File directory) {
-        new Command("mkdir", "-p", directory.getPath()).execute();
-    }
+public interface ServiceLoaderTestInterface {
 }
diff --git a/luni/src/test/java/java/util/TreeMapTest.java b/luni/src/test/java/java/util/TreeMapTest.java
new file mode 100644
index 0000000..87992da
--- /dev/null
+++ b/luni/src/test/java/java/util/TreeMapTest.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Map.Entry;
+import junit.framework.TestCase;
+
+public class TreeMapTest extends TestCase {
+    
+    public void testConcurrentModificationDetection() {
+        Map<String, String> map = new TreeMap<String, String>();
+        map.put("A", "a");
+        map.put("B", "b");
+        map.put("C", "c");
+        Iterator<Entry<String,String>> iterator = map.entrySet().iterator();
+        iterator.next();
+        iterator.next();
+        iterator.remove();
+        map.put("D", "d");
+        try {
+            iterator.next();
+            fail();
+        } catch (ConcurrentModificationException e) {
+        }
+    }
+
+    public void testIteratorRemoves() {
+        Map<String, String> map = new TreeMap<String, String>();
+        map.put("A", "a");
+        map.put("B", "b");
+        map.put("C", "c");
+        Iterator<Entry<String,String>> iterator = map.entrySet().iterator();
+        assertEquals("A", iterator.next().getKey());
+        assertEquals("B", iterator.next().getKey());
+        iterator.remove();
+        assertEquals("C", iterator.next().getKey());
+        iterator.remove();
+        assertFalse(iterator.hasNext());
+    }
+
+    /**
+     * Test that entry set contains and removal use the comparator rather than equals.
+     */
+    public void testEntrySetUsesComparatorOnly() {
+        Map<String,String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+        map.put("ABC", "a");
+        assertTrue(map.entrySet().contains(new SimpleEntry<String, String>("abc", "a")));
+        assertTrue(map.entrySet().remove(new SimpleEntry<String, String>("abc", "a")));
+        assertEquals(0, map.size());
+    }
+
+    public void testMapConstructorPassingSortedMap() {
+        Map<String,String> source = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+        NavigableMap<String,String> copy = new TreeMap<String, String>(source);
+        assertEquals(null, copy.comparator());
+    }
+
+    public void testNullsWithNaturalOrder() {
+        HashMap<String, String> copyFrom = new HashMap<String, String>();
+        copyFrom.put(null, "b");
+        try {
+            new TreeMap<String, String>(copyFrom);
+            fail(); // the RI doesn't throw if null is the only key
+        } catch (NullPointerException expected) {
+        }
+
+        TreeMap<String,String> map = new TreeMap<String, String>();
+        try {
+            map.put(null, "b");
+            fail();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            map.descendingMap().put(null, "b");
+            fail();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            map.subMap("a", "z").put(null, "b");
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testClassCastExceptions() {
+        Map<Object, Object> map = new TreeMap<Object, Object>();
+        map.put("A", "a");
+        try {
+            map.get(5);
+            fail();
+        } catch (ClassCastException e) {
+        }
+        try {
+            map.containsKey(5);
+            fail();
+        } catch (ClassCastException e) {
+        }
+        try {
+            map.remove(5);
+            fail();
+        } catch (ClassCastException e) {
+        }
+    }
+
+    public void testClassCastExceptionsOnBounds() {
+        Map<Object, Object> map = new TreeMap<Object, Object>().subMap("a", "z");
+        try {
+            map.get(5);
+            fail();
+        } catch (ClassCastException e) {
+        }
+        try {
+            map.containsKey(5);
+            fail();
+        } catch (ClassCastException e) {
+        }
+        try {
+            map.remove(5);
+            fail();
+        } catch (ClassCastException e) {
+        }
+    }
+
+    public void testClone() {
+        TreeMap<String, String> map = new TreeMap<String, String>() {
+            @Override public String toString() {
+                return "x:" + super.toString();
+            }
+        };
+
+        map.put("A", "a");
+        map.put("B", "b");
+
+        @SuppressWarnings("unchecked")
+        TreeMap<String, String> clone = (TreeMap<String, String>) map.clone();
+        assertEquals(map.getClass(), clone.getClass());
+        assertEquals("x:{A=a, B=b}", map.toString());
+    }
+
+    public void testEmptyMapSerialization() {
+        String s = "aced0005737200116a6176612e7574696c2e547265654d61700cc1f63e2d256a"
+                + "e60300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436"
+                + "f6d70617261746f723b78707077040000000078";
+        TreeMap<String, String> map = new TreeMap<String, String>();
+        new SerializableTester<TreeMap<String, String>>(map, s).test();
+    }
+
+    public void testSerializationWithComparator() {
+        String s = "aced0005737200116a6176612e7574696c2e547265654d61700cc1f63e2d256a"
+                + "e60300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436"
+                + "f6d70617261746f723b78707372002a6a6176612e6c616e672e537472696e6724"
+                + "43617365496e73656e736974697665436f6d70617261746f7277035c7d5c50e5c"
+                + "e02000078707704000000027400016171007e00057400016271007e000678";
+        TreeMap<String,String> map = new TreeMap<String, String>(
+                String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        new SerializableTester<NavigableMap<String, String>>(map, s) {
+            @Override protected void verify(NavigableMap<String, String> deserialized) {
+                assertEquals(0, deserialized.comparator().compare("X", "x"));
+            }
+        }.test();
+    }
+
+    public void testSubmapSerialization() {
+        String s = "aced0005737200216a6176612e7574696c2e547265654d617024417363656e646"
+                + "96e675375624d61700cab946d1f0fab1c020000787200216a6176612e7574696c2"
+                + "e547265654d6170244e6176696761626c655375624d6170e2d0a70e64210e08020"
+                + "0075a000966726f6d53746172745a000b6869496e636c75736976655a000b6c6f4"
+                + "96e636c75736976655a0005746f456e644c000268697400124c6a6176612f6c616"
+                + "e672f4f626a6563743b4c00026c6f71007e00024c00016d7400134c6a6176612f7"
+                + "574696c2f547265654d61703b7870000001007400016374000161737200116a617"
+                + "6612e7574696c2e547265654d61700cc1f63e2d256ae60300014c000a636f6d706"
+                + "17261746f727400164c6a6176612f7574696c2f436f6d70617261746f723b78707"
+                + "372002a6a6176612e6c616e672e537472696e672443617365496e73656e7369746"
+                + "97665436f6d70617261746f7277035c7d5c50e5ce0200007870770400000004710"
+                + "07e000671007e00067400016271007e000c71007e000571007e000574000164710"
+                + "07e000d78";
+        TreeMap<String,String> map = new TreeMap<String, String>(
+                String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        map.put("c", "c");
+        map.put("d", "d");
+        SortedMap<String, String> submap = map.subMap("a", "c");
+        new SerializableTester<SortedMap<String, String>>(submap, s) {
+            @Override protected void verify(SortedMap<String, String> deserialized) {
+                try {
+                    deserialized.put("e", "e");
+                    fail();
+                } catch (IllegalArgumentException e) {
+                }
+            }
+        }.test();
+    }
+
+    public void testNavigableSubmapSerialization() {
+        String s = "aced0005737200216a6176612e7574696c2e547265654d617024417363656e646"
+                + "96e675375624d61700cab946d1f0fab1c020000787200216a6176612e7574696c2"
+                + "e547265654d6170244e6176696761626c655375624d6170e2d0a70e64210e08020"
+                + "0075a000966726f6d53746172745a000b6869496e636c75736976655a000b6c6f4"
+                + "96e636c75736976655a0005746f456e644c000268697400124c6a6176612f6c616"
+                + "e672f4f626a6563743b4c00026c6f71007e00024c00016d7400134c6a6176612f7"
+                + "574696c2f547265654d61703b7870000100007400016374000161737200116a617"
+                + "6612e7574696c2e547265654d61700cc1f63e2d256ae60300014c000a636f6d706"
+                + "17261746f727400164c6a6176612f7574696c2f436f6d70617261746f723b78707"
+                + "372002a6a6176612e6c616e672e537472696e672443617365496e73656e7369746"
+                + "97665436f6d70617261746f7277035c7d5c50e5ce0200007870770400000004710"
+                + "07e000671007e00067400016271007e000c71007e000571007e000574000164710"
+                + "07e000d78";
+        TreeMap<String,String> map = new TreeMap<String, String>(
+                String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        map.put("c", "c");
+        map.put("d", "d");
+        SortedMap<String, String> submap = map.subMap("a", false, "c", true);
+        new SerializableTester<SortedMap<String, String>>(submap, s) {
+            @Override protected void verify(SortedMap<String, String> deserialized) {
+                try {
+                    deserialized.put("e", "e");
+                    fail();
+                } catch (IllegalArgumentException e) {
+                }
+            }
+        }.test();
+    }
+
+    public void testDescendingMapSerialization() {
+        String s = "aced0005737200226a6176612e7574696c2e547265654d61702444657363656e6"
+                + "4696e675375624d61700cab946d1f0f9d0c0200014c001172657665727365436f6"
+                + "d70617261746f727400164c6a6176612f7574696c2f436f6d70617261746f723b7"
+                + "87200216a6176612e7574696c2e547265654d6170244e6176696761626c6553756"
+                + "24d6170e2d0a70e64210e080200075a000966726f6d53746172745a000b6869496"
+                + "e636c75736976655a000b6c6f496e636c75736976655a0005746f456e644c00026"
+                + "8697400124c6a6176612f6c616e672f4f626a6563743b4c00026c6f71007e00034"
+                + "c00016d7400134c6a6176612f7574696c2f547265654d61703b787001010101707"
+                + "0737200116a6176612e7574696c2e547265654d61700cc1f63e2d256ae60300014"
+                + "c000a636f6d70617261746f7271007e000178707372002a6a6176612e6c616e672"
+                + "e537472696e672443617365496e73656e736974697665436f6d70617261746f727"
+                + "7035c7d5c50e5ce02000078707704000000027400016171007e000a74000162710"
+                + "07e000b78737200286a6176612e7574696c2e436f6c6c656374696f6e732452657"
+                + "665727365436f6d70617261746f7232000003fa6c354d510200014c0003636d707"
+                + "1007e0001787071007e0009";
+        TreeMap<String,String> map = new TreeMap<String, String>(
+                String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        NavigableMap<String, String> descendingMap = map.descendingMap();
+        new SerializableTester<NavigableMap<String, String>>(descendingMap, s) {
+            @Override protected void verify(NavigableMap<String, String> deserialized) {
+                assertEquals("b", deserialized.navigableKeySet().first());
+            }
+        }.test();
+    }
+
+    public void testJava5SerializationWithComparator() {
+        String s = "aced0005737200116a6176612e7574696c2e547265654d61700cc1f63e2d256a"
+                + "e60300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436"
+                + "f6d70617261746f723b78707372002a6a6176612e6c616e672e537472696e6724"
+                + "43617365496e73656e736974697665436f6d70617261746f7277035c7d5c50e5c"
+                + "e02000078707704000000027400016171007e00057400016271007e000678";
+        TreeMap<String,String> map = new TreeMap<String, String>(
+                String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        new SerializableTester<TreeMap<String, String>>(map, s) {
+            @Override protected void verify(TreeMap<String, String> deserialized) {
+                assertEquals(0, deserialized.comparator().compare("X", "x"));
+            }
+        }.test();
+    }
+
+    /**
+     * On JDK5, this fails with a NullPointerException after deserialization!
+     */
+    public void testJava5SubmapSerialization() {
+        String s = "aced0005737200186a6176612e7574696c2e547265654d6170245375624d6170"
+                + "a5818343a213c27f0200055a000966726f6d53746172745a0005746f456e644c0"
+                + "00766726f6d4b65797400124c6a6176612f6c616e672f4f626a6563743b4c0006"
+                + "7468697324307400134c6a6176612f7574696c2f547265654d61703b4c0005746"
+                + "f4b657971007e00017870000074000161737200116a6176612e7574696c2e5472"
+                + "65654d61700cc1f63e2d256ae60300014c000a636f6d70617261746f727400164"
+                + "c6a6176612f7574696c2f436f6d70617261746f723b78707372002a6a6176612e"
+                + "6c616e672e537472696e672443617365496e73656e736974697665436f6d70617"
+                + "261746f7277035c7d5c50e5ce020000787077040000000471007e000471007e00" 
+                + "047400016271007e000a7400016371007e000b7400016471007e000c7871007e0"
+                + "00b";
+        TreeMap<String,String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        map.put("c", "c");
+        map.put("d", "d");
+        SortedMap<String, String> submap = map.subMap("a", "c");
+        new SerializableTester<SortedMap<String, String>>(submap, s) {
+            @Override protected void verify(SortedMap<String, String> deserialized) {
+                try {
+                    deserialized.put("e", "e");
+                    fail();
+                } catch (IllegalArgumentException e) {
+                }
+            }
+        }.test();
+    }
+}
diff --git a/luni/src/test/java/java/util/zip/ZipEntryTest.java b/luni/src/test/java/java/util/zip/ZipEntryTest.java
new file mode 100644
index 0000000..4c7cccf
--- /dev/null
+++ b/luni/src/test/java/java/util/zip/ZipEntryTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ZipEntryTest extends junit.framework.TestCase {
+    // http://code.google.com/p/android/issues/detail?id=4690
+    public void test_utf8FileNames() throws Exception {
+        // Create a zip file containing non-ASCII filenames.
+        File f = File.createTempFile("your", "mum");
+        List<String> filenames = Arrays.asList("us-ascii",
+                "\u043c\u0430\u0440\u0442\u0430", // russian
+                "\u1f00\u03c0\u1f78", // greek
+                "\u30b3\u30f3\u30cb\u30c1\u30cf"); // japanese
+        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
+        for (String filename : filenames) {
+            out.putNextEntry(new ZipEntry(filename));
+            out.closeEntry(); // Empty files are fine.
+        }
+        out.close();
+        // Read it back, and check we find all those names.
+        // This failed when we were mangling the encoding.
+        ZipFile zipFile = new ZipFile(f);
+        for (String filename : filenames) {
+            assertNotNull(filename, zipFile.getEntry(filename));
+        }
+        // Check that ZipInputStream works too.
+        ZipInputStream in = new ZipInputStream(new FileInputStream(f));
+        ZipEntry entry;
+        int entryCount = 0;
+        while ((entry = in.getNextEntry()) != null) {
+            assertTrue(entry.getName(), filenames.contains(entry.getName()));
+            ++entryCount;
+        }
+        assertEquals(filenames.size(), entryCount);
+        in.close();
+    }
+}
diff --git a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java b/luni/src/test/java/javax/net/ssl/AllTests.java
similarity index 64%
copy from icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
copy to luni/src/test/java/javax/net/ssl/AllTests.java
index 1b95075..740b788 100644
--- a/icu/src/test/java/com/ibm/icu4jni/util/AllTests.java
+++ b/luni/src/test/java/javax/net/ssl/AllTests.java
@@ -1,12 +1,12 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
- * 
+ * Copyright (C) 2010 The Android Open Source Project
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,15 +14,19 @@
  * limitations under the License.
  */
 
-package com.ibm.icu4jni.util;
+package javax.net.ssl;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
-        suite.addTestSuite(com.ibm.icu4jni.util.ResourcesTest.class);
+        TestSuite suite = new TestSuite();
+        suite.addTestSuite(SSLSocketFactoryTest.class);
+        suite.addTestSuite(SSLContextTest.class);
+        suite.addTestSuite(SSLSocketTest.class);
+        suite.addTestSuite(SSLSessionTest.class);
+        suite.addTestSuite(SSLSessionContextTest.class);
         return suite;
     }
 }
diff --git a/luni/src/test/java/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/javax/net/ssl/SSLContextTest.java
new file mode 100644
index 0000000..508aaaf
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLContextTest.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+import java.util.Hashtable;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import junit.framework.TestCase;
+import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.x509.X509V3CertificateGenerator;
+
+public class SSLContextTest extends TestCase {
+
+    public static final boolean IS_RI = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
+    public static final String PROVIDER_NAME = (IS_RI) ? "SunJSSE" : "HarmonyJSSE";
+
+    public void test_SSLContext_getInstance() throws Exception {
+        try {
+            SSLContext.getInstance(null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+        assertNotNull(SSLContext.getInstance("SSL"));
+        assertNotNull(SSLContext.getInstance("SSLv3"));
+        assertNotNull(SSLContext.getInstance("TLS"));
+        assertNotNull(SSLContext.getInstance("TLSv1"));
+
+        assertNotSame(SSLContext.getInstance("TLS"),
+                      SSLContext.getInstance("TLS"));
+
+        try {
+            SSLContext.getInstance(null, (String) null);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            SSLContext.getInstance(null, "");
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            SSLContext.getInstance("TLS", (String) null);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            SSLContext.getInstance(null, PROVIDER_NAME);
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void test_SSLContext_getProtocol() throws Exception {
+        assertProtocolExistsForName("SSL");
+        assertProtocolExistsForName("TLS");
+    }
+
+    private void assertProtocolExistsForName(String protocolName) throws Exception {
+        String protocol = SSLContext.getInstance(protocolName).getProtocol();
+        assertNotNull(protocol);
+        assertEquals(protocolName, protocol);
+    }
+
+    public void test_SSLContext_getProvider() throws Exception {
+        Provider provider = SSLContext.getInstance("TLS").getProvider();
+        assertNotNull(provider);
+        assertEquals(PROVIDER_NAME, provider.getName());
+    }
+
+    public void test_SSLContext_init() throws Exception {
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(null, null, null);
+    }
+
+    public void test_SSLContext_getSocketFactory() throws Exception {
+        try {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.getSocketFactory();
+            fail();
+        } catch (IllegalStateException e) {
+        }
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(null, null, null);
+        SocketFactory sf = sslContext.getSocketFactory();
+        assertNotNull(sf);
+        assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
+    }
+
+    public void test_SSLContext_getServerSocketFactory() throws Exception {
+        try {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.getServerSocketFactory();
+            fail();
+        } catch (IllegalStateException e) {
+        }
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(null, null, null);
+        ServerSocketFactory ssf = sslContext.getServerSocketFactory();
+        assertNotNull(ssf);
+        assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
+    }
+
+    public void test_SSLContext_createSSLEngine() throws Exception {
+        try {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.createSSLEngine();
+            fail();
+        } catch (IllegalStateException e) {
+        }
+        try {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.createSSLEngine(null, -1);
+            fail();
+        } catch (IllegalStateException e) {
+        }
+        {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, null, null);
+            SSLEngine se = sslContext.createSSLEngine();
+            assertNotNull(se);
+        }
+        {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, null, null);
+            SSLEngine se = sslContext.createSSLEngine(null, -1);
+            assertNotNull(se);
+        }
+    }
+
+    @KnownFailure("Should be able to ask SSLContext for SSLSessionContext's before called SSLContext.init")
+    public void test_SSLContext_getServerSessionContext() throws Exception {
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        SSLSessionContext sessionContext = sslContext.getServerSessionContext();
+        assertNotNull(sessionContext);
+
+        assertNotSame(SSLContext.getInstance("TLS").getServerSessionContext(),
+                      sessionContext);
+    }
+
+    @KnownFailure("Should be able to ask SSLContext for SSLSessionContext's before called SSLContext.init")
+    public void test_SSLContext_getClientSessionContext() throws Exception {
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        SSLSessionContext sessionContext = sslContext.getClientSessionContext();
+        assertNotNull(sessionContext);
+
+        assertNotSame(SSLContext.getInstance("TLS").getClientSessionContext(),
+                      sessionContext);
+    }
+
+    /**
+     * SSLContextTest.Helper is a convenience class for other tests that
+     * want a canned SSLContext and related state for testing so they
+     * don't have to duplicate the logic.
+     */
+    public static final class Helper {
+
+        static {
+            if (SSLContextTest.IS_RI) {
+                Security.addProvider(new BouncyCastleProvider());
+            }
+        }
+
+        public final KeyStore keyStore;
+        public final char[] keyStorePassword;
+        public final String publicAlias;
+        public final String privateAlias;
+        public final SSLContext sslContext;
+        public final SSLServerSocket serverSocket;
+        public final InetAddress host;
+        public final int port;
+
+        private Helper(KeyStore keyStore,
+                       char[] keyStorePassword,
+                       String publicAlias,
+                       String privateAlias,
+                       SSLContext sslContext,
+                       SSLServerSocket serverSocket,
+                       InetAddress host,
+                       int port) {
+            this.keyStore = keyStore;
+            this.keyStorePassword = keyStorePassword;
+            this.publicAlias = publicAlias;
+            this.privateAlias = privateAlias;
+            this.sslContext = sslContext;
+            this.serverSocket = serverSocket;
+            this.host = host;
+            this.port = port;
+        }
+
+        public static Helper create() {
+            try {
+                char[] keyStorePassword = null;
+                String publicAlias = "public";
+                String privateAlias = "private";
+                return create(createKeyStore(keyStorePassword, publicAlias, privateAlias),
+                              null,
+                              publicAlias,
+                              privateAlias);
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public static Helper create(KeyStore keyStore,
+                                    char[] keyStorePassword,
+                                    String publicAlias,
+                                    String privateAlias) {
+            try {
+                SSLContext sslContext = createSSLContext(keyStore, keyStorePassword);
+
+                SSLServerSocket serverSocket = (SSLServerSocket)
+                    sslContext.getServerSocketFactory().createServerSocket(0);
+                InetSocketAddress sa = (InetSocketAddress) serverSocket.getLocalSocketAddress();
+                InetAddress host = sa.getAddress();
+                int port = sa.getPort();
+
+                return new Helper(keyStore, keyStorePassword, publicAlias, privateAlias,
+                                  sslContext, serverSocket, host, port);
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /**
+         * Create a BKS KeyStore containing an RSAPrivateKey with alias
+         * "private" and a X509Certificate based on the matching
+         * RSAPublicKey stored under the alias name publicAlias.
+         *
+         * The private key will have a certificate chain including the
+         * certificate stored under the alias name privateAlias. The
+         * certificate will be signed by the private key. The certificate
+         * Subject and Issuer Common-Name will be the local host's
+         * canonical hostname. The certificate will be valid for one day
+         * before and one day after the time of creation.
+         *
+         * The KeyStore is optionally password protected by the
+         * keyStorePassword argument, which can be null if a password is
+         * not desired.
+         *
+         * Based on:
+         * org.bouncycastle.jce.provider.test.SigTest
+         * org.bouncycastle.jce.provider.test.CertTest
+         */
+        public static KeyStore createKeyStore(char[] keyStorePassword,
+                                              String publicAlias,
+                                              String privateAlias)
+                throws Exception {
+
+            // 1.) we make the keys
+            int keysize = 1024;
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+            kpg.initialize(keysize, new SecureRandom());
+            KeyPair kp = kpg.generateKeyPair();
+            RSAPrivateKey privateKey = (RSAPrivateKey)kp.getPrivate();
+            RSAPublicKey publicKey  = (RSAPublicKey)kp.getPublic();
+
+            // 2.) use keys to make certficate
+
+            // note that there doesn't seem to be a standard way to make a
+            // certificate using java.* or javax.*. The CertificateFactory
+            // interface assumes you want to read in a stream of bytes a
+            // factory specific format. So here we use Bouncy Castle's
+            // X509V3CertificateGenerator and related classes.
+
+            Hashtable attributes = new Hashtable();
+            attributes.put(X509Principal.CN, InetAddress.getLocalHost().getCanonicalHostName());
+            X509Principal dn = new X509Principal(attributes);
+
+            long millisPerDay = 24 * 60 * 60 * 1000;
+            long now = System.currentTimeMillis();
+            Date start = new Date(now - millisPerDay);
+            Date end = new Date(now + millisPerDay);
+            BigInteger serial = BigInteger.valueOf(1);
+
+            X509V3CertificateGenerator x509cg = new X509V3CertificateGenerator();
+            x509cg.setSubjectDN(dn);
+            x509cg.setIssuerDN(dn);
+            x509cg.setNotBefore(start);
+            x509cg.setNotAfter(end);
+            x509cg.setPublicKey(publicKey);
+            x509cg.setSignatureAlgorithm("sha1WithRSAEncryption");
+            x509cg.setSerialNumber(serial);
+            X509Certificate x509c = x509cg.generateX509Certificate(privateKey);
+            X509Certificate[] x509cc = new X509Certificate[] { x509c };
+
+
+            // 3.) put certificate and private key to make a key store
+            KeyStore ks = KeyStore.getInstance("BKS");
+            ks.load(null, null);
+            ks.setKeyEntry(privateAlias, privateKey, keyStorePassword, x509cc);
+            ks.setCertificateEntry(publicAlias, x509c);
+            return ks;
+        }
+
+        /**
+         * Create a SSLContext with a KeyManager using the private key and
+         * certificate chain from the given KeyStore and a TrustManager
+         * using the certificates authorities from the same KeyStore.
+         */
+        public static final SSLContext createSSLContext(final KeyStore keyStore, final char[] keyStorePassword)
+                throws Exception {
+            String kmfa = KeyManagerFactory.getDefaultAlgorithm();
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfa);
+            kmf.init(keyStore, keyStorePassword);
+
+            String tmfa = TrustManagerFactory.getDefaultAlgorithm();
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfa);
+            tmf.init(keyStore);
+
+            SSLContext context = SSLContext.getInstance("TLS");
+            context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
+            return context;
+        }
+    }
+
+    public void test_SSLContextTest_Helper_create() {
+        Helper helper = Helper.create();
+        assertNotNull(helper);
+        assertNotNull(helper.keyStore);
+        assertNull(helper.keyStorePassword);
+        assertNotNull(helper.publicAlias);
+        assertNotNull(helper.privateAlias);
+        assertNotNull(helper.sslContext);
+        assertNotNull(helper.serverSocket);
+        assertNotNull(helper.host);
+        assertTrue(helper.port != 0);
+    }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
new file mode 100644
index 0000000..83ed9c9
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import junit.framework.TestCase;
+
+public class SSLSessionContextTest extends TestCase {
+
+    public static final void assertSSLSessionContextSize(int expected, SSLSessionContext s) {
+        assertEquals(expected, Collections.list(s.getIds()).size());
+    }
+
+    public void test_SSLSessionContext_getIds() {
+        SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        assertSSLSessionContextSize(0, c.sslContext.getClientSessionContext());
+        assertSSLSessionContextSize(0, c.sslContext.getServerSessionContext());
+
+        SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+        assertSSLSessionContextSize(1, s.c.sslContext.getClientSessionContext());
+        assertSSLSessionContextSize(1, s.c.sslContext.getServerSessionContext());
+        Enumeration clientIds = s.c.sslContext.getClientSessionContext().getIds();
+        Enumeration serverIds = s.c.sslContext.getServerSessionContext().getIds();
+        byte[] clientId = (byte[]) clientIds.nextElement();
+        byte[] serverId = (byte[]) serverIds.nextElement();
+        assertEquals(32, clientId.length);
+        assertEquals(32, serverId.length);
+        assertTrue(Arrays.equals(clientId, serverId));
+    }
+
+    @KnownFailure("Should throw NullPointerException on getSession(null)")
+    public void test_SSLSessionContext_getSession() {
+        SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        try {
+            c.sslContext.getClientSessionContext().getSession(null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+        assertNull(c.sslContext.getClientSessionContext().getSession(new byte[0]));
+        assertNull(c.sslContext.getClientSessionContext().getSession(new byte[1]));
+
+        SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+        SSLSessionContext client = s.c.sslContext.getClientSessionContext();
+        SSLSessionContext server = s.c.sslContext.getServerSessionContext();
+        byte[] clientId = (byte[]) client.getIds().nextElement();
+        byte[] serverId = (byte[]) server.getIds().nextElement();
+        assertNotNull(client.getSession(clientId));
+        assertNotNull(server.getSession(serverId));
+        assertTrue(Arrays.equals(clientId, client.getSession(clientId).getId()));
+        assertTrue(Arrays.equals(serverId, server.getSession(serverId).getId()));
+    }
+
+    @KnownFailure("Should return 0 for unlimited, not 10 entries")
+    public void test_SSLSessionContext_getSessionCacheSize() {
+        SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        assertEquals(0, c.sslContext.getClientSessionContext().getSessionCacheSize());
+        assertEquals(0, c.sslContext.getServerSessionContext().getSessionCacheSize());
+
+        SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+        assertEquals(0, s.c.sslContext.getClientSessionContext().getSessionCacheSize());
+        assertEquals(0, s.c.sslContext.getServerSessionContext().getSessionCacheSize());
+    }
+
+    @KnownFailure("Should return 0 for unlimited, not 10 entries")
+    public void test_SSLSessionContext_setSessionCacheSize_basic() {
+        SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        assertBasicSetSessionCacheSizeBehavior(c.sslContext.getClientSessionContext());
+        assertBasicSetSessionCacheSizeBehavior(c.sslContext.getServerSessionContext());
+    }
+
+    private static void assertBasicSetSessionCacheSizeBehavior(SSLSessionContext s) {
+        try {
+            s.setSessionCacheSize(-1);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        assertEquals(0, s.getSessionCacheSize());
+        s.setSessionCacheSize(1);
+        assertEquals(1, s.getSessionCacheSize());
+    }
+
+    @KnownFailure("Should return 0 for unlimited, not 10 entries")
+    public void test_SSLSessionContext_setSessionCacheSize_dynamic() {
+
+        SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+        SSLSessionContext client = s.c.sslContext.getClientSessionContext();
+        SSLSessionContext server = s.c.sslContext.getServerSessionContext();
+        assertEquals(0, client.getSessionCacheSize());
+        assertEquals(0, server.getSessionCacheSize());
+        assertSSLSessionContextSize(1, client);
+        assertSSLSessionContextSize(1, server);
+
+        LinkedList<String> uniqueCipherSuites
+            = new LinkedList(Arrays.asList(s.server.getEnabledCipherSuites()));
+        uniqueCipherSuites.remove(s.client.getSession().getCipherSuite());
+
+        // only use RSA cipher suites which will work with our TrustProvider
+        Iterator<String> i = uniqueCipherSuites.iterator();
+        while (i.hasNext()) {
+            String cipherSuite = i.next();
+            if (cipherSuite.startsWith("SSL_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("TLS_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("TLS_DHE_RSA_")) {
+                continue;
+            }
+            if (cipherSuite.startsWith("SSL_DHE_RSA_")) {
+                continue;
+            }
+            i.remove();
+        }
+
+        /*
+         * having more than 5 uniqueCipherSuites is a test
+         * requirement, not a requirement of the interface or
+         * implementation. It simply allows us to make sure that we
+         * will not get a cached session ID since we'll have to
+         * renegotiate a new session due to the new cipher suite
+         * requirement. even this test only really needs three if it
+         * reused the unique cipher suites every time it resets the
+         * session cache.
+         */
+        assertTrue(uniqueCipherSuites.size() > 5);
+
+        SSLSocketTest.Helper.connect_workaround(s.c,
+                                              new String[] { uniqueCipherSuites.remove() }); // 1
+        assertSSLSessionContextSize(2, client);
+        assertSSLSessionContextSize(2, server);
+        SSLSocketTest.Helper.connect_workaround(s.c,
+                                              new String[] { uniqueCipherSuites.remove() }); // 2
+        assertSSLSessionContextSize(3, client);
+        assertSSLSessionContextSize(3, server);
+
+        client.setSessionCacheSize(1);
+        server.setSessionCacheSize(1);
+        assertEquals(1, client.getSessionCacheSize());
+        assertEquals(1, server.getSessionCacheSize());
+        assertSSLSessionContextSize(1, client);
+        assertSSLSessionContextSize(1, server);
+        SSLSocketTest.Helper.connect_workaround(s.c,
+                                              new String[] { uniqueCipherSuites.remove() }); // 3
+        assertSSLSessionContextSize(1, client);
+        assertSSLSessionContextSize(1, server);
+
+        client.setSessionCacheSize(2);
+        server.setSessionCacheSize(2);
+        SSLSocketTest.Helper.connect_workaround(s.c,
+                                              new String[] { uniqueCipherSuites.remove() }); // 4
+        assertSSLSessionContextSize(2, client);
+        assertSSLSessionContextSize(2, server);
+        SSLSocketTest.Helper.connect_workaround(s.c,
+                                              new String[] { uniqueCipherSuites.remove() }); // 5
+        assertSSLSessionContextSize(2, client);
+        assertSSLSessionContextSize(2, server);
+    }
+
+    @KnownFailure("Should return 86400 seconds (1 day), not 0 for unlimited")
+    public void test_SSLSessionContext_getSessionTimeout() {
+        SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        assertEquals(86400, c.sslContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(86400, c.sslContext.getServerSessionContext().getSessionTimeout());
+
+        SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+        assertEquals(86400, s.c.sslContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(86400, s.c.sslContext.getServerSessionContext().getSessionTimeout());
+    }
+
+    @KnownFailure("Should return 86400 seconds (1 day), not 0 for unlimited")
+    public void test_SSLSessionContext_setSessionTimeout() throws Exception {
+        SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        assertEquals(86400, c.sslContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(86400, c.sslContext.getServerSessionContext().getSessionTimeout());
+        c.sslContext.getClientSessionContext().setSessionTimeout(0);
+        c.sslContext.getServerSessionContext().setSessionTimeout(0);
+        assertEquals(0, c.sslContext.getClientSessionContext().getSessionTimeout());
+        assertEquals(0, c.sslContext.getServerSessionContext().getSessionTimeout());
+
+        try {
+            c.sslContext.getClientSessionContext().setSessionTimeout(-1);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            c.sslContext.getServerSessionContext().setSessionTimeout(-1);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+
+        SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+        assertSSLSessionContextSize(1, s.c.sslContext.getClientSessionContext());
+        assertSSLSessionContextSize(1, s.c.sslContext.getServerSessionContext());
+        Thread.sleep(1 * 1000);
+        s.c.sslContext.getClientSessionContext().setSessionTimeout(1);
+        s.c.sslContext.getServerSessionContext().setSessionTimeout(1);
+        assertSSLSessionContextSize(0, s.c.sslContext.getClientSessionContext());
+        assertSSLSessionContextSize(0, s.c.sslContext.getServerSessionContext());
+    }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionTest.java
new file mode 100644
index 0000000..020cd41
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSessionTest.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+public class SSLSessionTest extends TestCase {
+
+    public static final class Helper {
+
+        /**
+         * An invalid session that is not connected
+         */
+        public final SSLSession invalid;
+
+        /**
+         * The server side of a connected session
+         */
+        public final SSLSession server;
+
+        /**
+         * The client side of a connected session
+         */
+        public final SSLSession client;
+
+        /**
+         * The associated SSLSocketTest.Helper that is the source of
+         * the client and server SSLSessions.
+         */
+        public final SSLSocketTest.Helper s;
+
+        private Helper(SSLSession invalid,
+                       SSLSession server,
+                       SSLSession client,
+                       SSLSocketTest.Helper s) {
+            this.invalid = invalid;
+            this.server = server;
+            this.client = client;
+            this.s = s;
+        }
+
+        public static final Helper create() {
+            try {
+                SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+                SSLSocket ssl = (SSLSocket) sf.createSocket();
+                SSLSession invalid = ssl.getSession();
+                SSLSocketTest.Helper s = SSLSocketTest.Helper.create_workaround();
+                return new Helper(invalid, s.server.getSession(), s.client.getSession(), s);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+
+    public void test_SSLSocket_Helper_create() {
+        Helper s = Helper.create();
+        assertNotNull(s.invalid);
+        assertFalse(s.invalid.isValid());
+        assertTrue(s.server.isValid());
+        assertTrue(s.client.isValid());
+    }
+
+    public void test_SSLSession_getApplicationBufferSize() {
+        Helper s = Helper.create();
+        assertTrue(s.invalid.getApplicationBufferSize() > 0);
+        assertTrue(s.server.getApplicationBufferSize() > 0);
+        assertTrue(s.client.getApplicationBufferSize() > 0);
+    }
+
+    @KnownFailure("Expected SSL_NULL_WITH_NULL_NULL but received TLS_NULL_WITH_NULL_NULL")
+    public void test_SSLSession_getCipherSuite() {
+        Helper s = Helper.create();
+        assertNotNull(s.invalid.getCipherSuite());
+        assertEquals("SSL_NULL_WITH_NULL_NULL", s.invalid.getCipherSuite());
+        assertNotNull(s.server.getCipherSuite());
+        assertNotNull(s.client.getCipherSuite());
+        assertEquals(s.server.getCipherSuite(),
+                     s.client.getCipherSuite());
+    }
+
+    public void test_SSLSession_getCreationTime() {
+        Helper s = Helper.create();
+        assertTrue(s.invalid.getCreationTime() > 0);
+        assertTrue(s.server.getCreationTime() > 0);
+        assertTrue(s.client.getCreationTime() > 0);
+        assertTrue(Math.abs(s.server.getCreationTime() - s.client.getCreationTime()) < 1 * 1000);
+    }
+
+    public void test_SSLSession_getId() {
+        Helper s = Helper.create();
+        assertNotNull(s.invalid.getId());
+        assertNotNull(s.server.getId());
+        assertNotNull(s.client.getId());
+        assertEquals(0, s.invalid.getId().length);
+        assertEquals(32, s.server.getId().length);
+        assertEquals(32, s.client.getId().length);
+        assertTrue(Arrays.equals(s.server.getId(), s.client.getId()));
+    }
+
+    public void test_SSLSession_getLastAccessedTime() {
+        Helper s = Helper.create();
+        assertTrue(s.invalid.getLastAccessedTime() > 0);
+        assertTrue(s.server.getLastAccessedTime() > 0);
+        assertTrue(s.client.getLastAccessedTime() > 0);
+        assertTrue(Math.abs(s.server.getLastAccessedTime() -
+                            s.client.getLastAccessedTime()) < 1 * 1000);
+        assertTrue(s.server.getLastAccessedTime() >=
+                   s.server.getCreationTime());
+        assertTrue(s.client.getLastAccessedTime() >=
+                   s.client.getCreationTime());
+    }
+
+    public void test_SSLSession_getLocalCertificates() throws Exception {
+        Helper s = Helper.create();
+        assertNull(s.invalid.getLocalCertificates());
+        assertNull(s.client.getLocalCertificates());
+        assertNotNull(s.server.getLocalCertificates());
+        assertEquals(1, s.server.getLocalCertificates().length);
+        assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias),
+                     s.server.getLocalCertificates()[0]);
+    }
+
+    public void test_SSLSession_getLocalPrincipal() throws Exception {
+        Helper s = Helper.create();
+        assertNull(s.invalid.getLocalPrincipal());
+        assertNull(s.client.getLocalPrincipal());
+        assertNotNull(s.server.getLocalPrincipal());
+        assertNotNull(s.server.getLocalPrincipal().getName());
+        X509Certificate x509certificate = (X509Certificate)
+            s.s.c.keyStore.getCertificate(s.s.c.publicAlias);
+        assertEquals(x509certificate.getSubjectDN().getName(),
+                     s.server.getLocalPrincipal().getName());
+    }
+
+    public void test_SSLSession_getPacketBufferSize() {
+        Helper s = Helper.create();
+        assertTrue(s.invalid.getPacketBufferSize() > 0);
+        assertTrue(s.server.getPacketBufferSize() > 0);
+        assertTrue(s.client.getPacketBufferSize() > 0);
+    }
+
+    public void test_SSLSession_getPeerCertificateChain() throws Exception {
+        Helper s = Helper.create();
+        try {
+            s.invalid.getPeerCertificateChain();
+            fail();
+        } catch (SSLPeerUnverifiedException e) {
+        }
+        assertNotNull(s.client.getPeerCertificates());
+        assertEquals(1, s.client.getPeerCertificates().length);
+        assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias),
+                     s.client.getPeerCertificates()[0]);
+        try {
+            assertNull(s.server.getPeerCertificates());
+            fail();
+        } catch (SSLPeerUnverifiedException e) {
+        }
+    }
+
+    public void test_SSLSession_getPeerCertificates() throws Exception {
+        Helper s = Helper.create();
+        try {
+            s.invalid.getPeerCertificates();
+            fail();
+        } catch (SSLPeerUnverifiedException e) {
+        }
+        assertNotNull(s.client.getPeerCertificates());
+        assertEquals(1, s.client.getPeerCertificates().length);
+        assertEquals(s.s.c.keyStore.getCertificate(s.s.c.publicAlias),
+                     s.client.getPeerCertificates()[0]);
+        try {
+            s.server.getPeerCertificates();
+            fail();
+        } catch (SSLPeerUnverifiedException e) {
+        }
+    }
+
+    public void test_SSLSession_getPeerHost() {
+        Helper s = Helper.create();
+        assertNull(s.invalid.getPeerHost());
+        assertNotNull(s.server.getPeerHost());
+        assertNotNull(s.client.getPeerHost());
+    }
+
+    public void test_SSLSession_getPeerPort() {
+        Helper s = Helper.create();
+        assertEquals(-1, s.invalid.getPeerPort());
+        assertTrue(s.server.getPeerPort() > 0);
+        assertEquals(s.s.c.port, s.client.getPeerPort());
+    }
+
+    public void test_SSLSession_getPeerPrincipal() throws Exception {
+        Helper s = Helper.create();
+        try {
+            s.invalid.getPeerPrincipal();
+            fail();
+        } catch (SSLPeerUnverifiedException e) {
+        }
+        try {
+            s.server.getPeerPrincipal();
+            fail();
+        } catch (SSLPeerUnverifiedException e) {
+        }
+        assertNotNull(s.client.getPeerPrincipal());
+        assertNotNull(s.client.getPeerPrincipal().getName());
+        X509Certificate x509certificate = (X509Certificate)
+            s.s.c.keyStore.getCertificate(s.s.c.publicAlias);
+        assertEquals(x509certificate.getSubjectDN().getName(),
+                     s.client.getPeerPrincipal().getName());
+
+    }
+
+    public void test_SSLSession_getProtocol() {
+        Helper s = Helper.create();
+        assertNotNull(s.invalid.getProtocol());
+        assertEquals("NONE", s.invalid.getProtocol());
+        assertNotNull(s.server.getProtocol());
+        assertNotNull(s.client.getProtocol());
+        assertEquals(s.server.getProtocol(),
+                     s.client.getProtocol());
+    }
+
+    public void test_SSLSession_getSessionContext() {
+        Helper s = Helper.create();
+        assertNull(s.invalid.getSessionContext());
+        assertNotNull(s.server.getSessionContext());
+        assertNotNull(s.client.getSessionContext());
+        assertEquals(s.s.c.sslContext.getServerSessionContext(),
+                     s.server.getSessionContext());
+        assertEquals(s.s.c.sslContext.getClientSessionContext(),
+                     s.client.getSessionContext());
+        assertNotSame(s.server.getSessionContext(),
+                      s.client.getSessionContext());
+    }
+
+    public void test_SSLSession_getValue() {
+        Helper s = Helper.create();
+        try {
+            s.invalid.getValue(null);
+        } catch (IllegalArgumentException e) {
+        }
+        assertNull(s.invalid.getValue("BOGUS"));
+    }
+
+    public void test_SSLSession_getValueNames() {
+        Helper s = Helper.create();
+        assertNotNull(s.invalid.getValueNames());
+        assertEquals(0, s.invalid.getValueNames().length);
+    }
+
+    public void test_SSLSession_invalidate() {
+        Helper s = Helper.create();
+        assertFalse(s.invalid.isValid());
+        s.invalid.invalidate();
+        assertFalse(s.invalid.isValid());
+        assertNull(s.invalid.getSessionContext());
+
+        assertTrue(s.server.isValid());
+        s.server.invalidate();
+        assertFalse(s.server.isValid());
+        assertNull(s.server.getSessionContext());
+
+        assertTrue(s.client.isValid());
+        s.client.invalidate();
+        assertFalse(s.client.isValid());
+        assertNull(s.client.getSessionContext());
+    }
+
+    public void test_SSLSession_isValid() {
+        Helper s = Helper.create();
+        assertFalse(s.invalid.isValid());
+        assertTrue(s.server.isValid());
+        assertTrue(s.client.isValid());
+    }
+
+    public void test_SSLSession_putValue() {
+        Helper s = Helper.create();
+        String key = "KEY";
+        String value = "VALUE";
+        assertNull(s.invalid.getValue(key));
+        assertEquals(0, s.invalid.getValueNames().length);
+        s.invalid.putValue(key, value);
+        assertSame(value, s.invalid.getValue(key));
+        assertEquals(1, s.invalid.getValueNames().length);
+        assertEquals(key, s.invalid.getValueNames()[0]);
+    }
+
+    public void test_SSLSession_removeValue() {
+        Helper s = Helper.create();
+        String key = "KEY";
+        String value = "VALUE";
+        s.invalid.putValue(key, value);
+        assertEquals(1, s.invalid.getValueNames().length);
+        assertEquals(key, s.invalid.getValueNames()[0]);
+        s.invalid.removeValue(key);
+        assertNull(s.invalid.getValue(key));
+        assertEquals(0, s.invalid.getValueNames().length);
+    }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
new file mode 100644
index 0000000..5ccae7f
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.ServerSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import junit.framework.TestCase;
+
+public class SSLSocketFactoryTest extends TestCase {
+    public void test_SSLSocketFactory_getDefault() {
+        SocketFactory sf = SSLSocketFactory.getDefault();
+        assertNotNull(sf);
+        assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
+    }
+
+    public void test_SSLSocketFactory_getDefaultCipherSuites() {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        String[] cs = sf.getDefaultCipherSuites();
+        assertNotNull(cs);
+        assertTrue(cs.length != 0);
+    }
+
+    public void test_SSLSocketFactory_getSupportedCipherSuites() {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        String[] cs = sf.getSupportedCipherSuites();
+        assertNotNull(cs);
+        assertTrue(cs.length != 0);
+    }
+
+    @KnownFailure("Should not parse bogus port number -1 during createSocket")
+    public void test_SSLSocketFactory_createSocket() throws Exception {
+        try {
+            SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            Socket s = sf.createSocket(null, null, -1, false);
+            fail();
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            Socket ssl = sf.createSocket(new Socket(), null, -1, false);
+            fail();
+        } catch (SocketException e) {
+        }
+
+        ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0);
+        InetSocketAddress sa = (InetSocketAddress) ss.getLocalSocketAddress();
+        InetAddress host = sa.getAddress();
+        int port = sa.getPort();
+        Socket s = new Socket(host, port);
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        Socket ssl = sf.createSocket(s, null, -1, false);
+        assertNotNull(ssl);
+        assertTrue(SSLSocket.class.isAssignableFrom(ssl.getClass()));
+    }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
new file mode 100644
index 0000000..d02aeee
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.SecureRandom;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+import junit.framework.TestCase;
+
+public class SSLSocketTest extends TestCase {
+
+    public void test_SSLSocket_getSupportedCipherSuites() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] cs = ssl.getSupportedCipherSuites();
+        assertNotNull(cs);
+        assertTrue(cs.length != 0);
+    }
+
+    public void test_SSLSocket_getEnabledCipherSuites() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] cs = ssl.getEnabledCipherSuites();
+        assertNotNull(cs);
+        assertTrue(cs.length != 0);
+    }
+
+    @KnownFailure("Should support disabling all cipher suites")
+    public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+
+        try {
+            ssl.setEnabledCipherSuites(null);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            ssl.setEnabledCipherSuites(new String[1]);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            ssl.setEnabledCipherSuites(new String[] { "Bogus" } );
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+
+        ssl.setEnabledCipherSuites(new String[0]);
+        ssl.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
+        ssl.setEnabledCipherSuites(ssl.getSupportedCipherSuites());
+    }
+
+    public void test_SSLSocket_getSupportedProtocols() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] p = ssl.getSupportedProtocols();
+        assertNotNull(p);
+        assertTrue(p.length != 0);
+    }
+
+    public void test_SSLSocket_getEnabledProtocols() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        String[] p = ssl.getEnabledProtocols();
+        assertNotNull(p);
+        assertTrue(p.length != 0);
+    }
+
+    @KnownFailure("Should thow IllegalArgumentException not NullPointerException on null enabled protocols argument")
+    public void test_SSLSocket_setEnabledProtocols() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+
+        try {
+            ssl.setEnabledProtocols(null);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            ssl.setEnabledProtocols(new String[1]);
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        try {
+            ssl.setEnabledProtocols(new String[] { "Bogus" } );
+            fail();
+        } catch (IllegalArgumentException e) {
+        }
+        ssl.setEnabledProtocols(new String[0]);
+        ssl.setEnabledProtocols(ssl.getEnabledProtocols());
+        ssl.setEnabledProtocols(ssl.getSupportedProtocols());
+    }
+
+    @KnownFailure("session of unconnected socket should not be valid")
+    public void test_SSLSocket_getSession() throws Exception {
+        SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket ssl = (SSLSocket) sf.createSocket();
+        SSLSession session = ssl.getSession();
+        assertNotNull(session);
+        assertFalse(session.isValid());
+    }
+
+    @KnownFailure("Implementation should not start handshake in ServerSocket.accept")
+    public void test_SSLSocket_startHandshake() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        if (!SSLContextTest.IS_RI) {
+            /*
+             * The following hangs in accept in the Dalvik
+             * implementation because accept is also incorrectly
+             * starting the handhake.
+            */
+            c.serverSocket.setSoTimeout(1 * 1000);
+            /*
+             * That workaround doesn't seem to work so...
+             *
+             * See test_SSLSocket_startHandshake_workaround for
+             * redundant version of this test that works around this
+             * issue.
+             */
+            fail();
+        }
+        final SSLSocket server = (SSLSocket) c.serverSocket.accept();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    server.startHandshake();
+                    assertNotNull(server.getSession());
+                    try {
+                        server.getSession().getPeerCertificates();
+                        fail();
+                    } catch (SSLPeerUnverifiedException e) {
+                    }
+                    Certificate[] localCertificates = server.getSession().getLocalCertificates();
+                    assertNotNull(localCertificates);
+                    assertEquals(1, localCertificates.length);
+                    assertNotNull(localCertificates[0]);
+                    assertNotNull(localCertificates[0].equals(c.keyStore.getCertificate(c.privateAlias)));
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        client.startHandshake();
+        assertNotNull(client.getSession());
+        assertNull(client.getSession().getLocalCertificates());
+        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
+        assertNotNull(peerCertificates);
+        assertEquals(1, peerCertificates.length);
+        assertNotNull(peerCertificates[0]);
+        assertNotNull(peerCertificates[0].equals(c.keyStore.getCertificate(c.publicAlias)));
+        thread.join();
+    }
+
+    @KnownFailure("local certificates should be null as it should not have been requested by server")
+    public void test_SSLSocket_startHandshake_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    server.startHandshake();
+                    assertNotNull(server.getSession());
+                    try {
+                        server.getSession().getPeerCertificates();
+                        fail();
+                    } catch (SSLPeerUnverifiedException e) {
+                    }
+                    Certificate[] localCertificates = server.getSession().getLocalCertificates();
+                    assertNotNull(localCertificates);
+                    assertEquals(1, localCertificates.length);
+                    assertNotNull(localCertificates[0]);
+                    assertNotNull(localCertificates[0].equals(c.keyStore.getCertificate(c.privateAlias)));
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        client.startHandshake();
+        assertNotNull(client.getSession());
+        assertNull(client.getSession().getLocalCertificates());
+        Certificate[] peerCertificates = client.getSession().getPeerCertificates();
+        assertNotNull(peerCertificates);
+        assertEquals(1, peerCertificates.length);
+        assertNotNull(peerCertificates[0]);
+        assertNotNull(peerCertificates[0].equals(c.keyStore.getCertificate(c.publicAlias)));
+        thread.join();
+    }
+
+    @KnownFailure("Should throw SSLException on server, not IOException on client")
+    public void test_SSLSocket_startHandshake_noKeyStore_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create(null, null, null, null);
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    c.serverSocket.accept();
+                    fail();
+                } catch (SSLException e) {
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        if (!SSLContextTest.IS_RI) {
+            client.startHandshake();
+        }
+        thread.join();
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+     */
+    @KnownFailure("local certificates should be null as it should not have been requested by server")
+    public void test_SSLSocket_HandshakeCompletedListener_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    server.startHandshake();
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        final SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        final boolean[] handshakeCompletedListenerCalled = new boolean[1];
+        client.addHandshakeCompletedListener(new HandshakeCompletedListener() {
+            public void handshakeCompleted(HandshakeCompletedEvent event) {
+                try {
+                    SSLSession session = event.getSession();
+                    String cipherSuite = event.getCipherSuite();
+                    Certificate[] localCertificates = event.getLocalCertificates();
+                    Certificate[] peerCertificates = event.getPeerCertificates();
+                    javax.security.cert.X509Certificate[] peerCertificateChain = event.getPeerCertificateChain();
+                    Principal peerPrincipal = event.getPeerPrincipal();
+                    Principal localPrincipal = event.getLocalPrincipal();
+                    Socket socket = event.getSocket();
+
+                    if (false) {
+                        System.out.println("Session=" + session);
+                        System.out.println("CipherSuite=" + cipherSuite);
+                        System.out.println("LocalCertificates=" + localCertificates);
+                        System.out.println("PeerCertificates=" + peerCertificates);
+                        System.out.println("PeerCertificateChain=" + peerCertificateChain);
+                        System.out.println("PeerPrincipal=" + peerPrincipal);
+                        System.out.println("LocalPrincipal=" + localPrincipal);
+                        System.out.println("Socket=" + socket);
+                    }
+
+                    assertNotNull(session);
+                    byte[] id = session.getId();
+                    assertNotNull(id);
+                    assertEquals(32, id.length);
+                    assertNotNull(c.sslContext.getClientSessionContext().getSession(id));
+                    assertNotNull(c.sslContext.getServerSessionContext().getSession(id));
+
+                    assertNotNull(cipherSuite);
+                    assertTrue(Arrays.asList(client.getEnabledCipherSuites()).contains(cipherSuite));
+                    assertTrue(Arrays.asList(c.serverSocket.getEnabledCipherSuites()).contains(cipherSuite));
+
+                    Enumeration e = c.keyStore.aliases();
+                    Certificate certificate = null;
+                    Key key = null;
+                    while (e.hasMoreElements()) {
+                        String alias = (String) e.nextElement();
+                        if (c.keyStore.isCertificateEntry(alias)) {
+                            assertNull(certificate);
+                            certificate = c.keyStore.getCertificate(alias);
+                        } else if (c.keyStore.isKeyEntry(alias)) {
+                            assertNull(key);
+                            key = c.keyStore.getKey(alias, c.keyStorePassword);
+                        } else {
+                            fail();
+                        }
+                    }
+                    assertNotNull(certificate);
+                    assertNotNull(key);
+
+                    assertTrue(X509Certificate.class.isAssignableFrom(certificate.getClass()));
+                    X509Certificate x509certificate = (X509Certificate) certificate;
+
+                    assertNull(localCertificates);
+
+                    assertNotNull(peerCertificates);
+                    assertEquals(1, peerCertificates.length);
+                    assertNotNull(peerCertificates[0]);
+                    assertEquals(peerCertificates[0], x509certificate);
+
+                    assertNotNull(peerCertificateChain);
+                    assertEquals(1, peerCertificateChain.length);
+                    assertNotNull(peerCertificateChain[0]);
+                    assertEquals(x509certificate.getSubjectDN().getName(),
+                                 peerCertificateChain[0].getSubjectDN().getName());
+
+                    assertNotNull(peerPrincipal);
+                    assertEquals(x509certificate.getSubjectDN().getName(),
+                                 peerPrincipal.getName());
+
+                    assertNull(localPrincipal);
+
+                    assertNotNull(socket);
+                    assertSame(client, socket);
+
+                    synchronized (handshakeCompletedListenerCalled) {
+                        handshakeCompletedListenerCalled[0] = true;
+                        handshakeCompletedListenerCalled.notify();
+                    }
+                    handshakeCompletedListenerCalled[0] = true;
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        client.startHandshake();
+        thread.join();
+        synchronized (handshakeCompletedListenerCalled) {
+            while (!handshakeCompletedListenerCalled[0]) {
+                handshakeCompletedListenerCalled.wait();
+            }
+        }
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround.
+     * Technically this test shouldn't even need a second thread.
+     */
+    public void test_SSLSocket_getUseClientMode_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    assertFalse(server.getUseClientMode());
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        if (!SSLContextTest.IS_RI) {
+            client.startHandshake();
+        }
+        assertTrue(client.getUseClientMode());
+        thread.join();
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround.
+     * Technically this test shouldn't even need a second thread.
+     */
+    @KnownFailure("This test relies on socket timeouts which are not working. It also fails because ServerSocket.accept is handshaking")
+    public void test_SSLSocket_setUseClientMode_workaround() throws Exception {
+        // client is client, server is server
+        test_SSLSocket_setUseClientMode_workaround(true, false);
+        // client is server, server is client
+        test_SSLSocket_setUseClientMode_workaround(true, false);
+        // both are client
+        try {
+            test_SSLSocket_setUseClientMode_workaround(true, true);
+            fail();
+        } catch (SSLProtocolException e) {
+        }
+
+        // both are server
+        try {
+            test_SSLSocket_setUseClientMode_workaround(false, false);
+            fail();
+        } catch (SocketTimeoutException e) {
+        }
+    }
+
+    private void test_SSLSocket_setUseClientMode_workaround(final boolean clientClientMode,
+                                                            final boolean serverClientMode)
+            throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        final SSLProtocolException[] sslProtocolException = new SSLProtocolException[1];
+        final SocketTimeoutException[] socketTimeoutException = new SocketTimeoutException[1];
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    if (!serverClientMode) {
+                        server.setSoTimeout(1 * 1000);
+                        if (!SSLContextTest.IS_RI) {
+                            /* as above setSoTimeout isn't working in dalvikvm */
+                            fail();
+                        }
+                    }
+                    server.setUseClientMode(serverClientMode);
+                    server.startHandshake();
+                } catch (SSLProtocolException e) {
+                    sslProtocolException[0] = e;
+                } catch (SocketTimeoutException e) {
+                    socketTimeoutException[0] = e;
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        if (!clientClientMode) {
+            client.setSoTimeout(1 * 1000);
+            if (!SSLContextTest.IS_RI) {
+                /* as above setSoTimeout isn't working in dalvikvm */
+                fail();
+            }
+        }
+        client.setUseClientMode(clientClientMode);
+        client.startHandshake();
+        thread.join();
+        if (sslProtocolException[0] != null) {
+            throw sslProtocolException[0];
+        }
+        if (socketTimeoutException[0] != null) {
+            throw socketTimeoutException[0];
+        }
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+     */
+    public void test_SSLSocket_clientAuth_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    assertFalse(server.getWantClientAuth());
+                    assertFalse(server.getNeedClientAuth());
+
+                    // confirm turning one on by itself
+                    server.setWantClientAuth(true);
+                    assertTrue(server.getWantClientAuth());
+                    assertFalse(server.getNeedClientAuth());
+
+                    // confirm turning setting on toggles the other
+                    server.setNeedClientAuth(true);
+                    assertFalse(server.getWantClientAuth());
+                    assertTrue(server.getNeedClientAuth());
+
+                    // confirm toggling back
+                    server.setWantClientAuth(true);
+                    assertTrue(server.getWantClientAuth());
+                    assertFalse(server.getNeedClientAuth());
+
+                    server.startHandshake();
+
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        client.startHandshake();
+        assertNotNull(client.getSession().getLocalCertificates());
+        assertEquals(1, client.getSession().getLocalCertificates().length);
+        thread.join();
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+     * Technically this test shouldn't even need a second thread.
+     */
+    public void test_SSLSocket_getEnableSessionCreation_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    assertTrue(server.getEnableSessionCreation());
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        assertTrue(client.getEnableSessionCreation());
+        if (!SSLContextTest.IS_RI) {
+            client.startHandshake();
+        }
+        thread.join();
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+     */
+    @KnownFailure("Server side session creation disabling does not work, should throw SSLException, not fail")
+    public void test_SSLSocket_setEnableSessionCreation_server_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    server.setEnableSessionCreation(false);
+                    try {
+                        server.startHandshake();
+                        fail();
+                    } catch (SSLException e) {
+                    }
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLException e) {
+        }
+        thread.join();
+    }
+
+    /**
+     * Marked workaround because it avoid accepting on main thread like test_SSLSocket_startHandshake_workaround
+     */
+    @KnownFailure("Should throw SSLException on server, not IOException")
+    public void test_SSLSocket_setEnableSessionCreation_client_workaround() throws Exception {
+        final SSLContextTest.Helper c = SSLContextTest.Helper.create();
+        Thread thread = new Thread(new Runnable () {
+            public void run() {
+                try {
+                    SSLSocket server = (SSLSocket) c.serverSocket.accept();
+                    try {
+                        server.startHandshake();
+                        fail();
+                    } catch (SSLException e) {
+                    }
+                } catch (RuntimeException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+        thread.start();
+        SSLSocket client = (SSLSocket) c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+        client.setEnableSessionCreation(false);
+        try {
+            client.startHandshake();
+            fail();
+        } catch (SSLException e) {
+            if (!SSLContextTest.IS_RI) {
+                fail();
+            }
+        }
+        thread.join();
+    }
+
+    /**
+     * SSLSocketTest.Helper is a convenience class for other tests that
+     * want a pair of connected and handshaked client and server
+     * SSLSocketsfor testing so they don't have to duplicate the
+     * logic.
+     */
+    public static final class Helper {
+        public final SSLContextTest.Helper c;
+        public final SSLSocket server;
+        public final SSLSocket client;
+
+        private Helper (SSLContextTest.Helper c,
+                        SSLSocket server,
+                        SSLSocket client) {
+            this.c = c;
+            this.server = server;
+            this.client = client;
+        }
+
+        /**
+         * based on test_SSLSocket_startHandshake_workaround, should
+         * be written to non-workaround form when possible
+         */
+        public static Helper create_workaround () {
+            SSLContextTest.Helper c = SSLContextTest.Helper.create();
+            SSLSocket[] sockets = connect_workaround(c, null);
+            return new Helper(c, sockets[0], sockets[1]);
+        }
+
+        /**
+         * Create a new connected server/client socket pair within a
+         * existing SSLContext. Optional clientCipherSuites allows
+         * forcing new SSLSession to test SSLSessionContext caching
+         */
+        public static SSLSocket[] connect_workaround (final SSLContextTest.Helper c,
+                                                      String[] clientCipherSuites) {
+            try {
+                final SSLSocket[] server = new SSLSocket[1];
+                Thread thread = new Thread(new Runnable () {
+                    public void run() {
+                        try {
+                            server[0] = (SSLSocket) c.serverSocket.accept();
+                            server[0].startHandshake();
+                        } catch (RuntimeException e) {
+                            throw e;
+                        } catch (Exception e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
+                thread.start();
+                SSLSocket client = (SSLSocket)
+                    c.sslContext.getSocketFactory().createSocket(c.host, c.port);
+                if (clientCipherSuites != null) {
+                    client.setEnabledCipherSuites(clientCipherSuites);
+                }
+                client.startHandshake();
+                thread.join();
+                return new SSLSocket[] { server[0], client };
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void test_SSLSocketTest_Test_create() {
+        Helper test = Helper.create_workaround();
+        assertNotNull(test.c);
+        assertNotNull(test.server);
+        assertNotNull(test.client);
+        assertNotNull(test.server.isConnected());
+        assertNotNull(test.client.isConnected());
+        assertNotNull(test.server.getSession());
+        assertNotNull(test.client.getSession());
+    }
+}
diff --git a/luni/src/test/java/javax/xml/parsers/AllTests.java b/luni/src/test/java/javax/xml/parsers/AllTests.java
index 3e4a9c6..a838d3b 100644
--- a/luni/src/test/java/javax/xml/parsers/AllTests.java
+++ b/luni/src/test/java/javax/xml/parsers/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(javax.xml.parsers.DocumentBuilderTest.class);
         return suite;
     }
diff --git a/luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java b/luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java
new file mode 100644
index 0000000..3dc411e
--- /dev/null
+++ b/luni/src/test/java/org/apache/harmony/luni/internal/net/www/protocol/http/HeaderTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.luni.internal.net.www.protocol.http;
+
+import java.util.Arrays;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class HeaderTest extends junit.framework.TestCase {
+    // http://code.google.com/p/android/issues/detail?id=6684
+    public void test_caseInsensitiveButCasePreserving() {
+        Header h = new Header();
+        h.add("Content-Type", "text/plain");
+        // Case-insensitive:
+        assertEquals("text/plain", h.get("Content-Type"));
+        assertEquals("text/plain", h.get("Content-type"));
+        assertEquals("text/plain", h.get("content-type"));
+        assertEquals("text/plain", h.get("CONTENT-TYPE"));
+        // ...but case-preserving:
+        assertEquals("Content-Type", h.getFieldMap().keySet().toArray()[0]);
+        
+        // We differ from the RI in that the Map we return is also case-insensitive.
+        // Our behavior seems more consistent. (And code that works on the RI will work on Android.)
+        assertEquals(Arrays.asList("text/plain"), h.getFieldMap().get("Content-Type"));
+        assertEquals(Arrays.asList("text/plain"), h.getFieldMap().get("Content-type")); // RI fails this.
+    }
+
+    // The copy constructor used to be broken for headers with multiple values.
+    // http://code.google.com/p/android/issues/detail?id=6722
+    public void test_copyConstructor() {
+        Header h1 = new Header();
+        h1.add("key", "value1");
+        h1.add("key", "value2");
+        Header h2 = new Header(h1.getFieldMap());
+        assertEquals(2, h2.length());
+        assertEquals("key", h2.getKey(0));
+        assertEquals("value1", h2.get(0));
+        assertEquals("key", h2.getKey(1));
+        assertEquals("value2", h2.get(1));
+    }
+}
diff --git a/luni/src/test/java/org/apache/harmony/luni/platform/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/platform/AllTests.java
index be28d41..bfba0b5 100644
--- a/luni/src/test/java/org/apache/harmony/luni/platform/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/platform/AllTests.java
@@ -27,7 +27,7 @@
     }
     
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.apache.harmony.luni.platform");
+        TestSuite suite = new TestSuite("Tests for org.apache.harmony.luni.platform");
         
         suite.addTestSuite(OSMemoryTest.class);
         
diff --git a/luni/src/test/java/org/apache/harmony/luni/platform/OSMemoryTest.java b/luni/src/test/java/org/apache/harmony/luni/platform/OSMemoryTest.java
index a546289..fc34219 100644
--- a/luni/src/test/java/org/apache/harmony/luni/platform/OSMemoryTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/platform/OSMemoryTest.java
@@ -17,24 +17,12 @@
 
 package org.apache.harmony.luni.platform;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.AndroidOnly;
-
 import junit.framework.TestCase;
 
 /**
  * Tests org.apache.harmony.luni.platform.OSMemory (via IMemorySystem).
  */
-@TestTargetClass(org.apache.harmony.luni.platform.OSMemory.class)
 public class OSMemoryTest extends TestCase {
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "memset",
-        args = {}
-    )
     public void testMemset() {
         IMemorySystem memory = Platform.getMemorySystem();
         
@@ -62,12 +50,6 @@
         }
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "setIntArray",
-        args = {}
-    )
     public void testSetIntArray() {
         IMemorySystem memory = Platform.getMemorySystem();
         
@@ -115,12 +97,6 @@
                (((n >> 24) & 0xff) <<  0);
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "setShortArray",
-        args = {}
-    )
     public void testSetShortArray() {
         IMemorySystem memory = Platform.getMemorySystem();
         
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/AllTests.java
index 6b4cbd0..89faac1 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for HttpURLConnecton, HttpsURLConnection.");
+        TestSuite suite = new TestSuite("Tests for HttpURLConnecton, HttpsURLConnection.");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(HttpURLConnectionTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/AllTests.java
index a58850b..e03633d 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/AllTests.java
@@ -25,13 +25,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for HttpURLConnecton, HttpsURLConnection.");
+        TestSuite suite = new TestSuite("Tests for HttpURLConnecton, HttpsURLConnection.");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(HttpsURLConnectionTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
index e26cf74..4825cfb 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https/HttpsURLConnectionTest.java
@@ -147,9 +147,6 @@
         method = "setDefaultHostnameVerifier",
         args = {javax.net.ssl.HostnameVerifier.class}
     )
-    @KnownFailure("Handshake fails.")
-    @BrokenTest("Different behavior between cts host and run-core-test")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testHttpsConnection() throws Throwable {
         // set up the properties defining the default values needed by SSL stuff
         setUpStoreProperties();
@@ -202,9 +199,6 @@
             args = {int.class}
         )
     })
-    @KnownFailure("Handshake fails.")
-    @BrokenTest("Different behavior between cts host and run-core-test")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testHttpsConnection_Not_Found_Response() throws Throwable {
         // set up the properties defining the default values needed by SSL stuff
         setUpStoreProperties();
@@ -247,8 +241,6 @@
         method = "setDefaultSSLSocketFactory",
         args = {javax.net.ssl.SSLSocketFactory.class}
     )
-    @AndroidOnly("we only have a .bks key store in the test resources")
-    @KnownFailure("End to end test fails. No response data is transferred from server to client")
     public void testSetDefaultSSLSocketFactory() throws Throwable {
         // create the SSLServerSocket which will be used by server side
         SSLContext ctx = getContext();
@@ -304,8 +296,6 @@
         method = "setSSLSocketFactory",
         args = {javax.net.ssl.SSLSocketFactory.class}
     )
-    @AndroidOnly("we only have a .bks key store in the test resources")
-    @KnownFailure("End to end test fails. No response data is transferred from server to client")
     public void testSetSSLSocketFactory() throws Throwable {
         // create the SSLServerSocket which will be used by server side
         SSLContext ctx = getContext();
@@ -424,9 +414,6 @@
         method = "setHostnameVerifier",
         args = {javax.net.ssl.HostnameVerifier.class}
     )
-    @KnownFailure("Handshake fails.")
-    @BrokenTest("Different behavior between cts host and run-core-test")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testSetHostnameVerifier() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
@@ -470,9 +457,6 @@
         method = "setDoOutput",
         args = {boolean.class}
     )
-    @KnownFailure("Handshake fails.")
-    @BrokenTest("Different behavior between cts host and run-core-test")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void test_doOutput() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
@@ -523,8 +507,6 @@
             args = {int.class}
         )
     })
-    @KnownFailure("Handshake fails.")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testProxyConnection() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
@@ -576,8 +558,6 @@
             args = {int.class}
         )
     })
-    @KnownFailure("Handshake fails.")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testProxyAuthConnection() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
@@ -639,8 +619,6 @@
             args = {}
         )
     })
-    @KnownFailure("Handshake fails.")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testConsequentProxyConnection() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
@@ -707,8 +685,6 @@
             args = {boolean.class}
         )
     })
-    @KnownFailure("Handshake fails.")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testProxyAuthConnection_doOutput() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
@@ -825,8 +801,6 @@
             args = {int.class}
         )
     })
-    @KnownFailure("Handshake fails.")
-    @AndroidOnly("we only have a .bks key store in the test resources")
     public void testProxyConnection_Not_Found_Response() throws Throwable {
         // setting up the properties pointing to the key/trust stores
         setUpStoreProperties();
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
index 778e527..e266b7c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
@@ -31,7 +31,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.io");
+        TestSuite suite = new TestSuite("Tests for java.io");
 
         suite.addTestSuite(BufferedReaderTest.class);
         suite.addTestSuite(FilePermissionTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java
index 55e8c6f..6f0ef40 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/BufferedReaderTest.java
@@ -1,134 +1,592 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.CharArrayReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PipedReader;
+import java.io.Reader;
 import java.io.StringReader;
 
 import junit.framework.TestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-@TestTargetClass(BufferedReader.class)
+import tests.support.Support_StringReader;
+
 public class BufferedReaderTest extends TestCase {
 
-    /**
-     * @tests java.io.BufferedReader#read(char[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks exceptions.",
-        method = "read",
-        args = {char[].class, int.class, int.class}
-    )
-    public void test_read$CII() throws IOException {
-        char[] in = {'L', 'o', 'r', 'e', 'm'};
-        char[] ch = new char[3];
-        BufferedReader reader = new BufferedReader(new CharArrayReader(in));
-        
-        try {
-            reader.read(null, 1, 0);
-            fail("Test 1: NullPointerException expected.");
-        } catch (NullPointerException e) {
-            // Expected.
+	BufferedReader br;
+
+	String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+
+        /**
+         * The spec says that BufferedReader.readLine() considers only "\r", "\n"
+         * and "\r\n" to be line separators. We must not permit additional separator
+         * characters.
+        */
+        public void test_readLine_IgnoresEbcdic85Characters() throws IOException {
+            assertLines("A\u0085B", "A\u0085B");
         }
 
-        try {
-            reader.read(ch , -1, 1);
-            fail("Test 2: IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected.
-        }
-        
-        try {
-            reader.read(ch , 1, -1);
-            fail("Test 3: IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected.
+        public void test_readLine_Separators() throws IOException {
+            assertLines("A\nB\nC", "A", "B", "C");
+            assertLines("A\rB\rC", "A", "B", "C");
+            assertLines("A\r\nB\r\nC", "A", "B", "C");
+            assertLines("A\n\rB\n\rC", "A", "", "B", "", "C");
+            assertLines("A\n\nB\n\nC", "A", "", "B", "", "C");
+            assertLines("A\r\rB\r\rC", "A", "", "B", "", "C");
+            assertLines("A\n\n", "A", "");
+            assertLines("A\n\r", "A", "");
+            assertLines("A\r\r", "A", "");
+            assertLines("A\r\n", "A");
+            assertLines("A\r\n\r\n", "A", "");
         }
 
-        try {
-            reader.read(ch, 1, 3);
-            fail("Test 4: IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected.
+        private void assertLines(String in, String... lines) throws IOException {
+            BufferedReader bufferedReader
+                = new BufferedReader(new Support_StringReader(in));
+            for (String line : lines) {
+                assertEquals(line, bufferedReader.readLine());
+            }
+            assertNull(bufferedReader.readLine());
         }
 
-        reader.close();
-        try {
-            reader.read(ch, 1, 1);
-            fail("Test 5: IOException expected.");
-        } catch (IOException e) {
-            // Expected.
-        }
-    }
-    
-    /**
-     * @tests java.io.BufferedReader#mark(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "mark",
-        args = {int.class}
-    )
-    public void test_markI() throws IOException {
-        BufferedReader buf = new BufferedReader(new StringReader("01234"), 2);
+	/**
+	 * @tests java.io.BufferedReader#BufferedReader(java.io.Reader)
+	 */
+	public void test_ConstructorLjava_io_Reader() {
+		// Test for method java.io.BufferedReader(java.io.Reader)
+		assertTrue("Used in tests", true);
+	}
 
-        try {
-            buf.mark(-1);
-            fail("Test 1: IllegalArgumentException expected.");
-        } catch (IllegalArgumentException e) {
-            // Expected.
-        }
-               
-        buf.mark(3);
-        char[] chars = new char[3];
-        int result = buf.read(chars);
+	/**
+	 * @tests java.io.BufferedReader#BufferedReader(java.io.Reader, int)
+	 */
+	public void test_ConstructorLjava_io_ReaderI() {
+		// Test for method java.io.BufferedReader(java.io.Reader, int)
+		assertTrue("Used in tests", true);
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#close()
+	 */
+	public void test_close() {
+		// Test for method void java.io.BufferedReader.close()
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			br.close();
+			br.read();
+			fail("Read on closed stream");
+		} catch (IOException x) {
+			return;
+		}
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#mark(int)
+	 */
+	public void test_markI() throws IOException {
+		// Test for method void java.io.BufferedReader.mark(int)
+		char[] buf = null;
+		br = new BufferedReader(new Support_StringReader(testString));
+		br.skip(500);
+		br.mark(1000);
+		br.skip(250);
+		br.reset();
+		buf = new char[testString.length()];
+		br.read(buf, 0, 500);
+		assertTrue("Failed to set mark properly", testString.substring(500,
+				1000).equals(new String(buf, 0, 500)));
+
+		try {
+			br = new BufferedReader(new Support_StringReader(testString), 800);
+			br.skip(500);
+			br.mark(250);
+			br.read(buf, 0, 1000);
+			br.reset();
+			fail("Failed to invalidate mark properly");
+		} catch (IOException x) {
+		    // Expected
+		}
+
+		char[] chars = new char[256];
+		for (int i = 0; i < 256; i++)
+			chars[i] = (char) i;
+		Reader in = new BufferedReader(new Support_StringReader(new String(
+				chars)), 12);
+
+		in.skip(6);
+		in.mark(14);
+		in.read(new char[14], 0, 14);
+		in.reset();
+		assertTrue("Wrong chars", in.read() == (char) 6
+				&& in.read() == (char) 7);
+
+		in = new BufferedReader(new Support_StringReader(new String(chars)), 12);
+		in.skip(6);
+		in.mark(8);
+		in.skip(7);
+		in.reset();
+		assertTrue("Wrong chars 2", in.read() == (char) 6
+				&& in.read() == (char) 7);
+		
+        BufferedReader br = new BufferedReader(new StringReader("01234"), 2);
+        br.mark(3);
+        char[] carray = new char[3];
+        int result = br.read(carray);
         assertEquals(3, result);
-        assertEquals("Assert 0:", '0', chars[0]);
-        assertEquals("Assert 1:", '1', chars[1]);
-        assertEquals("Assert 2:", '2', chars[2]);
-        assertEquals("Assert 3:", '3', buf.read());
+        assertEquals("Assert 0:", '0', carray[0]);
+        assertEquals("Assert 1:", '1', carray[1]);
+        assertEquals("Assert 2:", '2', carray[2]);
+        assertEquals("Assert 3:", '3', br.read());
 
-        buf = new BufferedReader(new StringReader("01234"), 2);
-        buf.mark(3);
-        chars = new char[4];
-        result = buf.read(chars);
+        br = new BufferedReader(new StringReader("01234"), 2);
+        br.mark(3);
+        carray = new char[4];
+        result = br.read(carray);
         assertEquals("Assert 4:", 4, result);
-        assertEquals("Assert 5:", '0', chars[0]);
-        assertEquals("Assert 6:", '1', chars[1]);
-        assertEquals("Assert 7:", '2', chars[2]);
-        assertEquals("Assert 8:", '3', chars[3]);
-        assertEquals("Assert 9:", '4', buf.read());
-        assertEquals("Assert 10:", -1, buf.read());
+        assertEquals("Assert 5:", '0', carray[0]);
+        assertEquals("Assert 6:", '1', carray[1]);
+        assertEquals("Assert 7:", '2', carray[2]);
+        assertEquals("Assert 8:", '3', carray[3]);
+        assertEquals("Assert 9:", '4', br.read());
+        assertEquals("Assert 10:", -1, br.read());
 
         BufferedReader reader = new BufferedReader(new StringReader("01234"));
         reader.mark(Integer.MAX_VALUE);
         reader.read();
         reader.close();
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#markSupported()
+	 */
+	public void test_markSupported() {
+		// Test for method boolean java.io.BufferedReader.markSupported()
+		br = new BufferedReader(new Support_StringReader(testString));
+		assertTrue("markSupported returned false", br.markSupported());
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#read()
+	 */
+	public void test_read() throws IOException {
+		// Test for method int java.io.BufferedReader.read()
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			int r = br.read();
+			assertTrue("Char read improperly", testString.charAt(0) == r);
+			br = new BufferedReader(new Support_StringReader(new String(
+					new char[] { '\u8765' })));
+			assertTrue("Wrong double byte character", br.read() == '\u8765');
+		} catch (java.io.IOException e) {
+			fail("Exception during read test");
+		}
+
+		char[] chars = new char[256];
+		for (int i = 0; i < 256; i++)
+			chars[i] = (char) i;
+		Reader in = new BufferedReader(new Support_StringReader(new String(
+				chars)), 12);
+		try {
+			assertEquals("Wrong initial char", 0, in.read()); // Fill the
+			// buffer
+			char[] buf = new char[14];
+			in.read(buf, 0, 14); // Read greater than the buffer
+			assertTrue("Wrong block read data", new String(buf)
+					.equals(new String(chars, 1, 14)));
+			assertEquals("Wrong chars", 15, in.read()); // Check next byte
+		} catch (IOException e) {
+			fail("Exception during read test 2:" + e);
+		}
+		
+		// regression test for HARMONY-841
+		assertTrue(new BufferedReader(new CharArrayReader(new char[5], 1, 0), 2).read() == -1);
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#read(char[], int, int)
+	 */
+	public void test_read$CII() throws Exception{
+		char[] ca = new char[2];
+		BufferedReader toRet = new BufferedReader(new InputStreamReader(
+				new ByteArrayInputStream(new byte[0])));
+		
+		/* Null buffer should throw NPE even when len == 0 */
+		try {
+			toRet.read(null, 1, 0);
+			fail("null buffer reading zero bytes should throw NPE");
+		} catch (NullPointerException e) {
+			//expected
+		}
+		
+		try {
+			toRet.close();
+		} catch (IOException e) {
+			fail("unexpected 1: " + e);
+		}
+		
+		try {
+			toRet.read(null, 1, 0);
+			fail("null buffer reading zero bytes on closed stream should throw IOException");
+		} catch (IOException e) {
+			//expected
+		}
+
+		/* Closed reader should throw IOException reading zero bytes */
+		try {
+			toRet.read(ca, 0, 0);
+			fail("Reading zero bytes on a closed reader should not work");
+		} catch (IOException e) {
+			// expected
+		}
+
+		/*
+		 * Closed reader should throw IOException in preference to index out of
+		 * bounds
+		 */
+		try {
+			// Read should throw IOException before
+			// ArrayIndexOutOfBoundException
+			toRet.read(ca, 1, 5);
+			fail("IOException should have been thrown");
+		} catch (IOException e) {
+			// expected
+		}
+
+		// Test to ensure that a drained stream returns 0 at EOF
+		toRet = new BufferedReader(new InputStreamReader(
+				new ByteArrayInputStream(new byte[2])));
+		try {
+			assertEquals("Emptying the reader should return two bytes", 2,
+					toRet.read(ca, 0, 2));
+			assertEquals("EOF on a reader should be -1", -1, toRet.read(ca, 0,
+					2));
+			assertEquals("Reading zero bytes at EOF should work", 0, toRet
+					.read(ca, 0, 0));
+		} catch (IOException ex) {
+			fail("Unexpected IOException : " + ex.getLocalizedMessage());
+		}
+
+		// Test for method int java.io.BufferedReader.read(char [], int, int)
+		try {
+			char[] buf = new char[testString.length()];
+			br = new BufferedReader(new Support_StringReader(testString));
+			br.read(buf, 50, 500);
+			assertTrue("Chars read improperly", new String(buf, 50, 500)
+					.equals(testString.substring(0, 500)));
+		} catch (java.io.IOException e) {
+			fail("Exception during read test");
+		}
+
+		BufferedReader bufin = new BufferedReader(new Reader() {
+			int size = 2, pos = 0;
+
+			char[] contents = new char[size];
+
+			public int read() throws IOException {
+				if (pos >= size)
+					throw new IOException("Read past end of data");
+				return contents[pos++];
+			}
+
+			public int read(char[] buf, int off, int len) throws IOException {
+				if (pos >= size)
+					throw new IOException("Read past end of data");
+				int toRead = len;
+				if (toRead > (size - pos))
+					toRead = size - pos;
+				System.arraycopy(contents, pos, buf, off, toRead);
+				pos += toRead;
+				return toRead;
+			}
+
+			public boolean ready() throws IOException {
+				return size - pos > 0;
+			}
+
+			public void close() throws IOException {
+			}
+		});
+		try {
+			bufin.read();
+			int result = bufin.read(new char[2], 0, 2);
+			assertTrue("Incorrect result: " + result, result == 1);
+		} catch (IOException e) {
+			fail("Unexpected: " + e);
+		}
         
+        //regression for HARMONY-831
+        try{
+            new BufferedReader(new PipedReader(), 9).read(new char[] {}, 7, 0);
+            fail("should throw IndexOutOfBoundsException");
+        }catch(IndexOutOfBoundsException e){
+        }
+        
+        // Regression for HARMONY-54
+        char[] ch = {};
+        BufferedReader reader = new BufferedReader(new CharArrayReader(ch));
         try {
-            reader.mark(1);
-            fail("Test 2: IOException expected.");
+            // Check exception thrown when the reader is open.
+            reader.read(null, 1, 0);
+            fail("Assert 0: NullPointerException expected");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        // Now check IOException is thrown in preference to
+        // NullPointerexception when the reader is closed.
+        reader.close();
+        try {
+            reader.read(null, 1, 0);
+            fail("Assert 1: IOException expected");
         } catch (IOException e) {
-            // Expected.
+            // Expected
+        }
+
+        try {
+            // And check that the IOException is thrown before
+            // ArrayIndexOutOfBoundException
+            reader.read(ch, 0, 42);
+            fail("Assert 2: IOException expected");
+        } catch (IOException e) {
+            // expected
+        }
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#read(char[], int, int)
+	 */
+	public void test_read_$CII_Exception() throws IOException {
+		br = new BufferedReader(new Support_StringReader(testString));
+		char[] nullCharArray = null;
+		char[] charArray = testString.toCharArray();
+		
+		try {
+			br.read(nullCharArray, -1, -1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+		
+		try {
+			br.read(nullCharArray, -1, 0);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+
+		try {
+			br.read(nullCharArray, 0, -1);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+
+		try {
+			br.read(nullCharArray, 0, 0);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		
+		try {
+			br.read(nullCharArray, 0, 1);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		
+		try {
+			br.read(charArray, -1, -1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+
+		try {
+			br.read(charArray, -1, 0);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+
+		br.read(charArray, 0, 0);
+        br.read(charArray, 0, charArray.length);
+        br.read(charArray, charArray.length, 0);
+		
+		try {
+			br.read(charArray, charArray.length + 1, 0);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			//expected
+		}
+		
+		try {
+			br.read(charArray, charArray.length + 1, 1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			//expected
+		}
+
+		br.close();
+
+		try {
+			br.read(nullCharArray, -1, -1);
+			fail("should throw IOException");
+		} catch (IOException e) {
+			// expected
+		}
+
+		try {
+			br.read(charArray, -1, 0);
+			fail("should throw IOException");
+		} catch (IOException e) {
+			// expected
+		}
+
+		try {
+			br.read(charArray, 0, -1);
+			fail("should throw IOException");
+		} catch (IOException e) {
+			// expected
+		}
+	}
+	/**
+	 * @tests java.io.BufferedReader#readLine()
+	 */
+	public void test_readLine() {
+		// Test for method java.lang.String java.io.BufferedReader.readLine()
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			String r = br.readLine();
+			assertEquals("readLine returned incorrect string", "Test_All_Tests", r
+					);
+		} catch (java.io.IOException e) {
+			fail("Exception during readLine test");
+		}
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#ready()
+	 */
+	public void test_ready() {
+		// Test for method boolean java.io.BufferedReader.ready()
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			assertTrue("ready returned false", br.ready());
+		} catch (java.io.IOException e) {
+			fail("Exception during ready test" + e.toString());
+		}
+	}
+
+	/**
+	 * @tests java.io.BufferedReader#reset()
+	 */
+	public void test_reset() {
+		// Test for method void java.io.BufferedReader.reset()
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			br.skip(500);
+			br.mark(900);
+			br.skip(500);
+			br.reset();
+			char[] buf = new char[testString.length()];
+			br.read(buf, 0, 500);
+			assertTrue("Failed to reset properly", testString.substring(500,
+					1000).equals(new String(buf, 0, 500)));
+		} catch (java.io.IOException e) {
+			fail("Exception during reset test");
+		}
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			br.skip(500);
+			br.reset();
+			fail("Reset succeeded on unmarked stream");
+		} catch (IOException x) {
+			return;
+
+		}
+	}
+
+    public void test_reset_IOException() throws Exception {
+        int[] expected = new int[] { '1', '2', '3', '4', '5', '6', '7', '8',
+                '9', '0', -1 };
+        br = new BufferedReader(new Support_StringReader("1234567890"), 9);
+        br.mark(9);
+        for (int i = 0; i < 11; i++) {
+            assertEquals(expected[i], br.read());
+        }
+        try {
+            br.reset();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+        for (int i = 0; i < 11; i++) {
+            assertEquals(-1, br.read());
+        }
+
+        br = new BufferedReader(new Support_StringReader("1234567890"));
+        br.mark(10);
+        for (int i = 0; i < 10; i++) {
+            assertEquals(expected[i], br.read());
+        }
+        br.reset();
+        for (int i = 0; i < 11; i++) {
+            assertEquals(expected[i], br.read());
         }
     }
 
+	/**
+	 * @tests java.io.BufferedReader#skip(long)
+	 */
+	public void test_skipJ() {
+		// Test for method long java.io.BufferedReader.skip(long)
+		try {
+			br = new BufferedReader(new Support_StringReader(testString));
+			br.skip(500);
+			char[] buf = new char[testString.length()];
+			br.read(buf, 0, 500);
+			assertTrue("Failed to set skip properly", testString.substring(500,
+					1000).equals(new String(buf, 0, 500)));
+		} catch (java.io.IOException e) {
+			fail("Exception during skip test");
+		}
+
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+		try {
+			br.close();
+		} catch (Exception e) {
+		}
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FilePermissionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FilePermissionTest.java
index a358cc5..5b5a759 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FilePermissionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FilePermissionTest.java
@@ -1,41 +1,166 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
 import java.io.File;
 import java.io.FilePermission;
+import java.security.PermissionCollection;
 
 import junit.framework.TestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-@TestTargetClass(FilePermission.class)
+
 public class FilePermissionTest extends TestCase {
 
+    FilePermission readAllFiles = new FilePermission("<<ALL FILES>>", "read");
+
+    FilePermission alsoReadAllFiles = new FilePermission("<<ALL FILES>>",
+            "read");
+
+    FilePermission allInCurrent = new FilePermission("*",
+            "read, write, execute,delete");
+
+    FilePermission readInCurrent = new FilePermission("*", "read");
+
+    FilePermission readInFile = new FilePermission("aFile.file", "read");
+
+    FilePermission readInSubdir = new FilePermission("-", "read");
+
+    /**
+     * @tests java.io.FilePermission#FilePermission(java.lang.String,
+     *        java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+        assertTrue("Used to test", true);
+        FilePermission constructFile = new FilePermission("test constructor",
+                "write");
+        assertEquals(
+                "action given to the constructor did not correspond - constructor failed",
+                "write", constructFile.getActions());
+        assertTrue(
+                "name given to the constructor did not correspond - constructor failed",
+                constructFile.getName() == "test constructor");
+
+        // Regression test for HARMONY-1050
+        try {
+            new FilePermission(null, "drink");
+            fail("Expected IAE");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+
+        try {
+            new FilePermission(null, "read");
+            fail("Expected NPE");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            new FilePermission(null, null);
+            fail("Expected IAE");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.io.FilePermission#getActions()
+     */
+    public void test_getActions() {
+        assertEquals("getActions should have returned only read", "read",
+                readAllFiles.getActions());
+        assertEquals("getActions should have returned all actions",
+                "read,write,execute,delete", allInCurrent.getActions());
+    }
+
+    /**
+     * @tests java.io.FilePermission#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        assertTrue(
+                "Should not returned false when two instance of FilePermission is equal",
+                readAllFiles.equals(alsoReadAllFiles));
+        assertFalse(
+                "Should not returned true when two instance of FilePermission is not equal",
+                readInCurrent.equals(readInFile));
+    }
+
     /**
      * @tests java.io.FilePermission#implies(java.security.Permission)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "implies",
-        args = {java.security.Permission.class}
-    )
-    public void test_impliesLjava_io_FilePermission() {
+    public void test_impliesLjava_security_Permission() {
+        assertFalse("Should not return true for non-subset of actions", readAllFiles
+                .implies(allInCurrent));
+        assertFalse("Should not return true for non-subset of files", allInCurrent
+                .implies(readAllFiles));
+        assertTrue("Should not return false for subset of actions", allInCurrent
+                .implies(readInCurrent));
+        assertTrue("Should not return false for subset of files", readAllFiles
+                .implies(readInCurrent));
+        assertTrue("Should not return false for subset of files and actions",
+                allInCurrent.implies(readInFile));
+        assertTrue("Should not return false for equal FilePermissions", readAllFiles
+                .implies(alsoReadAllFiles));
+        assertTrue("Should not return false for subdir self", readInSubdir.implies(readInSubdir));
+        assertTrue("Should not return false for current self", readInCurrent.implies(readInCurrent));
+        assertTrue("Should not return false for subdir", readInSubdir.implies(readInCurrent));
+
+        FilePermission fp13 = new FilePermission(File.separator, "read");
+        FilePermission fp14 = new FilePermission(File.separator + "*", "read");
+        assertFalse("/ should not imply /*", fp13.implies(fp14));
+        fp14 = new FilePermission(File.separator + "-", "read");
+        assertFalse("/ should not imply /-", fp13.implies(fp14));
+
+        FilePermission fp3 = new FilePermission("/bob/*".replace('/',
+                File.separatorChar), "read,write");
+        FilePermission fp4 = new FilePermission("/bob/".replace('/',
+                File.separatorChar), "write");
+        assertFalse("Should not return true for same dir using * and not *", fp3
+                .implies(fp4));
+        FilePermission fp5 = new FilePermission("/bob/file".replace('/',
+                File.separatorChar), "write");
+        assertTrue("Should not return false for same dir using * and file", fp3
+                .implies(fp5));
+
+        FilePermission fp6 = new FilePermission("/bob/".replace('/',
+                File.separatorChar), "read,write");
+        FilePermission fp7 = new FilePermission("/bob/*".replace('/',
+                File.separatorChar), "write");
+        assertFalse("Should not return true for same dir using not * and *", fp6
+                .implies(fp7));
+        assertTrue("Should not return false for same subdir", fp6.implies(fp4));
+
+        FilePermission fp8 = new FilePermission("/".replace('/',
+                File.separatorChar), "read,write");
+        FilePermission fp9 = new FilePermission("/".replace('/',
+                File.separatorChar), "write");
+        assertTrue("Should not return false for same dir", fp8.implies(fp9));
+
+        FilePermission fp10 = new FilePermission("/".replace('/',
+                File.separatorChar), "read,write");
+        FilePermission fp11 = new FilePermission("/".replace('/',
+                File.separatorChar), "write");
+        assertTrue("Should not return false for same dir", fp10.implies(fp11));
+
+        FilePermission fp12 = new FilePermission("/*".replace('/',
+                File.separatorChar), "read,write");
+        assertFalse("Should not return true for same dir using * and dir", fp12
+                .implies(fp10));
+
         // Regression for HARMONY-47
         char separator = File.separatorChar;
         char nonSeparator = (separator == '/') ? '\\' : '/';
@@ -46,4 +171,52 @@
         fp1 = new FilePermission(nonSeparator + "-", "read");
         assertFalse("Assert 1: non-separator worked", fp1.implies(fp2));
     }
+
+    /**
+     * @tests java.io.FilePermission#newPermissionCollection()
+     */
+    public void test_newPermissionCollection() {
+        char s = File.separatorChar;
+        FilePermission perm[] = new FilePermission[4];
+        perm[0] = readAllFiles;
+        perm[1] = allInCurrent;
+        perm[2] = new FilePermission(s + "tmp" + s + "test" + s + "*",
+                "read,write");
+        perm[3] = new FilePermission(s + "tmp" + s + "test" + s
+                + "collection.file", "read");
+
+        PermissionCollection collect = perm[0].newPermissionCollection();
+        for (int i = 0; i < perm.length; i++) {
+            collect.add(perm[i]);
+        }
+        assertTrue("Should not return false for subset of files", collect
+                .implies(new FilePermission("*", "write")));
+        assertTrue("Should not return false for subset of name and action", collect
+                .implies(new FilePermission(s + "tmp", "read")));
+        assertTrue("Should not return false for non subset of file and action", collect
+                .implies(readInFile));
+
+        FilePermission fp1 = new FilePermission("/tmp/-".replace('/',
+                File.separatorChar), "read");
+        PermissionCollection fpc = fp1.newPermissionCollection();
+        fpc.add(fp1);
+        fpc.add(new FilePermission("/tmp/scratch/foo/*".replace('/',
+                File.separatorChar), "write"));
+        FilePermission fp2 = new FilePermission("/tmp/scratch/foo/file"
+                .replace('/', File.separatorChar), "read,write");
+        assertTrue("collection does not collate", fpc.implies(fp2));
+    }
+
+    /**
+     * @tests java.io.FilePermission#hashCode()
+     */
+    public void test_hashCode() {
+        assertTrue(
+                "two equal filePermission instances returned different hashCode",
+                readAllFiles.hashCode() == alsoReadAllFiles.hashCode());
+        assertTrue(
+                "two filePermission instances with same permission name returned same hashCode",
+                readInCurrent.hashCode() != allInCurrent.hashCode());
+
+    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
index 53ce506..8cae683 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
@@ -1,136 +1,1015 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
 import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamField;
+import java.io.RandomAccessFile;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
 
 import junit.framework.TestCase;
 
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import tests.util.TestEnvironment;
+import tests.support.Support_Exec;
+import tests.support.Support_PlatformFile;
 
-@TestTargetClass(File.class)
 public class FileTest extends TestCase {
+    
+    private static String platformId = "JDK"
+        + System.getProperty("java.vm.version").replace('.', '-');
+    
+    private static void deleteTempFolder(File dir) {
+        String files[] = dir.list();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                if (f.isDirectory()) {
+                    deleteTempFolder(f);
+                } else {
+                    f.delete();
+                }
+            }
+        }
+        dir.delete();
+    }
+    
+    private static String addTrailingSlash(String path) {
+        if (File.separatorChar == path.charAt(path.length() - 1)) {
+            return path;
+        }
+        return path + File.separator;
+    }
+    
+    /** Location to store tests in */
+    private File tempDirectory;
 
-    @Override protected void setUp() throws Exception {
-        super.setUp();
-        TestEnvironment.reset();
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_File\nTest_FileDescriptor\nTest_FileInputStream\nTest_FileNotFoundException\nTest_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
+    
+    protected void setUp() throws IOException {
+        /** Setup the temporary directory */
+        tempDirectory = new File(addTrailingSlash(System.getProperty("java.io.tmpdir")) + "harmony-test-" + getClass().getSimpleName() + File.separator);
+        tempDirectory.mkdirs();
     }
 
-    @Override protected void tearDown() throws Exception {
-        TestEnvironment.reset();
-        super.tearDown();
+    protected void tearDown() {
+        if (tempDirectory != null) {
+            deleteTempFolder(tempDirectory);
+            tempDirectory = null;
+        }
     }
 
     /**
      * @tests java.io.File#File(java.io.File, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "File",
-        args = {java.io.File.class, java.lang.String.class}
-    )
-    public void test_ConstructorLjava_io_FileLjava_lang_String() {
+    public void test_ConstructorLjava_io_FileLjava_lang_String0() {
+        File f = new File(tempDirectory.getPath(), "input.tst");
+        assertEquals("Created Incorrect File ", addTrailingSlash(tempDirectory.getPath()) + "input.tst", f.getPath());
+    }
+    
+    public void test_ConstructorLjava_io_FileLjava_lang_String1() {
+        try {
+            new File(tempDirectory, null);
+            fail("NullPointerException Not Thrown.");
+        } catch (NullPointerException e) {
+        }
+    }
+    
+    public void test_ConstructorLjava_io_FileLjava_lang_String2() throws IOException {
+        File f = new File((File)null, "input.tst");
+        assertEquals("Created Incorrect File", 
+                new File("input.tst").getAbsolutePath(), 
+                f.getAbsolutePath());
+    }
+    
+    public void test_ConstructorLjava_io_FileLjava_lang_String3() {
+        // Regression test for HARMONY-382
+        File f = new File("/abc");
+        File d = new File((File)null, "/abc");
+        assertEquals("Test3: Created Incorrect File",
+                     d.getAbsolutePath(), f.getAbsolutePath());
+    }
+    
+    public void test_ConstructorLjava_io_FileLjava_lang_String4() {
         // Regression test for HARMONY-21
         File path = new File("/dir/file");
         File root = new File("/");
         File file = new File(root, "/dir/file");
         assertEquals("Assert 1: wrong path result ", path.getPath(), file
                 .getPath());
-        assertFalse("Assert 1.1: path absolute ", new File("\\\\\\a\b").isAbsolute());
-        assertTrue("Assert 1.1: path absolute ", new File("///a/b").isAbsolute());
-
+        if (File.separatorChar == '\\') {
+            assertTrue("Assert 1.1: path not absolute ", new File("\\\\\\a\b")
+                       .isAbsolute());
+        } else {
+            assertFalse("Assert 1.1: path absolute ", new File("\\\\\\a\b")
+                       .isAbsolute());
+        }
+    }
+    
+    public void test_ConstructorLjava_io_FileLjava_lang_String5() {
         // Test data used in a few places below
-        String dirName = System.getProperty("java.io.tmpdir");
+        String dirName = tempDirectory.getPath();
         String fileName = "input.tst";
 
-        // change user.dir to a folder that's writeable on android.
-        String oldUserDir = System.getProperty("user.dir");
-        System.setProperty("user.dir", dirName);
-
         // Check filename is preserved correctly
         File d = new File(dirName);
         File f = new File(d, fileName);
-        if (!dirName
-                .regionMatches((dirName.length() - 1), File.separator, 0, 1)) {
-            dirName += File.separator;
-        }
+        dirName = addTrailingSlash(dirName);
         dirName += fileName;
-        assertTrue("Assert 2: Created incorrect file " + f.getPath(), f
-                .getPath().equals(dirName));
+        assertEquals("Assert 1: Created incorrect file ",
+                     dirName, f.getPath());
 
         // Check null argument is handled
         try {
             f = new File(d, null);
-            fail("Assert 3: NullPointerException not thrown.");
+            fail("Assert 2: NullPointerException not thrown.");
         } catch (NullPointerException e) {
             // Expected.
         }
-
-        f = new File((File) null, fileName);
-        assertEquals("Assert 4: Created incorrect file " + f.getPath(), dirName,
-                f.getAbsolutePath());
-
+    }
+    
+    public void test_ConstructorLjava_io_FileLjava_lang_String6() {
         // Regression for HARMONY-46
         File f1 = new File("a");
         File f2 = new File("a/");
-        assertEquals("Assert 5: Trailing slash file name is incorrect", f1, f2);
-
-        // reset user.dir
-        System.setProperty("user.dir", oldUserDir);
+        assertEquals("Trailing slash file name is incorrect", f1, f2);
     }
-    
-    /**
-     * @tests java.io.File#hashCode()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
-    public void test_hashCode() {
-        // Regression for HARMONY-53
-        String mixedFname = "SoMe FiLeNaMe";
-        File mfile = new File(mixedFname);
-        File lfile = new File(mixedFname.toLowerCase());
 
-        if (mfile.equals(lfile)) {
-            assertTrue("Assert 0: wrong hashcode", mfile.hashCode() == lfile.hashCode());
-        } else {
-            assertFalse("Assert 1: wrong hashcode", mfile.hashCode() == lfile.hashCode());
+    /**
+     * @tests java.io.File#File(java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_String() {
+        String fileName = null;
+        try {
+            new File(fileName);
+            fail("NullPointerException Not Thrown.");
+        } catch (NullPointerException e) {
+            // Expected
         }
+
+        fileName = addTrailingSlash(tempDirectory.getPath());
+        fileName += "input.tst";
+
+        File f = new File(fileName);
+        assertEquals("Created incorrect File", fileName, f.getPath());
+    }
+
+    /**
+     * @tests java.io.File#File(java.lang.String, java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String() throws IOException {
+        String dirName = null;
+        String fileName = "input.tst";
+        File f = new File(dirName, fileName);
+        assertEquals("Test 1: Created Incorrect File", 
+                new File("input.tst").getAbsolutePath(), 
+                f.getAbsolutePath());
+
+        dirName = tempDirectory.getPath();
+        fileName = null;
+        try {
+            f = new File(dirName, fileName);
+            fail("NullPointerException Not Thrown.");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        fileName = "input.tst";
+        f = new File(dirName, fileName);
+        assertEquals("Test 2: Created Incorrect File", 
+                addTrailingSlash(tempDirectory.getPath()) + "input.tst",
+                f.getPath());
+
+        // Regression test for HARMONY-382
+        String s = null;
+        f = new File("/abc");
+        File d = new File(s, "/abc");
+        assertEquals("Test3: Created Incorrect File", d.getAbsolutePath(), f
+                .getAbsolutePath());
+    }
+
+    /**
+     * @tests java.io.File#File(java.lang.String, java.lang.String)
+     */
+    public void test_Constructor_String_String_112270() {
+        File ref1 = new File("/dir1/file1");
+
+        File file1 = new File("/", "/dir1/file1");
+        assertEquals("wrong result 1", ref1.getPath(), file1.getPath());
+        File file2 = new File("/", "//dir1/file1");
+        assertEquals("wrong result 2", ref1.getPath(), file2.getPath());
+
+        if (File.separatorChar == '\\') {
+            File file3 = new File("\\", "\\dir1\\file1");
+            assertEquals("wrong result 3", ref1.getPath(), file3.getPath());
+            File file4 = new File("\\", "\\\\dir1\\file1");
+            assertEquals("wrong result 4", ref1.getPath(), file4.getPath());
+        }
+
+        File ref2 = new File("/lib/content-types.properties");
+        File file5 = new File("/", "lib/content-types.properties");
+        assertEquals("wrong result 5", ref2.getPath(), file5.getPath());
+    }
+
+    /**
+     * @tests java.io.File#File(java.io.File, java.lang.String)
+     */
+    public void test_Constructor_File_String_112270() {
+        File ref1 = new File("/dir1/file1");
+
+        File root = new File("/");
+        File file1 = new File(root, "/dir1/file1");
+        assertEquals("wrong result 1", ref1.getPath(), file1.getPath());
+        File file2 = new File(root, "//dir1/file1");
+        assertEquals("wrong result 2", ref1.getPath(), file2.getPath());
+
+        if (File.separatorChar == '\\') {
+            File file3 = new File(root, "\\dir1\\file1");
+            assertEquals("wrong result 3", ref1.getPath(), file3.getPath());
+            File file4 = new File(root, "\\\\dir1\\file1");
+            assertEquals("wrong result 4", ref1.getPath(), file4.getPath());
+        }
+
+        File ref2 = new File("/lib/content-types.properties");
+        File file5 = new File(root, "lib/content-types.properties");
+        assertEquals("wrong result 5", ref2.getPath(), file5.getPath());
+    }
+
+    /**
+     * @tests java.io.File#File(java.net.URI)
+     */
+    public void test_ConstructorLjava_net_URI() throws URISyntaxException {
+        URI uri = null;
+        try {
+            new File(uri);
+            fail("NullPointerException Not Thrown.");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        // invalid file URIs
+        String[] uris = new String[] { "mailto:user@domain.com", // not
+                // hierarchical
+                "ftp:///path", // not file scheme
+                "//host/path/", // not absolute
+                "file://host/path", // non empty authority
+                "file:///path?query", // non empty query
+                "file:///path#fragment", // non empty fragment
+                "file:///path?", "file:///path#" };
+
+        for (int i = 0; i < uris.length; i++) {
+            uri = new URI(uris[i]);
+            try {
+                new File(uri);
+                fail("Expected IllegalArgumentException for new File(" + uri
+                        + ")");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+        }
+
+        // a valid File URI
+        File f = new File(new URI("file:///pa%20th/another\u20ac/pa%25th"));
+        assertTrue("Created incorrect File " + f.getPath(), f.getPath().equals(
+                File.separator + "pa th" + File.separator + "another\u20ac" + File.separator + "pa%th"));
+    }
+
+    /**
+     * @tests java.io.File#canRead()
+     */
+    public void test_canRead() throws IOException {
+        // canRead only returns if the file exists so cannot be fully tested.
+        File f = new File(tempDirectory, platformId + "canRead.tst");
+        try {
+            FileOutputStream fos = new FileOutputStream(f);
+            fos.close();
+            assertTrue("canRead returned false", f.canRead());
+        } finally {
+            f.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#canWrite()
+     */
+    public void test_canWrite() throws IOException {
+        // canWrite only returns if the file exists so cannot be fully tested.
+        File f = new File(tempDirectory, platformId + "canWrite.tst");
+        try {
+            FileOutputStream fos = new FileOutputStream(f);
+            fos.close();
+            assertTrue("canWrite returned false", f.canWrite());
+        } finally {
+            f.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#compareTo(java.io.File)
+     */
+    public void test_compareToLjava_io_File() {
+        File f1 = new File("thisFile.file");
+        File f2 = new File("thisFile.file");
+        File f3 = new File("thatFile.file");
+        assertEquals("Equal files did not answer zero for compareTo", 0, f1
+                .compareTo(f2));
+        assertTrue("f3.compareTo(f1) did not result in value < 0", f3
+                .compareTo(f1) < 0);
+        assertTrue("f1.compareTo(f3) did not result in value > 0", f1
+                .compareTo(f3) > 0);
+    }
+
+    /**
+     * @tests java.io.File#createNewFile()
+     */
+    public void test_createNewFile_EmptyString() {
+        File f = new File("");
+        try {
+            f.createNewFile();
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.io.File#createNewFile()
+     */
+    public void test_createNewFile() throws IOException {
+        String base = tempDirectory.getPath();
+        boolean dirExists = true;
+        int numDir = 1;
+        File dir = new File(base, String.valueOf(numDir));
+        // Making sure that the directory does not exist.
+        while (dirExists) {
+            // If the directory exists, add one to the directory number
+            // (making it a new directory name.)
+            if (dir.exists()) {
+                numDir++;
+                dir = new File(base, String.valueOf(numDir));
+            } else {
+                dirExists = false;
+            }
+        }
+
+        // Test for trying to create a file in a directory that does not
+        // exist.
+        try {
+            // Try to create a file in a directory that does not exist
+            File f1 = new File(dir, "tempfile.tst");
+            f1.createNewFile();
+            fail("IOException not thrown");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        dir.mkdir();
+
+        File f1 = new File(dir, "tempfile.tst");
+        File f2 = new File(dir, "tempfile.tst");
+        f1.deleteOnExit();
+        f2.deleteOnExit();
+        dir.deleteOnExit();
+        assertFalse("File Should Not Exist", f1.isFile());
+        f1.createNewFile();
+        assertTrue("File Should Exist.", f1.isFile());
+        assertTrue("File Should Exist.", f2.isFile());
+        String dirName = f1.getParent();
+        if (!dirName.endsWith(File.separator)) {
+            dirName += File.separator;
+        }
+        assertEquals("File Saved To Wrong Directory.",
+                     dir.getPath() + File.separator, dirName);
+        assertEquals("File Saved With Incorrect Name.", "tempfile.tst",
+                     f1.getName());
+
+        // Test for creating a file that already exists.
+        assertFalse("File Already Exists, createNewFile Should Return False.",
+                f2.createNewFile());
+
+        // Test create an illegal file
+        String sep = File.separator;
+        f1 = new File(sep + "..");
+        try {
+            f1.createNewFile();
+            fail("should throw IOE");
+        } catch (IOException e) {
+            // expected;
+        }
+        f1 = new File(sep + "a" + sep + ".." + sep + ".." + sep);
+        try {
+            f1.createNewFile();
+            fail("should throw IOE");
+        } catch (IOException e) {
+            // expected;
+        }
+
+        // This test is invalid. createNewFile should return false
+        // not IOE when the file exists (in this case it exists and is
+        // a directory). TODO: We should probably replace this test
+        // with some that cover this behaviour. It might even be
+        // different on unix and windows since it directly reflects
+        // the open syscall behaviour.
+        //
+        // // Test create an exist path
+        // f1 = new File(base);
+        // try {
+        // assertFalse(f1.createNewFile());
+        // fail("should throw IOE");
+        // } catch (IOException e) {
+        // // expected;
+        // }
+    }
+
+    /**
+     * @tests java.io.File#createTempFile(java.lang.String, java.lang.String)
+     */
+    public void test_createTempFileLjava_lang_StringLjava_lang_String()
+            throws IOException {
+        // Error protection against using a suffix without a "."?
+        File f1 = null;
+        File f2 = null;
+        try {
+            f1 = File.createTempFile("harmony-test-FileTest_tempFile_abc", ".tmp");
+            f2 = File.createTempFile("harmony-test-FileTest_tempFile_tf", null);
+
+            String fileLocation = addTrailingSlash(f1.getParent());
+            
+            String tempDir = addTrailingSlash(System.getProperty("java.io.tmpdir"));
+            
+            assertEquals(
+                    "File did not save to the default temporary-file location.",
+                    tempDir, fileLocation);
+
+            // Test to see if correct suffix was used to create the tempfile.
+            File currentFile;
+            String fileName;
+            // Testing two files, one with suffix ".tmp" and one with null
+            for (int i = 0; i < 2; i++) {
+                currentFile = i == 0 ? f1 : f2;
+                fileName = currentFile.getPath();
+                assertTrue("File Created With Incorrect Suffix.", fileName
+                        .endsWith(".tmp"));
+            }
+
+            // Tests to see if the correct prefix was used to create the
+            // tempfiles.
+            fileName = f1.getName();
+            assertTrue("Test 1: File Created With Incorrect Prefix.", fileName
+                    .startsWith("harmony-test-FileTest_tempFile_abc"));
+            fileName = f2.getName();
+            assertTrue("Test 2: File Created With Incorrect Prefix.", fileName
+                    .startsWith("harmony-test-FileTest_tempFile_tf"));
+
+            // Tests for creating a tempfile with a filename shorter than 3
+            // characters.
+            try {
+                File f3 = File.createTempFile("ab", ".tst");
+                f3.delete();
+                fail("IllegalArgumentException Not Thrown.");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+            try {
+                File f3 = File.createTempFile("a", ".tst");
+                f3.delete();
+                fail("IllegalArgumentException Not Thrown.");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+            try {
+                File f3 = File.createTempFile("", ".tst");
+                f3.delete();
+                fail("IllegalArgumentException Not Thrown.");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+        } finally {
+            if (f1 != null) {
+                f1.delete();
+            }
+            if (f2 != null) {
+                f2.delete();
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.File#createTempFile(java.lang.String, java.lang.String,
+     *        java.io.File)
+     */
+    public void test_createTempFileLjava_lang_StringLjava_lang_StringLjava_io_File()
+            throws IOException {
+        File f1 = null;
+        File f2 = null;
+        String base = System.getProperty("java.io.tmpdir");
+        try {
+            // Test to make sure that the tempfile was saved in the correct
+            // location and with the correct prefix/suffix.
+            f1 = File.createTempFile("harmony-test-FileTest_tempFile2_tf", null, null);
+            File dir = new File(base);
+            f2 = File.createTempFile("harmony-test-FileTest_tempFile2_tf", ".tmp", dir);
+            File currentFile;
+            String fileLocation;
+            String fileName;
+            for (int i = 0; i < 2; i++) {
+                currentFile = i == 0 ? f1 : f2;
+                fileLocation = addTrailingSlash(currentFile.getParent());
+                base = addTrailingSlash(base);
+                assertEquals(
+                        "File not created in the default temporary-file location.",
+                        base, fileLocation);
+                fileName = currentFile.getName();
+                assertTrue("File created with incorrect suffix.", fileName
+                        .endsWith(".tmp"));
+                assertTrue("File created with incorrect prefix.", fileName
+                        .startsWith("harmony-test-FileTest_tempFile2_tf"));
+                currentFile.delete();
+            }
+
+            // Test for creating a tempfile in a directory that does not exist.
+            int dirNumber = 1;
+            boolean dirExists = true;
+            // Set dir to a non-existent directory inside the temporary
+            // directory
+            dir = new File(base, String.valueOf(dirNumber));
+            // Making sure that the directory does not exist.
+            while (dirExists) {
+                // If the directory exists, add one to the directory number
+                // (making it
+                // a new directory name.)
+                if (dir.exists()) {
+                    dirNumber++;
+                    dir = new File(base, String.valueOf(dirNumber));
+                } else {
+                    dirExists = false;
+                }
+            }
+            try {
+                // Try to create a file in a directory that does not exist
+                File f3 = File.createTempFile("harmony-test-FileTest_tempFile2_tf", null, dir);
+                f3.delete();
+                fail("IOException not thrown");
+            } catch (IOException e) {
+                // Expected
+            }
+            dir.delete();
+
+            // Tests for creating a tempfile with a filename shorter than 3
+            // characters.
+            try {
+                File f4 = File.createTempFile("ab", null, null);
+                f4.delete();
+                fail("IllegalArgumentException not thrown.");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+            try {
+                File f4 = File.createTempFile("a", null, null);
+                f4.delete();
+                fail("IllegalArgumentException not thrown.");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+            try {
+                File f4 = File.createTempFile("", null, null);
+                f4.delete();
+                fail("IllegalArgumentException not thrown.");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+        } finally {
+            if (f1 != null) {
+                f1.delete();
+            }
+            if (f2 != null) {
+                f1.delete();
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.File#delete()
+     */
+    public void test_delete() throws IOException {
+        File dir = new File(tempDirectory, platformId
+                + "filechk");
+        dir.mkdir();
+        assertTrue("Directory does not exist", dir.exists());
+        assertTrue("Directory is not directory", dir.isDirectory());
+        File f = new File(dir, "filechk.tst");
+        FileOutputStream fos = new FileOutputStream(f);
+        fos.close();
+        assertTrue("Error Creating File For Delete Test", f.exists());
+        dir.delete();
+        assertTrue("Directory Should Not Have Been Deleted.", dir.exists());
+        f.delete();
+        assertTrue("File Was Not Deleted", !f.exists());
+        dir.delete();
+        assertTrue("Directory Was Not Deleted", !dir.exists());
+    }
+
+    // GCH
+    // TODO : This test passes on Windows but fails on Linux with a
+    // java.lang.NoClassDefFoundError. Temporarily removing from the test
+    // suite while I investigate the cause.
+    // /**
+    // * @tests java.io.File#deleteOnExit()
+    // */
+    // public void test_deleteOnExit() {
+    // File f1 = new File(System.getProperty("java.io.tmpdir"), platformId
+    // + "deleteOnExit.tst");
+    // try {
+    // FileOutputStream fos = new FileOutputStream(f1);
+    // fos.close();
+    // } catch (IOException e) {
+    // fail("Unexpected IOException During Test : " + e.getMessage());
+    // }
+    // assertTrue("File Should Exist.", f1.exists());
+    //
+    // try {
+    // Support_Exec.execJava(new String[] {
+    // "tests.support.Support_DeleteOnExitTest", f1.getPath() },
+    // null, true);
+    // } catch (IOException e) {
+    // fail("Unexpected IOException During Test + " + e.getMessage());
+    // } catch (InterruptedException e) {
+    // fail("Unexpected InterruptedException During Test: " + e);
+    // }
+    //
+    // boolean gone = !f1.exists();
+    // f1.delete();
+    // assertTrue("File Should Already Be Deleted.", gone);
+    // }
+
+    /**
+     * @tests java.io.File#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() throws IOException {
+        File f1 = new File("filechk.tst");
+        File f2 = new File("filechk.tst");
+        File f3 = new File("xxxx");
+
+        assertTrue("Equality test failed", f1.equals(f2));
+        assertTrue("Files Should Not Return Equal.", !f1.equals(f3));
+
+        f3 = new File("FiLeChK.tst");
+        boolean onWindows = File.separatorChar == '\\';
+        boolean onUnix = File.separatorChar == '/';
+        if (onWindows) {
+            assertTrue("Files Should Return Equal.", f1.equals(f3));
+        } else if (onUnix) {
+            assertTrue("Files Should NOT Return Equal.", !f1.equals(f3));
+        }
+
+        f1 = new File(tempDirectory, "casetest.tmp");
+        f2 = new File(tempDirectory, "CaseTest.tmp");
+        new FileOutputStream(f1).close(); // create the file
+        if (f1.equals(f2)) {
+            try {
+                FileInputStream fis = new FileInputStream(f2);
+                fis.close();
+            } catch (IOException e) {
+                fail("File system is case sensitive");
+            }
+        } else {
+            boolean exception = false;
+            try {
+                FileInputStream fis = new FileInputStream(f2);
+                fis.close();
+            } catch (IOException e) {
+                exception = true;
+            }
+            assertTrue("File system is case insensitive", exception);
+        }
+        f1.delete();
+    }
+
+    /**
+     * @tests java.io.File#exists()
+     */
+    public void test_exists() throws IOException {
+        File f = new File(tempDirectory, platformId
+                + "exists.tst");
+        assertTrue("Exists returned true for non-existent file", !f.exists());
+        FileOutputStream fos = new FileOutputStream(f);
+        fos.close();
+        assertTrue("Exists returned false file", f.exists());
+        f.delete();
+    }
+
+    /**
+     * @tests java.io.File#getAbsoluteFile()
+     */
+    public void test_getAbsoluteFile() {
+        String base = addTrailingSlash(tempDirectory.getPath());
+        File f = new File(base, "temp.tst");
+        File f2 = f.getAbsoluteFile();
+        assertEquals("Test 1: Incorrect File Returned.", 0, f2.compareTo(f
+                .getAbsoluteFile()));
+        f = new File(base + "Temp" + File.separator + File.separator + "temp.tst");
+        f2 = f.getAbsoluteFile();
+        assertEquals("Test 2: Incorrect File Returned.", 0, f2.compareTo(f
+                .getAbsoluteFile()));
+        f = new File(base + File.separator + ".." + File.separator + "temp.tst");
+        f2 = f.getAbsoluteFile();
+        assertEquals("Test 3: Incorrect File Returned.", 0, f2.compareTo(f
+                .getAbsoluteFile()));
+        f.delete();
+        f2.delete();
+    }
+
+    /**
+     * @tests java.io.File#getAbsolutePath()
+     */
+    public void test_getAbsolutePath() {
+        String base = addTrailingSlash(tempDirectory.getPath());
+        File f = new File(base, "temp.tst");
+        assertEquals("Test 1: Incorrect Path Returned.",
+                     base + "temp.tst", f.getAbsolutePath());
+
+        f = new File(base + "Temp" + File.separator + File.separator + File.separator + "Testing" + File.separator
+                + "temp.tst");
+        assertEquals("Test 2: Incorrect Path Returned.",
+		     base + "Temp" + File.separator + "Testing" + File.separator + "temp.tst",
+                     f.getAbsolutePath());
+
+        f = new File(base + "a" + File.separator + File.separator + ".." + File.separator + "temp.tst");
+        assertEquals("Test 3: Incorrect Path Returned.",
+                     base + "a" + File.separator + ".." + File.separator + "temp.tst",
+                     f.getAbsolutePath());
+        f.delete();
+    }
+
+    /**
+     * @tests java.io.File#getCanonicalFile()
+     */
+    public void test_getCanonicalFile() throws IOException {
+        String base = addTrailingSlash(tempDirectory.getPath());
+        File f = new File(base, "temp.tst");
+        File f2 = f.getCanonicalFile();
+        assertEquals("Test 1: Incorrect File Returned.", 0, f2
+                .getCanonicalFile().compareTo(f.getCanonicalFile()));
+        f = new File(base + "Temp" + File.separator + File.separator + "temp.tst");
+        f2 = f.getCanonicalFile();
+        assertEquals("Test 2: Incorrect File Returned.", 0, f2
+                .getCanonicalFile().compareTo(f.getCanonicalFile()));
+        f = new File(base + "Temp" + File.separator + File.separator + ".." + File.separator + "temp.tst");
+        f2 = f.getCanonicalFile();
+        assertEquals("Test 3: Incorrect File Returned.", 0, f2
+                .getCanonicalFile().compareTo(f.getCanonicalFile()));
+
+        // Test for when long directory/file names in Windows
+        boolean onWindows = File.separatorChar == '\\';
+        if (onWindows) {
+            File testdir = new File(base, "long-" + platformId);
+            testdir.mkdir();
+            File dir = new File(testdir, "longdirectory" + platformId);
+            try {
+                dir.mkdir();
+                f = new File(dir, "longfilename.tst");
+                f2 = f.getCanonicalFile();
+                assertEquals("Test 4: Incorrect File Returned.", 0, f2
+                        .getCanonicalFile().compareTo(f.getCanonicalFile()));
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+                f2 = new File(testdir + File.separator + "longdi~1" + File.separator
+                        + "longfi~1.tst");
+                File canonicalf2 = f2.getCanonicalFile();
+                /*
+                 * If the "short file name" doesn't exist, then assume that the
+                 * 8.3 file name compatibility is disabled.
+                 */
+                if (canonicalf2.exists()) {
+                    assertTrue("Test 5: Incorrect File Returned: "
+                            + canonicalf2, canonicalf2.compareTo(f
+                            .getCanonicalFile()) == 0);
+                }
+            } finally {
+                f.delete();
+                f2.delete();
+                dir.delete();
+                testdir.delete();
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.File#getCanonicalPath()
+     */
+    public void test_getCanonicalPath() throws IOException {
+        // Should work for Unix/Windows.
+        String dots = "..";
+        String base = tempDirectory.getCanonicalPath();
+        base = addTrailingSlash(base);
+        File f = new File(base, "temp.tst");
+        assertEquals("Test 1: Incorrect Path Returned.", base + "temp.tst", f
+                .getCanonicalPath());
+        f = new File(base + "Temp" + File.separator + dots + File.separator + "temp.tst");
+        assertEquals("Test 2: Incorrect Path Returned.", base + "temp.tst", f
+                .getCanonicalPath());
+
+        // Finding a non-existent directory for tests 3 and 4
+        // This is necessary because getCanonicalPath is case sensitive and
+        // could cause a failure in the test if the directory exists but with
+        // different case letters (e.g "Temp" and "temp")
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File dir1 = new File(base, String.valueOf(dirNumber));
+        while (dirExists) {
+            if (dir1.exists()) {
+                dirNumber++;
+                dir1 = new File(base, String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+        f = new File(base + dirNumber + File.separator + dots + File.separator + dirNumber
+                + File.separator + "temp.tst");
+        assertEquals("Test 3: Incorrect Path Returned.", base + dirNumber
+                + File.separator + "temp.tst", f.getCanonicalPath());
+        f = new File(base + dirNumber + File.separator + "Temp" + File.separator + dots + File.separator
+                + "Test" + File.separator + "temp.tst");
+        assertEquals("Test 4: Incorrect Path Returned.", base + dirNumber
+                + File.separator + "Test" + File.separator + "temp.tst", f.getCanonicalPath());
+
+        f = new File(base + "1234.567");
+        assertEquals("Test 5: Incorrect Path Returned.", base + "1234.567", f
+                .getCanonicalPath());
+
+        // Test for long file names on Windows
+        boolean onWindows = (File.separatorChar == '\\');
+        if (onWindows) {
+            File testdir = new File(base, "long-" + platformId);
+            testdir.mkdir();
+            File f1 = new File(testdir, "longfilename" + platformId + ".tst");
+            FileOutputStream fos = new FileOutputStream(f1);
+            File f2 = null, f3 = null, dir2 = null;
+            try {
+                fos.close();
+                String dirName1 = f1.getCanonicalPath();
+                File f4 = new File(testdir, "longfi~1.tst");
+                /*
+                 * If the "short file name" doesn't exist, then assume that the
+                 * 8.3 file name compatibility is disabled.
+                 */
+                if (f4.exists()) {
+                    String dirName2 = f4.getCanonicalPath();
+                    assertEquals("Test 6: Incorrect Path Returned.", dirName1,
+                            dirName2);
+                    dir2 = new File(testdir, "longdirectory" + platformId);
+                    if (!dir2.exists()) {
+                        assertTrue("Could not create dir: " + dir2, dir2
+                                .mkdir());
+                    }
+                    f2 = new File(testdir.getPath() + File.separator + "longdirectory"
+                            + platformId + File.separator + "Test" + File.separator + dots
+                            + File.separator + "longfilename.tst");
+                    FileOutputStream fos2 = new FileOutputStream(f2);
+                    fos2.close();
+                    dirName1 = f2.getCanonicalPath();
+                    f3 = new File(testdir.getPath() + File.separator + "longdi~1"
+                            + File.separator + "Test" + File.separator + dots + File.separator
+                            + "longfi~1.tst");
+                    dirName2 = f3.getCanonicalPath();
+                    assertEquals("Test 7: Incorrect Path Returned.", dirName1,
+                            dirName2);
+                }
+            } finally {
+                f1.delete();
+                if (f2 != null) {
+                    f2.delete();
+                }
+                if (dir2 != null) {
+                    dir2.delete();
+                }
+                testdir.delete();
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.File#getName()
+     */
+    public void test_getName() {
+        File f = new File("name.tst");
+        assertEquals("Test 1: Returned incorrect name", "name.tst", f.getName());
+
+        f = new File("");
+        assertEquals("Test 2: Returned incorrect name", "", f.getName());
+
+        f.delete();
+    }
+
+    /**
+     * @tests java.io.File#getParent()
+     */
+    public void test_getParent() {
+        File f = new File("p.tst");
+        assertNull("Incorrect path returned", f.getParent());
+        f = new File(System.getProperty("user.home"), "p.tst");
+        assertEquals("Incorrect path returned",
+                     System.getProperty("user.home"), f.getParent());
+        f.delete();
+
+        File f1 = new File("/directory");
+        assertEquals("Wrong parent test 1", File.separator, f1.getParent());
+        f1 = new File("/directory/file");
+        assertEquals("Wrong parent test 2",
+                     File.separator + "directory", f1.getParent());
+        f1 = new File("directory/file");
+        assertEquals("Wrong parent test 3", "directory", f1.getParent());
+        f1 = new File("/");
+        assertNull("Wrong parent test 4", f1.getParent());
+        f1 = new File("directory");
+        assertNull("Wrong parent test 5", f1.getParent());
+
+        if (File.separatorChar == '\\' && new File("d:/").isAbsolute()) {
+            f1 = new File("d:/directory");
+            assertEquals("Wrong parent test 1a", "d:" + File.separator, f1.getParent());
+            f1 = new File("d:/directory/file");
+            assertEquals("Wrong parent test 2a",
+                         "d:" + File.separator + "directory", f1.getParent());
+            f1 = new File("d:directory/file");
+            assertEquals("Wrong parent test 3a", "d:directory", f1.getParent());
+            f1 = new File("d:/");
+            assertNull("Wrong parent test 4a", f1.getParent());
+            f1 = new File("d:directory");
+            assertEquals("Wrong parent test 5a", "d:", f1.getParent());
+        }
+    }
+
+    /**
+     * @tests java.io.File#getParentFile()
+     */
+    public void test_getParentFile() {
+        File f = new File("tempfile.tst");
+        assertNull("Incorrect path returned", f.getParentFile());
+        f = new File(tempDirectory, "tempfile1.tmp");
+        File f2 = new File(tempDirectory, "tempfile2.tmp");
+        File f3 = new File(tempDirectory, "/a/tempfile.tmp");
+        assertEquals("Incorrect File Returned", 0, f.getParentFile().compareTo(
+                f2.getParentFile()));
+        assertTrue("Incorrect File Returned", f.getParentFile().compareTo(
+                f3.getParentFile()) != 0);
+        f.delete();
+        f2.delete();
+        f3.delete();
     }
 
     /**
      * @tests java.io.File#getPath()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPath",
-        args = {}
-    )
     public void test_getPath() {
+        String base = System.getProperty("user.home");
+        String fname;
+        File f1;
+        if (!base.regionMatches((base.length() - 1), File.separator, 0, 1)) {
+            base += File.separator;
+        }
+        fname = base + "filechk.tst";
+        f1 = new File(base, "filechk.tst");
+        File f2 = new File("filechk.tst");
+        File f3 = new File("c:");
+        File f4 = new File(base + "a" + File.separator + File.separator + ".." + File.separator
+                + "filechk.tst");
+        assertEquals("getPath returned incorrect path(f1)",
+                     fname, f1.getPath());
+        assertEquals("getPath returned incorrect path(f2)",
+                     "filechk.tst", f2.getPath());
+        assertEquals("getPath returned incorrect path(f3)","c:", f3.getPath());
+        assertEquals("getPath returned incorrect path(f4)",
+                     base + "a" + File.separator + ".." + File.separator + "filechk.tst",
+                     f4.getPath());
+        f1.delete();
+        f2.delete();
+        f3.delete();
+        f4.delete();
+
         // Regression for HARMONY-444
         File file;
         String separator = File.separator;
@@ -140,46 +1019,1234 @@
 
         file = new File((String) null, "x/y/z");
         assertEquals("x" + separator + "y" + separator + "z", file.getPath());
-    }
-    
-    /**
-     * @tests java.io.File#getPath()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPath",
-        args = {}
-    )
-    public void test_getPath_With_Empty_FileName() {
+
         // Regression for HARMONY-829
         String f1ParentName = "01";
-        File f1 = new File(f1ParentName, "");
+        f1 = new File(f1ParentName, "");
         assertEquals(f1ParentName, f1.getPath());
-        
+
         String f2ParentName = "0";
-        File f2 = new File(f2ParentName, "");
+        f2 = new File(f2ParentName, "");
 
         assertEquals(-1, f2.compareTo(f1));
         assertEquals(1, f1.compareTo(f2));
 
-        File parent = new File(System.getProperty("java.io.tmpdir"));
-        File f3 = new File(parent, "");
+        File parent = tempDirectory;
+        f3 = new File(parent, "");
 
         assertEquals(parent.getPath(), f3.getPath());
-        
-        
+
+        // Regression for HARMONY-3869
+        File file1 = new File("", "");
+        assertEquals(File.separator, file1.getPath());
+
+        File file2 = new File(new File(""), "");
+        assertEquals(File.separator, file2.getPath());
     }
-    
+
+    /**
+     * @tests java.io.File#hashCode()
+     */
+    public void test_hashCode() {
+        // Regression for HARMONY-53
+        String mixedFname = "SoMe FiLeNaMe";
+        File mfile = new File(mixedFname);
+        File lfile = new File(mixedFname.toLowerCase());
+
+        if (mfile.equals(lfile)) {
+            assertTrue("Assert 0: wrong hashcode", mfile.hashCode() == lfile
+                    .hashCode());
+        } else {
+            assertFalse("Assert 1: wrong hashcode", mfile.hashCode() == lfile
+                    .hashCode());
+        }
+    }
+
+    /**
+     * @tests java.io.File#isAbsolute()
+     */
+    public void test_isAbsolute() {
+        if (File.separatorChar == '\\') {
+            File f = new File("c:\\test");
+            File f1 = new File("\\test");
+            // One or the other should be absolute on Windows or CE
+            assertTrue("Absolute returned false", (f.isAbsolute() && !f1
+                    .isAbsolute())
+                    || (!f.isAbsolute() && f1.isAbsolute()));
+
+            assertTrue(new File("C:/").isAbsolute());
+            assertTrue(new File("f:/").isAbsolute());
+            assertTrue(new File("f:\\").isAbsolute());
+            assertFalse(new File("f:").isAbsolute());
+            assertFalse(new File("K:").isAbsolute());
+            assertTrue(new File("\\\\").isAbsolute());
+            assertTrue(new File("\\\\\\").isAbsolute());
+            assertTrue(new File("\\\\hello").isAbsolute());
+            assertFalse(new File("\\").isAbsolute());
+            assertFalse(new File("/").isAbsolute());
+        } else {
+            File f = new File("/test");
+            File f1 = new File("\\test");
+            assertTrue("Absolute returned false", f.isAbsolute());
+            assertFalse("Absolute returned true", f1.isAbsolute());
+            assertTrue(new File("//test").isAbsolute());
+            assertFalse(new File("test").isAbsolute());
+            assertFalse(new File("c:/").isAbsolute());
+            assertFalse(new File("c:\\").isAbsolute());
+            assertFalse(new File("c:").isAbsolute());
+            assertFalse(new File("\\").isAbsolute());
+            assertFalse(new File("\\\\").isAbsolute());
+        }
+        assertTrue("Non-Absolute returned true", !new File("../test")
+                .isAbsolute());
+    }
+
+    /**
+     * @tests java.io.File#isDirectory()
+     */
+    public void test_isDirectory() {
+        String base = addTrailingSlash(tempDirectory.getPath());
+        File f = new File(base);
+        assertTrue("Test 1: Directory Returned False", f.isDirectory());
+        f = new File(base + "zxzxzxz" + platformId);
+        assertTrue("Test 2: (Not Created) Directory Returned True.", !f
+                .isDirectory());
+        f.mkdir();
+        try {
+            assertTrue("Test 3: Directory Returned False.", f.isDirectory());
+        } finally {
+            f.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#isFile()
+     */
+    public void test_isFile() throws IOException {
+        String base = tempDirectory.getPath();
+        File f = new File(base);
+        assertFalse("Directory Returned True As Being A File.", f.isFile());
+        
+        base = addTrailingSlash(base);
+        f = new File(base, platformId + "amiafile");
+        assertTrue("Non-existent File Returned True", !f.isFile());
+        FileOutputStream fos = new FileOutputStream(f);
+        fos.close();
+        assertTrue("File returned false", f.isFile());
+        f.delete();
+    }
+
+    /**
+     * @tests java.io.File#isHidden()
+     */
+    public void test_isHidden() throws IOException, InterruptedException {
+        boolean onUnix = File.separatorChar == '/';
+        File f = File.createTempFile("harmony-test-FileTest_isHidden_", ".tmp");
+        // On Unix hidden files are marked with a "." at the beginning
+        // of the file name.
+        if (onUnix) {
+            File f2 = new File(".test.tst" + platformId);
+            FileOutputStream fos2 = new FileOutputStream(f2);
+            fos2.close();
+            assertTrue("File returned hidden on Unix", !f.isHidden());
+            assertTrue("File returned visible on Unix", f2.isHidden());
+            assertTrue("File did not delete.", f2.delete());
+        } else {
+            // For windows, the file is being set hidden by the attrib
+            // command.
+            Runtime r = Runtime.getRuntime();
+            assertTrue("File returned hidden", !f.isHidden());
+            Process p = r.exec("attrib +h \"" + f.getAbsolutePath() + "\"");
+            p.waitFor();
+            assertTrue("File returned visible", f.isHidden());
+            p = r.exec("attrib -h \"" + f.getAbsolutePath() + "\"");
+            p.waitFor();
+            assertTrue("File returned hidden", !f.isHidden());
+        }
+        f.delete();
+    }
+
+    /**
+     * @tests java.io.File#lastModified()
+     */
+    public void test_lastModified() throws IOException {
+        File f = new File(System.getProperty("java.io.tmpdir"), platformId
+                + "lModTest.tst");
+        f.delete();
+        long lastModifiedTime = f.lastModified();
+        assertEquals("LastModified Time Should Have Returned 0.", 0,
+                lastModifiedTime);
+        FileOutputStream fos = new FileOutputStream(f);
+        fos.close();
+        f.setLastModified(315550800000L);
+        lastModifiedTime = f.lastModified();
+        assertEquals("LastModified Time Incorrect",
+                     315550800000L, lastModifiedTime);
+        f.delete();
+
+        // Regression for HARMONY-2146
+        f = new File("/../");
+        assertTrue(f.lastModified() > 0);
+    }
+
+    /**
+     * @tests java.io.File#length()
+     */
+    public void test_length() throws IOException {
+        File f = new File(tempDirectory, platformId
+                + "input.tst");
+        assertEquals("File Length Should Have Returned 0.", 0, f.length());
+        FileOutputStream fos = new FileOutputStream(f);
+        fos.write(fileString.getBytes());
+        fos.close();
+        assertEquals("Incorrect file length returned",
+		     fileString.length(), f.length());
+        f.delete();
+
+        // regression test for HARMONY-1497
+        f = File.createTempFile("test", "tmp");
+        f.deleteOnExit();
+        RandomAccessFile raf = new RandomAccessFile(f, "rwd");
+        raf.write(0x41);
+        assertEquals(1, f.length());
+    }
+
+    /**
+     * @tests java.io.File#list()
+     */
+    public void test_list() throws IOException {
+        String base = tempDirectory.getPath();
+        // Old test left behind "garbage files" so this time it creates a
+        // directory that is guaranteed not to already exist (and deletes it
+        // afterward.)
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File dir = null;
+        dir = new File(base, platformId + String.valueOf(dirNumber));
+        while (dirExists) {
+            if (dir.exists()) {
+                dirNumber++;
+                dir = new File(base, String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+
+        String[] flist = dir.list();
+
+        assertNull("Method list() Should Have Returned null.", flist);
+
+        assertTrue("Could not create parent directory for list test", dir
+                .mkdir());
+
+        String[] files = { "mtzz1.xx", "mtzz2.xx", "mtzz3.yy", "mtzz4.yy" };
+        try {
+            assertEquals(
+                    "Method list() Should Have Returned An Array Of Length 0.",
+                    0, dir.list().length);
+
+            File file = new File(dir, "notADir.tst");
+            try {
+                FileOutputStream fos = new FileOutputStream(file);
+                fos.close();
+                assertNull(
+                        "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+                        file.list());
+            } finally {
+                file.delete();
+            }
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+            }
+
+            flist = dir.list();
+            if (flist.length != files.length) {
+                fail("Incorrect list returned");
+            }
+
+            // Checking to make sure the correct files were are listed in the
+            // array.
+            boolean[] check = new boolean[flist.length];
+            for (int i = 0; i < check.length; i++) {
+                check[i] = false;
+            }
+            for (int i = 0; i < files.length; i++) {
+                for (int j = 0; j < flist.length; j++) {
+                    if (flist[j].equals(files[i])) {
+                        check[i] = true;
+                        break;
+                    }
+                }
+            }
+            int checkCount = 0;
+            for (int i = 0; i < check.length; i++) {
+                if (check[i] == false) {
+                    checkCount++;
+                }
+            }
+            assertEquals("Invalid file returned in listing", 0, checkCount);
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+
+            assertTrue("Could not delete parent directory for list test.", dir
+                    .delete());
+        } finally {
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            dir.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#listFiles()
+     */
+    public void test_listFiles() throws IOException, InterruptedException {
+        String base = tempDirectory.getPath();
+        // Finding a non-existent directory to create.
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File dir = new File(base, platformId + String.valueOf(dirNumber));
+        // Making sure that the directory does not exist.
+        while (dirExists) {
+            // If the directory exists, add one to the directory number
+            // (making it a new directory name.)
+            if (dir.exists()) {
+                dirNumber++;
+                dir = new File(base, String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+        // Test for attempting to call listFiles on a non-existent directory.
+        assertNull("listFiles Should Return Null.", dir.listFiles());
+
+        assertTrue("Failed To Create Parent Directory.", dir.mkdir());
+
+        String[] files = { "1.tst", "2.tst", "3.tst", "" };
+        try {
+            assertEquals("listFiles Should Return An Array Of Length 0.", 0,
+                    dir.listFiles().length);
+
+            File file = new File(dir, "notADir.tst");
+            try {
+                FileOutputStream fos = new FileOutputStream(file);
+                fos.close();
+                assertNull(
+                        "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+                        file.listFiles());
+            } finally {
+                file.delete();
+            }
+
+            for (int i = 0; i < (files.length - 1); i++) {
+                File f = new File(dir, files[i]);
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+            }
+
+            new File(dir, "doesNotExist.tst");
+            File[] flist = dir.listFiles();
+
+            // Test to make sure that only the 3 files that were created are
+            // listed.
+            assertEquals("Incorrect Number Of Files Returned.", 3, flist.length);
+
+            // Test to make sure that listFiles can read hidden files.
+            boolean onUnix = File.separatorChar == '/';
+            boolean onWindows = File.separatorChar == '\\';
+            if (onWindows) {
+                files[3] = "4.tst";
+                File f = new File(dir, "4.tst");
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+                Runtime r = Runtime.getRuntime();
+                Process p = r.exec("attrib +h \"" + f.getPath() + "\"");
+                p.waitFor();
+            }
+            if (onUnix) {
+                files[3] = ".4.tst";
+                File f = new File(dir, ".4.tst");
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+            }
+            flist = dir.listFiles();
+            assertEquals("Incorrect Number Of Files Returned.", 4, flist.length);
+
+            // Checking to make sure the correct files were are listed in
+            // the array.
+            boolean[] check = new boolean[flist.length];
+            for (int i = 0; i < check.length; i++) {
+                check[i] = false;
+            }
+            for (int i = 0; i < files.length; i++) {
+                for (int j = 0; j < flist.length; j++) {
+                    if (flist[j].getName().equals(files[i])) {
+                        check[i] = true;
+                        break;
+                    }
+                }
+            }
+            int checkCount = 0;
+            for (int i = 0; i < check.length; i++) {
+                if (check[i] == false) {
+                    checkCount++;
+                }
+            }
+            assertEquals("Invalid file returned in listing", 0, checkCount);
+
+            if (onWindows) {
+                Runtime r = Runtime.getRuntime();
+                Process p = r.exec("attrib -h \""
+                        + new File(dir, files[3]).getPath() + "\"");
+                p.waitFor();
+            }
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            assertTrue("Parent Directory Not Deleted.", dir.delete());
+        } finally {
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            dir.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#listFiles(java.io.FileFilter)
+     */
+    public void test_listFilesLjava_io_FileFilter() throws IOException {
+        String base = System.getProperty("java.io.tmpdir");
+        // Finding a non-existent directory to create.
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File baseDir = new File(base, platformId + String.valueOf(dirNumber));
+        // Making sure that the directory does not exist.
+        while (dirExists) {
+            // If the directory exists, add one to the directory number (making
+            // it a new directory name.)
+            if (baseDir.exists()) {
+                dirNumber++;
+                baseDir = new File(base, String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+
+        // Creating a filter that catches directories.
+        FileFilter dirFilter = new FileFilter() {
+            public boolean accept(File f) {
+                return f.isDirectory();
+            }
+        };
+
+        assertNull("listFiles Should Return Null.", baseDir
+                .listFiles(dirFilter));
+
+        assertTrue("Failed To Create Parent Directory.", baseDir.mkdir());
+
+        File dir1 = null;
+        String[] files = { "1.tst", "2.tst", "3.tst" };
+        try {
+            assertEquals("listFiles Should Return An Array Of Length 0.", 0,
+                    baseDir.listFiles(dirFilter).length);
+
+            File file = new File(baseDir, "notADir.tst");
+            try {
+                FileOutputStream fos = new FileOutputStream(file);
+                fos.close();
+                assertNull(
+                        "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+                        file.listFiles(dirFilter));
+            } finally {
+                file.delete();
+            }
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(baseDir, files[i]);
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+            }
+            dir1 = new File(baseDir, "Temp1");
+            dir1.mkdir();
+
+            // Creating a filter that catches files.
+            FileFilter fileFilter = new FileFilter() {
+                public boolean accept(File f) {
+                    return f.isFile();
+                }
+            };
+
+            // Test to see if the correct number of directories are returned.
+            File[] directories = baseDir.listFiles(dirFilter);
+            assertEquals("Incorrect Number Of Directories Returned.", 1,
+                    directories.length);
+
+            // Test to see if the directory was saved with the correct name.
+            assertEquals("Incorrect Directory Returned.", 0, directories[0]
+                    .compareTo(dir1));
+
+            // Test to see if the correct number of files are returned.
+            File[] flist = baseDir.listFiles(fileFilter);
+            assertEquals("Incorrect Number Of Files Returned.",
+                         files.length, flist.length);
+
+            // Checking to make sure the correct files were are listed in the
+            // array.
+            boolean[] check = new boolean[flist.length];
+            for (int i = 0; i < check.length; i++) {
+                check[i] = false;
+            }
+            for (int i = 0; i < files.length; i++) {
+                for (int j = 0; j < flist.length; j++) {
+                    if (flist[j].getName().equals(files[i])) {
+                        check[i] = true;
+                        break;
+                    }
+                }
+            }
+            int checkCount = 0;
+            for (int i = 0; i < check.length; i++) {
+                if (check[i] == false) {
+                    checkCount++;
+                }
+            }
+            assertEquals("Invalid file returned in listing", 0, checkCount);
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(baseDir, files[i]);
+                f.delete();
+            }
+            dir1.delete();
+            assertTrue("Parent Directory Not Deleted.", baseDir.delete());
+        } finally {
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(baseDir, files[i]);
+                f.delete();
+            }
+            if (dir1 != null) {
+                dir1.delete();
+            }
+            baseDir.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#listFiles(java.io.FilenameFilter)
+     */
+    public void test_listFilesLjava_io_FilenameFilter() throws IOException {
+        String base = System.getProperty("java.io.tmpdir");
+        // Finding a non-existent directory to create.
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File dir = new File(base, platformId + String.valueOf(dirNumber));
+        // Making sure that the directory does not exist.
+        while (dirExists) {
+            // If the directory exists, add one to the directory number (making
+            // it a new directory name.)
+            if (dir.exists()) {
+                dirNumber++;
+                dir = new File(base, platformId + String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+
+        // Creating a filter that catches "*.tst" files.
+        FilenameFilter tstFilter = new FilenameFilter() {
+            public boolean accept(File f, String fileName) {
+                return fileName.endsWith(".tst");
+            }
+        };
+
+        assertNull("listFiles Should Return Null.", dir.listFiles(tstFilter));
+
+        assertTrue("Failed To Create Parent Directory.", dir.mkdir());
+
+        String[] files = { "1.tst", "2.tst", "3.tmp" };
+        try {
+            assertEquals("listFiles Should Return An Array Of Length 0.", 0,
+                    dir.listFiles(tstFilter).length);
+
+            File file = new File(dir, "notADir.tst");
+            try {
+                FileOutputStream fos = new FileOutputStream(file);
+                fos.close();
+                assertNull(
+                        "listFiles Should Have Returned Null When Used On A File Instead Of A Directory.",
+                        file.listFiles(tstFilter));
+            } finally {
+                file.delete();
+            }
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+            }
+
+            // Creating a filter that catches "*.tmp" files.
+            FilenameFilter tmpFilter = new FilenameFilter() {
+                public boolean accept(File f, String fileName) {
+                    // If the suffix is ".tmp" then send it to the array
+                    if (fileName.endsWith(".tmp")) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            };
+
+            // Tests to see if the correct number of files were returned.
+            File[] flist = dir.listFiles(tstFilter);
+            assertEquals("Incorrect Number Of Files Passed Through tstFilter.",
+                    2, flist.length);
+            for (int i = 0; i < flist.length; i++) {
+                assertTrue("File Should Not Have Passed The tstFilter.",
+                        flist[i].getPath().endsWith(".tst"));
+            }
+
+            flist = dir.listFiles(tmpFilter);
+            assertEquals("Incorrect Number Of Files Passed Through tmpFilter.",
+                    1, flist.length);
+            assertTrue("File Should Not Have Passed The tmpFilter.", flist[0]
+                    .getPath().endsWith(".tmp"));
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            assertTrue("Parent Directory Not Deleted.", dir.delete());
+        } finally {
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            dir.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#list(java.io.FilenameFilter)
+     */
+    public void test_listLjava_io_FilenameFilter() throws IOException {
+        String base = tempDirectory.getPath();
+        // Old test left behind "garbage files" so this time it creates a
+        // directory that is guaranteed not to already exist (and deletes it
+        // afterward.)
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File dir = new File(base, platformId + String.valueOf(dirNumber));
+        while (dirExists) {
+            if (dir.exists()) {
+                dirNumber++;
+                dir = new File(base, String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+
+        FilenameFilter filter = new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return !name.equals("mtzz1.xx");
+            }
+        };
+
+        String[] flist = dir.list(filter);
+        assertNull("Method list(FilenameFilter) Should Have Returned Null.",
+                flist);
+
+        assertTrue("Could not create parent directory for test", dir.mkdir());
+
+        String[] files = { "mtzz1.xx", "mtzz2.xx", "mtzz3.yy", "mtzz4.yy" };
+        try {
+            /*
+             * Do not return null when trying to use list(Filename Filter) on a
+             * file rather than a directory. All other "list" methods return
+             * null for this test case.
+             */
+            /*
+             * File file = new File(dir, "notADir.tst"); try { FileOutputStream
+             * fos = new FileOutputStream(file); fos.close(); } catch
+             * (IOException e) { fail("Unexpected IOException During Test."); }
+             * flist = dir.list(filter); assertNull("listFiles Should Have
+             * Returned Null When Used On A File Instead Of A Directory.",
+             * flist); file.delete();
+             */
+
+            flist = dir.list(filter);
+            assertEquals("Array Of Length 0 Should Have Returned.", 0,
+                    flist.length);
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                FileOutputStream fos = new FileOutputStream(f);
+                fos.close();
+            }
+
+            flist = dir.list(filter);
+
+            assertEquals("Incorrect list returned", flist.length,
+                    files.length - 1);
+
+            // Checking to make sure the correct files were are listed in the
+            // array.
+            boolean[] check = new boolean[flist.length];
+            for (int i = 0; i < check.length; i++) {
+                check[i] = false;
+            }
+            String[] wantedFiles = { "mtzz2.xx", "mtzz3.yy", "mtzz4.yy" };
+            for (int i = 0; i < wantedFiles.length; i++) {
+                for (int j = 0; j < flist.length; j++) {
+                    if (flist[j].equals(wantedFiles[i])) {
+                        check[i] = true;
+                        break;
+                    }
+                }
+            }
+            int checkCount = 0;
+            for (int i = 0; i < check.length; i++) {
+                if (check[i] == false) {
+                    checkCount++;
+                }
+            }
+            assertEquals("Invalid file returned in listing", 0, checkCount);
+
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            assertTrue("Could not delete parent directory for test.", dir
+                    .delete());
+        } finally {
+            for (int i = 0; i < files.length; i++) {
+                File f = new File(dir, files[i]);
+                f.delete();
+            }
+            dir.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#listRoots()
+     */
+    public void test_listRoots() {
+        File[] roots = File.listRoots();
+        boolean onUnix = File.separatorChar == '/';
+        boolean onWindows = File.separatorChar == '\\';
+        if (onUnix) {
+            assertEquals("Incorrect Number Of Root Directories.", 1,
+                    roots.length);
+            String fileLoc = roots[0].getPath();
+            assertTrue("Incorrect Root Directory Returned.", fileLoc
+                    .startsWith(File.separator));
+        } else if (onWindows) {
+            // Need better test for Windows
+            assertTrue("Incorrect Number Of Root Directories.",
+                    roots.length > 0);
+        }
+    }
+
+    /**
+     * @tests java.io.File#mkdir()
+     */
+    public void test_mkdir() throws IOException {
+        String base = tempDirectory.getPath();
+        // Old test left behind "garbage files" so this time it creates a
+        // directory that is guaranteed not to already exist (and deletes it
+        // afterward.)
+        int dirNumber = 1;
+        boolean dirExists = true;
+        File dir = new File(base, String.valueOf(dirNumber));
+        while (dirExists) {
+            if (dir.exists()) {
+                dirNumber++;
+                dir = new File(base, String.valueOf(dirNumber));
+            } else {
+                dirExists = false;
+            }
+        }
+
+        assertTrue("mkdir failed", dir.mkdir());
+	assertTrue("mkdir worked but exists check failed", dir.exists());
+        dir.deleteOnExit();
+
+        String longDirName = "abcdefghijklmnopqrstuvwx";// 24 chars
+        String newbase = new String(dir + File.separator);
+        StringBuilder sb = new StringBuilder(dir + File.separator);
+        StringBuilder sb2 = new StringBuilder(dir + File.separator);
+
+        // Test make a long path
+        while (dir.getCanonicalPath().length() < 256 - longDirName.length()) {
+            sb.append(longDirName + File.separator);
+            dir = new File(sb.toString());
+            assertTrue("mkdir failed", dir.mkdir());
+	    assertTrue("mkdir worked but exists check failed", dir.exists());
+            dir.deleteOnExit();
+        }
+
+        while (dir.getCanonicalPath().length() < 256) {
+            sb.append(0);
+            dir = new File(sb.toString());
+            assertTrue("mkdir " + dir.getCanonicalPath().length() + " failed",
+                    dir.mkdir());
+            assertTrue("mkdir " + dir.getCanonicalPath().length()
+                       + " worked but exists check failed", dir.exists());
+            dir.deleteOnExit();
+        }
+        dir = new File(sb2.toString());
+        // Test make many paths
+        while (dir.getCanonicalPath().length() < 256) {
+            sb2.append(0);
+            dir = new File(sb2.toString());
+            assertTrue("mkdir " + dir.getCanonicalPath().length() + " failed",
+                    dir.mkdir());
+            assertTrue("mkdir " + dir.getCanonicalPath().length()
+                       + " worked but exists check failed", dir.exists());
+            dir.deleteOnExit();
+        }
+
+        // Regression test for HARMONY-3656
+        String[] ss = { "dir\u3400", "abc", "abc@123", "!@#$%^&",
+                "~\u4E00!\u4E8C@\u4E09$", "\u56DB\u4E94\u516D",
+                "\u4E03\u516B\u4E5D" };
+        for (int i = 0; i < ss.length; i++) {
+            dir = new File(newbase, ss[i]);
+            assertTrue("mkdir " + dir.getCanonicalPath() + " failed",
+                       dir.mkdir());
+            assertTrue("mkdir " + dir.getCanonicalPath()
+                       + " worked but exists check failed",
+                       dir.exists());
+            dir.deleteOnExit();
+        }
+    }
+
+    /**
+     * @tests java.io.File#mkdir()
+     *
+     * HARMONY-6041
+     */
+    public void test_mkdir_special_unicode() throws IOException {
+        File specialDir = new File(this.tempDirectory,"\u5C73");
+        int i = 0;
+        while (specialDir.exists()) {
+            specialDir = new File("\u5C73" + i);
+            ++i;
+        }
+        assertFalse(specialDir.exists());
+        assertTrue(specialDir.mkdir());
+        assertTrue(specialDir.exists());
+    }
+
+    /**
+     * @tests java.io.File#mkdirs()
+     */
+    public void test_mkdirs() {
+        String userHome = addTrailingSlash(tempDirectory.getPath());
+        File f = new File(userHome + "mdtest" + platformId + File.separator + "mdtest2",
+                "p.tst");
+        File g = new File(userHome + "mdtest" + platformId + File.separator + "mdtest2");
+        File h = new File(userHome + "mdtest" + platformId);
+        f.mkdirs();
+        try {
+            assertTrue("Base Directory not created", h.exists());
+            assertTrue("Directories not created", g.exists());
+            assertTrue("File not created", f.exists());
+        } finally {
+            f.delete();
+            g.delete();
+            h.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#renameTo(java.io.File)
+     */
+    public void test_renameToLjava_io_File() throws IOException {
+        String base = tempDirectory.getPath();
+        File dir = new File(base, platformId);
+        dir.mkdir();
+        File f = new File(dir, "xxx.xxx");
+        File rfile = new File(dir, "yyy.yyy");
+        File f2 = new File(dir, "zzz.zzz");
+        try {
+            FileOutputStream fos = new FileOutputStream(f);
+            fos.write(fileString.getBytes());
+            fos.close();
+            long lengthOfFile = f.length();
+
+            rfile.delete(); // in case it already exists
+
+            assertTrue("Test 1: File Rename Failed", f.renameTo(rfile));
+            assertTrue("Test 2: File Rename Failed.", rfile.exists());
+            assertEquals("Test 3: Size Of File Changed.",
+                         lengthOfFile, rfile.length());
+
+            fos = new FileOutputStream(rfile);
+            fos.close();
+
+            f2.delete(); // in case it already exists
+            assertTrue("Test 4: File Rename Failed", rfile.renameTo(f2));
+            assertTrue("Test 5: File Rename Failed.", f2.exists());
+        } finally {
+            f.delete();
+            rfile.delete();
+            f2.delete();
+            dir.delete();
+        }
+    }
+
+    /**
+     * @tests java.io.File#setLastModified(long)
+     */
+    public void test_setLastModifiedJ() throws IOException {
+        File f1 = null;
+        try {
+            f1 = new File(Support_PlatformFile.getNewPlatformFile(
+                    "harmony-test-FileTest_setLastModified", ".tmp"));
+            f1.createNewFile();
+            long orgTime = f1.lastModified();
+            // Subtracting 100 000 milliseconds from the orgTime of File f1
+            f1.setLastModified(orgTime - 100000);
+            long lastModified = f1.lastModified();
+            assertEquals("Test 1: LastModifed time incorrect",
+                         orgTime - 100000, lastModified);
+            // Subtracting 10 000 000 milliseconds from the orgTime of File f1
+            f1.setLastModified(orgTime - 10000000);
+            lastModified = f1.lastModified();
+            assertEquals("Test 2: LastModifed time incorrect",
+                         orgTime - 10000000, lastModified);
+            // Adding 100 000 milliseconds to the orgTime of File f1
+            f1.setLastModified(orgTime + 100000);
+            lastModified = f1.lastModified();
+            assertEquals("Test 3: LastModifed time incorrect",
+                         orgTime + 100000, lastModified);
+            // Adding 10 000 000 milliseconds from the orgTime of File f1
+            f1.setLastModified(orgTime + 10000000);
+            lastModified = f1.lastModified();
+            assertEquals("Test 4: LastModifed time incorrect",
+                         orgTime + 10000000, lastModified);
+            // Trying to set time to an exact number
+            f1.setLastModified(315550800000L);
+            lastModified = f1.lastModified();
+            assertEquals("Test 5: LastModified time incorrect",
+                         315550800000L, lastModified);
+            String osName = System.getProperty("os.name", "unknown");
+            if (osName.equals("Windows 2000") || osName.equals("Windows NT")) {
+                // Trying to set time to a large exact number
+                boolean result = f1.setLastModified(4354837199000L);
+                long next = f1.lastModified();
+                // Dec 31 23:59:59 EST 2107 is overflow on FAT file systems, and
+                // the call fails
+                if (result) {
+                    assertEquals("Test 6: LastModified time incorrect",
+                                 4354837199000L, next);
+                }
+            }
+            // Trying to set time to a negative number
+            try {
+                f1.setLastModified(-25);
+                fail("IllegalArgumentException Not Thrown.");
+            } catch (IllegalArgumentException e) {
+            }
+        } finally {
+            if (f1 != null) {
+                f1.delete();
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.File#setReadOnly()
+     */
+    public void test_setReadOnly() throws IOException, InterruptedException {
+        File f1 = null;
+        File f2 = null;
+        try {
+            f1 = File.createTempFile("harmony-test-FileTest_setReadOnly", ".tmp");
+            f2 = File.createTempFile("harmony-test-FileTest_setReadOnly", ".tmp");
+            // Assert is flawed because canWrite does not work.
+            // assertTrue("File f1 Is Set To ReadOnly." , f1.canWrite());
+            f1.setReadOnly();
+            // Assert is flawed because canWrite does not work.
+            // assertTrue("File f1 Is Not Set To ReadOnly." , !f1.canWrite());
+            try {
+                // Attempt to write to a file that is setReadOnly.
+                new FileOutputStream(f1);
+                fail("IOException not thrown.");
+            } catch (IOException e) {
+                // Expected
+            }
+            Runtime r = Runtime.getRuntime();
+            Process p;
+            boolean onUnix = File.separatorChar == '/';
+            if (onUnix) {
+                p = r.exec("chmod +w " + f1.getAbsolutePath());
+            } else {
+                p = r.exec("attrib -r \"" + f1.getAbsolutePath() + "\"");
+            }
+            p.waitFor();
+            // Assert is flawed because canWrite does not work.
+            // assertTrue("File f1 Is Set To ReadOnly." , f1.canWrite());
+            FileOutputStream fos = new FileOutputStream(f1);
+            fos.write(fileString.getBytes());
+            fos.close();
+            assertTrue("File Was Not Able To Be Written To.",
+                    f1.length() == fileString.length());
+            assertTrue("File f1 Did Not Delete", f1.delete());
+
+            // Assert is flawed because canWrite does not work.
+            // assertTrue("File f2 Is Set To ReadOnly." , f2.canWrite());
+            fos = new FileOutputStream(f2);
+            // Write to a file.
+            fos.write(fileString.getBytes());
+            fos.close();
+            f2.setReadOnly();
+            // Assert is flawed because canWrite does not work.
+            // assertTrue("File f2 Is Not Set To ReadOnly." , !f2.canWrite());
+            try {
+                // Attempt to write to a file that has previously been written
+                // to.
+                // and is now set to read only.
+                fos = new FileOutputStream(f2);
+                fail("IOException not thrown.");
+            } catch (IOException e) {
+                // Expected
+            }
+            r = Runtime.getRuntime();
+            if (onUnix) {
+                p = r.exec("chmod +w " + f2.getAbsolutePath());
+            } else {
+                p = r.exec("attrib -r \"" + f2.getAbsolutePath() + "\"");
+            }
+            p.waitFor();
+            assertTrue("File f2 Is Set To ReadOnly.", f2.canWrite());
+            fos = new FileOutputStream(f2);
+            fos.write(fileString.getBytes());
+            fos.close();
+            f2.setReadOnly();
+            assertTrue("File f2 Did Not Delete", f2.delete());
+            // Similarly, trying to delete a read-only directory should succeed
+            f2 = new File(tempDirectory, "deltestdir");
+            f2.mkdir();
+            f2.setReadOnly();
+            assertTrue("Directory f2 Did Not Delete", f2.delete());
+            assertTrue("Directory f2 Did Not Delete", !f2.exists());
+        } finally {
+            if (f1 != null) {
+                f1.delete();
+            }
+            if (f2 != null) {
+                f2.delete();
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.File#toString()
+     */
+    public void test_toString() {
+        String fileName = System.getProperty("user.home") + File.separator + "input.tst";
+        File f = new File(fileName);
+        assertEquals("Incorrect string returned", fileName, f.toString());
+
+        if (File.separatorChar == '\\') {
+            String result = new File("c:\\").toString();
+            assertEquals("Removed backslash", "c:\\", result);
+        }
+    }
+
+    /**
+     * @tests java.io.File#toURI()
+     */
+    public void test_toURI() throws URISyntaxException {
+        // Need a directory that exists
+        File dir = tempDirectory;
+
+        // Test for toURI when the file is a directory.
+        String newURIPath = dir.getAbsolutePath();
+        newURIPath = newURIPath.replace(File.separatorChar, '/');
+        if (!newURIPath.startsWith("/")) {
+            newURIPath = "/" + newURIPath;
+        }
+        if (!newURIPath.endsWith("/")) {
+            newURIPath += '/';
+        }
+
+        URI uri = dir.toURI();
+        assertEquals("Test 1A: Incorrect URI Returned.", dir.getAbsoluteFile(), new File(uri));
+        assertEquals("Test 1B: Incorrect URI Returned.",
+                     new URI("file", null, newURIPath, null, null), uri);
+
+        // Test for toURI with a file name with illegal chars.
+        File f = new File(dir, "te% \u20ac st.tst");
+        newURIPath = f.getAbsolutePath();
+        newURIPath = newURIPath.replace(File.separatorChar, '/');
+        if (!newURIPath.startsWith("/")) {
+            newURIPath = "/" + newURIPath;
+        }
+
+        uri = f.toURI();
+        assertEquals("Test 2A: Incorrect URI Returned.",
+                     f.getAbsoluteFile(), new File(uri));
+        assertEquals("Test 2B: Incorrect URI Returned.",
+                     new URI("file", null, newURIPath, null, null), uri);
+
+        // Regression test for HARMONY-3207
+        dir = new File(""); // current directory
+        uri = dir.toURI();
+        assertTrue("Test current dir: URI does not end with slash.", uri
+                .toString().endsWith("/"));
+    }
+
+    /**
+     * @tests java.io.File#toURL()
+     */
+    public void test_toURL() throws MalformedURLException {
+        // Need a directory that exists
+        File dir = tempDirectory;
+
+        // Test for toURL when the file is a directory.
+        String newDirURL = dir.getAbsolutePath();
+        newDirURL = newDirURL.replace(File.separatorChar, '/');
+        if (newDirURL.startsWith("/")) {
+            newDirURL = "file:" + newDirURL;
+        } else {
+            newDirURL = "file:/" + newDirURL;
+        }
+        if (!newDirURL.endsWith("/")) {
+            newDirURL += '/';
+        }
+        assertEquals("Test 1: Incorrect URL Returned.",
+                     dir.toURL().toString(), newDirURL);
+
+        // Test for toURL with a file.
+        File f = new File(dir, "test.tst");
+        String newURL = f.getAbsolutePath();
+        newURL = newURL.replace(File.separatorChar, '/');
+        if (newURL.startsWith("/")) {
+            newURL = "file:" + newURL;
+        } else {
+            newURL = "file:/" + newURL;
+        }
+        assertEquals("Test 2: Incorrect URL Returned.",
+                     f.toURL().toString(), newURL);
+
+        // Regression test for HARMONY-3207
+        dir = new File(""); // current directory
+        newDirURL = dir.toURL().toString();
+        assertTrue("Test current dir: URL does not end with slash.", newDirURL
+                .endsWith("/"));
+    }
+
+    /**
+     * @tests java.io.File#toURI()
+     */
+    public void test_toURI2() throws URISyntaxException {
+        File f = new File(tempDirectory, "a/b/c/../d/e/./f");
+
+        String path = f.getAbsolutePath();
+        path = path.replace(File.separatorChar, '/');
+        if (!path.startsWith("/")) {
+            path = "/" + path;
+        }
+
+        URI uri1 = new URI("file", null, path, null);
+        URI uri2 = f.toURI();
+        assertEquals("uris not equal", uri1, uri2);
+    }
+
+    /**
+     * @tests java.io.File#toURL()
+     */
+    public void test_toURL2() throws MalformedURLException {
+        File f = new File(tempDirectory, "a/b/c/../d/e/./f");
+
+        String path = f.getAbsolutePath();
+        path = path.replace(File.separatorChar, '/');
+        if (!path.startsWith("/")) {
+            path = "/" + path;
+        }
+
+        URL url1 = new URL("file", "", path);
+        URL url2 = f.toURL();
+        assertEquals("urls not equal", url1, url2);
+    }
+
+    /**
+     * @tests java.io.File#deleteOnExit()
+     */
+    /* BEGIN android-removed: we don't have Support_Exec.execJava.
+    public void test_deleteOnExit() throws IOException, InterruptedException {
+        File dir = new File("dir4filetest");
+        dir.mkdir();
+        assertTrue(dir.exists());
+        File subDir = new File("dir4filetest/subdir");
+        subDir.mkdir();
+        assertTrue(subDir.exists());
+
+        Support_Exec.execJava(new String[] {
+                "tests.support.Support_DeleteOnExitTest",
+                dir.getAbsolutePath(), subDir.getAbsolutePath() },
+                new String[] {}, false);
+        assertFalse(dir.exists());
+        assertFalse(subDir.exists());
+    }
+    */
+
+    /**
+     * @tests serilization
+     */
+    public void test_objectStreamClass_getFields() throws Exception {
+        // Regression for HARMONY-2674
+        ObjectStreamClass objectStreamClass = ObjectStreamClass
+                .lookup(File.class);
+        ObjectStreamField[] objectStreamFields = objectStreamClass.getFields();
+        assertEquals(1, objectStreamFields.length);
+        ObjectStreamField objectStreamField = objectStreamFields[0];
+        assertEquals("path", objectStreamField.getName());
+        assertEquals(String.class, objectStreamField.getType());
+    }
+
+    // Regression test for HARMONY-4493
+    public void test_list_withUnicodeFileName() throws Exception {
+        File rootDir = new File("P");
+        if (!rootDir.exists()) {
+            rootDir.mkdir();
+            rootDir.deleteOnExit();
+        }
+
+        String dirName = new String("src\u3400");
+        File dir = new File(rootDir, dirName);
+        if (!dir.exists()) {
+            dir.mkdir();
+            dir.deleteOnExit();
+        }
+        boolean exist = false;
+        String[] fileNames = rootDir.list();
+        for (String fileName : fileNames) {
+            if (dirName.equals(fileName)) {
+                exist = true;
+                break;
+            }
+        }
+        assertTrue(exist);
+    }
+
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies self serialization/deserialization.",
-        method = "!SerializationSelf",
-        args = {}
-    )    
     public void test_serialization_self() throws Exception {
         File testFile = new File("test.ser");
         SerializationTest.verifySelf(testFile);
@@ -188,15 +2255,8 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void test_serialization_compatibility() throws Exception {
         File file = new File("FileTest.golden.ser");
         SerializationTest.verifyGolden(this, file);
     }
-
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/InputStreamReaderTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/InputStreamReaderTest.java
index 08c8627..642c8dd 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/InputStreamReaderTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/InputStreamReaderTest.java
@@ -1,82 +1,537 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
+import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.util.Arrays;
 
 import junit.framework.TestCase;
-@TestTargetClass(InputStreamReader.class)
+
 public class InputStreamReaderTest extends TestCase {
-    
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "InputStreamReader",
-            args = {java.io.InputStream.class, java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getEncoding",
-            args = {}
-        )
-    })
-    public void testGetEncoding_StreamClosed() throws IOException {
-        InputStreamReader in = null;
-        byte b[] = new byte[5];
-        in = new InputStreamReader(new ByteArrayInputStream(b), "UTF-16BE");
-        in.close();
-        String result = in.getEncoding();
-        assertNull(result);
-    }
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "InputStreamReader",
-            args = {java.io.InputStream.class, java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getEncoding",
-            args = {}
-        )
-    })
-    public void testGetEncoding_NotHistorical() {
-        InputStreamReader in = null;
-        try {
-            in = new InputStreamReader(System.in, "UTF-16BE");
-        } catch (UnsupportedEncodingException e) {
-            // ok
+    static class LimitedByteArrayInputStream extends ByteArrayInputStream {
+
+        // A ByteArrayInputStream that only returns a single byte per read
+        byte[] bytes;
+
+        int count;
+
+        public LimitedByteArrayInputStream(int type) {
+            super(new byte[0]);
+            switch (type) {
+            case 0:
+                bytes = new byte[] { 0x61, 0x72 };
+                break;
+            case 1:
+                bytes = new byte[] { (byte) 0xff, (byte) 0xfe, 0x61, 0x72 };
+                break;
+            case 2:
+                bytes = new byte[] { '\u001b', '$', 'B', '6', 'e', 'B', 'h',
+                        '\u001b', '(', 'B' };
+                break;
+            }
+            count = bytes.length;
         }
-        String result = in.getEncoding();
-        assertEquals("UnicodeBigUnmarked", result);
 
+        @Override
+        public int available() {
+            return count;
+        }
+
+        @Override
+        public int read() {
+            if (count == 0) {
+                return -1;
+            }
+            count--;
+            return bytes[bytes.length - count];
+        }
+
+        @Override
+        public int read(byte[] buffer, int offset, int length) {
+            if (count == 0) {
+                return -1;
+            }
+            if (length == 0) {
+                return 0;
+            }
+            buffer[offset] = bytes[bytes.length - count];
+            count--;
+            return 1;
+        }
     }
 
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+    private InputStream fis;
+
+    private InputStream in;
+
+    private InputStreamReader is;
+
+    private InputStreamReader reader;
+
+    private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese";
+
+    /*
+     * @see TestCase#setUp()
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        in = new ByteArrayInputStream(source.getBytes("UTF-8"));
+        reader = new InputStreamReader(in, "UTF-8");
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        OutputStreamWriter osw = new OutputStreamWriter(bos);
+        char[] buf = new char[fileString.length()];
+        fileString.getChars(0, fileString.length(), buf, 0);
+        osw.write(buf);
+        osw.close();
+        fis = new ByteArrayInputStream(bos.toByteArray());
+        is = new InputStreamReader(fis);
+    }
+
+    /*
+     * @see TestCase#tearDown()
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            in.close();
+            is.close();
+            fis.close();
+        } catch (IOException e) {
+            // Ignored
+        }
+
+        super.tearDown();
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#close()
+     */
+    public void test_close() throws IOException {
+        is.close();
+        try {
+            is.read();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        reader.close();
+        try {
+            reader.ready();
+            fail("Should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        // Should be a no-op
+        reader.close();
+
+        // Tests after reader closed
+        in = new BufferedInputStream(
+                this
+                        .getClass()
+                        .getClassLoader()
+                        .getResourceAsStream(
+                                "org/apache/harmony/luni/tests/java/io/testfile-utf8.txt"));
+        reader = new InputStreamReader(in, "utf-8");
+        in.close();
+        try {
+            int count = reader.read(new char[1]);
+            fail("count:" + count);
+        } catch (IOException e) {
+            // Expected
+        }
+        try {
+            reader.read();
+            fail();
+        } catch (IOException e) {
+            // Expected
+        }
+
+        assertFalse(reader.ready());
+        Charset cs = Charset.forName("utf-8");
+        assertEquals(cs, Charset.forName(reader.getEncoding()));
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#InputStreamReader(java.io.InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStream() throws IOException {
+        try {
+            reader = new InputStreamReader(null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        InputStreamReader reader2 = new InputStreamReader(in);
+        reader2.close();
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#InputStreamReader(java.io.InputStream,
+     *        java.lang.String)
+     */
+    public void test_ConstructorLjava_io_InputStreamLjava_lang_String()
+            throws IOException {
+        is = new InputStreamReader(fis, "8859_1");
+
+        try {
+            is = new InputStreamReader(fis, "Bogus");
+            fail("Failed to throw Unsupported Encoding exception");
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+
+        try {
+            reader = new InputStreamReader(null, "utf-8");
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            reader = new InputStreamReader(in, (String) null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            reader = new InputStreamReader(in, "");
+            fail();
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+        try {
+            reader = new InputStreamReader(in, "badname");
+            fail();
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+        InputStreamReader reader2 = new InputStreamReader(in, "utf-8");
+        assertEquals(Charset.forName(reader2.getEncoding()), Charset
+                .forName("utf-8"));
+        reader2.close();
+        reader2 = new InputStreamReader(in, "utf8");
+        assertEquals(Charset.forName(reader2.getEncoding()), Charset
+                .forName("utf-8"));
+        reader2.close();
+    }
+
+    /**
+     * @tests java.io.InputStreamReader(java.io.InputStream,
+     *        java.nio.charset.Charset)
+     */
+    public void test_ConstructorLjava_io_InputStreamLjava_nio_charset_Charset()
+            throws IOException {
+        Charset cs = Charset.forName("utf-8");
+        try {
+            reader = new InputStreamReader(null, cs);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            reader = new InputStreamReader(in, (Charset) null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        InputStreamReader reader2 = new InputStreamReader(in, cs);
+        assertEquals(Charset.forName(reader2.getEncoding()), cs);
+        reader2.close();
+    }
+
+    /**
+     * @tests java.io.InputStreamReader(java.io.InputStream,
+     *        java.nio.charset.CharsetDecoder)
+     */
+    public void test_ConstructorLjava_io_InputStreamLjava_nio_charset_CharsetDecoder()
+            throws IOException {
+        CharsetDecoder decoder = Charset.forName("utf-8").newDecoder();
+        try {
+            reader = new InputStreamReader(null, decoder);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            reader = new InputStreamReader(in, (CharsetDecoder) null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        InputStreamReader reader2 = new InputStreamReader(in, decoder);
+        assertEquals(Charset.forName(reader2.getEncoding()), decoder.charset());
+        reader2.close();
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#getEncoding()
+     */
+    public void test_getEncoding() throws IOException {
+        InputStreamReader isr = new InputStreamReader(fis, "8859_1");
+        assertEquals("Returned incorrect encoding when setting 8859_1",
+                "ISO8859_1", isr.getEncoding());
+
+        isr = new InputStreamReader(fis, "ISO-8859-1");
+        assertEquals("Returned incorrect encoding when setting ISO-8859-1",
+                "ISO8859_1", isr.getEncoding());
+
+        byte b[] = new byte[5];
+        isr = new InputStreamReader(new ByteArrayInputStream(b), "UTF-16BE");
+        isr.close();
+        assertNull(isr.getEncoding());
+
+        try {
+            isr = new InputStreamReader(System.in, "UTF-16BE");
+        } catch (UnsupportedEncodingException e) {
+            // Ignored
+        }
+        assertEquals("UnicodeBigUnmarked", isr.getEncoding());
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#read()
+     */
+    public void test_read() throws IOException {
+        assertEquals('T', (char) reader.read());
+        assertEquals('h', (char) reader.read());
+        assertEquals('i', (char) reader.read());
+        assertEquals('s', (char) reader.read());
+        assertEquals(' ', (char) reader.read());
+        reader.read(new char[source.length() - 5], 0, source.length() - 5);
+        assertEquals(-1, reader.read());
+
+        int c = is.read();
+        assertTrue("returned incorrect char", (char) c == fileString.charAt(0));
+        InputStreamReader reader = new InputStreamReader(
+                new ByteArrayInputStream(new byte[] { (byte) 0xe8, (byte) 0x9d,
+                        (byte) 0xa5 }), "UTF8");
+        assertTrue("wrong double byte char", reader.read() == '\u8765');
+
+        // Regression for HARMONY-166
+        InputStream in;
+
+        in = new LimitedByteArrayInputStream(0);
+        reader = new InputStreamReader(in, "UTF-16BE");
+        assertEquals("Incorrect byte UTF-16BE", '\u6172', reader.read());
+
+        in = new LimitedByteArrayInputStream(0);
+        reader = new InputStreamReader(in, "UTF-16LE");
+        assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read());
+
+        in = new LimitedByteArrayInputStream(1);
+        reader = new InputStreamReader(in, "UTF-16");
+        assertEquals("Incorrect byte UTF-16BE", '\u7261', reader.read());
+
+        /*
+         * Temporarily commented out due to lack of ISO2022 support in ICU4J 3.8
+         * in = new LimitedByteArrayInputStream(2); reader = new
+         * InputStreamReader(in, "ISO2022JP"); assertEquals("Incorrect byte
+         * ISO2022JP 1", '\u4e5d', reader.read()); assertEquals("Incorrect byte
+         * ISO2022JP 2", '\u7b2c', reader.read());
+         */
+    }
+
+    /*
+     * Class under test for int read() Regression for Harmony-411
+     */
+    public void test_read_1() throws IOException {
+        // if the decoder is constructed by InputStreamReader itself, the
+        // decoder's default error action is REPLACE
+        InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(
+                new byte[] { -32, -96 }), "UTF-8");
+        assertEquals("read() return incorrect value", 65533, isr.read());
+
+        InputStreamReader isr2 = new InputStreamReader(
+                new ByteArrayInputStream(new byte[] { -32, -96 }), Charset
+                        .forName("UTF-8"));
+        assertEquals("read() return incorrect value", 65533, isr2.read());
+
+        // if the decoder is passed in, keep its status intact
+        CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.REPORT);
+        InputStreamReader isr3 = new InputStreamReader(
+                new ByteArrayInputStream(new byte[] { -32, -96 }), decoder);
+        try {
+            isr3.read();
+            fail("Should throw MalformedInputException");
+        } catch (MalformedInputException e) {
+            // expected
+        }
+
+        CharsetDecoder decoder2 = Charset.forName("UTF-8").newDecoder();
+        decoder2.onMalformedInput(CodingErrorAction.IGNORE);
+        InputStreamReader isr4 = new InputStreamReader(
+                new ByteArrayInputStream(new byte[] { -32, -96 }), decoder2);
+        assertEquals("read() return incorrect value", -1, isr4.read());
+
+        CharsetDecoder decoder3 = Charset.forName("UTF-8").newDecoder();
+        decoder3.onMalformedInput(CodingErrorAction.REPLACE);
+        InputStreamReader isr5 = new InputStreamReader(
+                new ByteArrayInputStream(new byte[] { -32, -96 }), decoder3);
+        assertEquals("read() return incorrect value", 65533, isr5.read());
+    }
+
+    public void test_read_specialCharset() throws IOException {
+        reader.close();
+        in = this.getClass().getClassLoader().getResourceAsStream(
+                "org/apache/harmony/luni/tests/java/io/testfile-utf8.txt");
+        reader = new InputStreamReader(in, "utf-8");
+        int c;
+        StringBuffer sb = new StringBuffer();
+        while ((c = reader.read()) != -1) {
+            sb.append((char) c);
+        }
+        // delete BOM
+        assertEquals(source, sb.deleteCharAt(0).toString());
+
+        sb.setLength(0);
+        reader.close();
+        in = this.getClass().getClassLoader().getResourceAsStream(
+                "org/apache/harmony/luni/tests/java/io/testfile.txt");
+        try {
+            reader = new InputStreamReader(in, "gb18030");
+        } catch (UnsupportedEncodingException e) {
+            System.out
+                    .println("GB18030 is not supported, abort test InputStreamReaderTest.testSpecialCharsetReading().");
+        }
+        while ((c = reader.read()) != -1) {
+            sb.append((char) c);
+        }
+        assertEquals(source, sb.toString());
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#read(char[], int, int)
+     */
+    public void test_read$CII() throws IOException {
+        char[] rbuf = new char[100];
+        char[] sbuf = new char[100];
+        fileString.getChars(0, 100, sbuf, 0);
+        is.read(rbuf, 0, 100);
+        for (int i = 0; i < rbuf.length; i++) {
+            assertTrue("returned incorrect chars", rbuf[i] == sbuf[i]);
+        }
+
+        // Test successive reads
+        byte[] data = new byte[8192 * 2];
+        Arrays.fill(data, (byte) 116); // 116 = ISO-8859-1 value for 't'
+        ByteArrayInputStream bis = new ByteArrayInputStream(data);
+        InputStreamReader isr = new InputStreamReader(bis, "ISO-8859-1");
+
+        // One less than the InputStreamReader.BUFFER_SIZE
+        char[] buf = new char[8191];
+        int bytesRead = isr.read(buf, 0, buf.length);
+        assertFalse(-1 == bytesRead);
+        bytesRead = isr.read(buf, 0, buf.length);
+        assertFalse(-1 == bytesRead);
+
+        bis = new ByteArrayInputStream(source.getBytes("UTF-8"));
+        isr = new InputStreamReader(in, "UTF-8");
+        char[] chars = new char[source.length()];
+        assertEquals(source.length() - 3, isr.read(chars, 0, chars.length - 3));
+        assertEquals(3, isr.read(chars, 0, 10));
+    }
+
+    /*
+     * Class under test for int read(char[], int, int)
+     */
+    public void test_read$CII_1() throws IOException {
+        try {
+            // Throws IndexOutOfBoundsException before NullPointerException
+            reader.read(null, -1, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            // Throws NullPointerException before IndexOutOfBoundsException
+            reader.read(null, 0, -1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        try {
+            reader.read(null, 0, 1);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            reader.read(new char[3], -1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            reader.read(new char[3], 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            reader.read(new char[3], 1, 3);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        assertEquals(0, reader.read(new char[3], 3, 0));
+        char[] chars = new char[source.length()];
+        assertEquals(0, reader.read(chars, 0, 0));
+        assertEquals(0, chars[0]);
+        assertEquals(3, reader.read(chars, 0, 3));
+        assertEquals(5, reader.read(chars, 3, 5));
+        assertEquals(source.length() - 8, reader.read(chars, 8,
+                chars.length - 8));
+        assertTrue(Arrays.equals(chars, source.toCharArray()));
+        assertEquals(-1, reader.read(chars, 0, chars.length));
+        assertTrue(Arrays.equals(chars, source.toCharArray()));
+    }
+
+    /**
+     * @tests java.io.InputStreamReader#ready()
+     */
+    public void test_ready() throws IOException {
+        assertTrue("Ready test failed", is.ready());
+        is.read();
+        assertTrue("More chars, but not ready", is.ready());
+
+        assertTrue(reader.ready());
+        reader.read(new char[source.length()]);
+        assertFalse(reader.ready());
+    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
index 5710dd3..f2eea47 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectInputStreamTest.java
@@ -1,309 +1,1179 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
+import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InvalidClassException;
+import java.io.InvalidObjectException;
+import java.io.NotActiveException;
+import java.io.ObjectInput;
 import java.io.ObjectInputStream;
+import java.io.ObjectInputValidation;
+import java.io.ObjectOutput;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamClass;
-import java.io.ObjectStreamException;
-import java.io.OptionalDataException;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
 import java.io.Serializable;
+import java.io.SerializablePermission;
 import java.io.StreamCorruptedException;
-import java.util.ArrayList;
+import java.lang.reflect.Proxy;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Vector;
 
 import junit.framework.TestCase;
 
 import org.apache.harmony.testframework.serialization.SerializationTest;
+import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-import tests.support.Support_ASimpleInputStream;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-@TestTargetClass(ObjectInputStream.class)
-public class ObjectInputStreamTest extends TestCase {
+@SuppressWarnings("serial")
+public class ObjectInputStreamTest extends TestCase implements
+        Serializable {
 
     ObjectInputStream ois;
 
     ObjectOutputStream oos;
 
     ByteArrayOutputStream bao;
-    
-    private final String testString = "Lorem ipsum...";
 
-    protected void setUp() throws Exception {
-        super.setUp();
-        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
+    public class SerializableTestHelper implements Serializable {
+
+        public String aField1;
+
+        public String aField2;
+
+        SerializableTestHelper() {
+            aField1 = null;
+            aField2 = null;
+        }
+
+        SerializableTestHelper(String s, String t) {
+            aField1 = s;
+            aField2 = t;
+        }
+
+        private void readObject(ObjectInputStream ois) throws Exception {
+            // note aField2 is not read
+            ObjectInputStream.GetField fields = ois.readFields();
+            aField1 = (String) fields.get("aField1", "Zap");
+        }
+
+        private void writeObject(ObjectOutputStream oos) throws IOException {
+            // note aField2 is not written
+            ObjectOutputStream.PutField fields = oos.putFields();
+            fields.put("aField1", aField1);
+            oos.writeFields();
+        }
+
+        public String getText1() {
+            return aField1;
+        }
+
+        public void setText1(String s) {
+            aField1 = s;
+        }
+
+        public String getText2() {
+            return aField2;
+        }
+
+        public void setText2(String s) {
+            aField2 = s;
+        }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks ObjectStreamException and OptionalDataException.",
-        method = "readUnshared",
-        args = {}
-    )
-    public void test_readUnshared_1() throws IOException, ClassNotFoundException {
-        oos.writeObject(testString);
-        oos.writeObject(testString);
-        oos.writeInt(42);
-        oos.close();
+    public static class A1 implements Serializable {
 
-        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
-        try {
-            ois.readUnshared();
-            ois.readObject();
-            fail("Test 1: ObjectStreamException expected.");
-        } catch (ObjectStreamException e) {
-            // Expected.
-        }
-        
-        try {
-            ois.readUnshared();
-            fail("Test 2: OptionalDataException expected.");
-        } catch (OptionalDataException e) {
-            // Expected.
-        }
-        ois.close();
-    } 
+        private static final long serialVersionUID = 5942584913446079661L;
+
+        B1 b1 = new B1();
+
+        B1 b2 = b1;
+
+        Vector v = new Vector();
+    }
+
+    public static class B1 implements Serializable {
+
+        int i = 5;
+
+        Hashtable h = new Hashtable();
+    }
 
     /**
-     * @tests java.io.ObjectInputStream#readUnshared()
+     * @tests java.io.ObjectInputStream#readObject()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks StreamCorruptedException.",
-        method = "readUnshared",
-        args = {}
-    )    
-    public void test_readUnshared_2() throws IOException, ClassNotFoundException {
+    public void test_readObjectMissingClasses() throws Exception {
+        SerializationTest.verifySelf(new A1(), new SerializableAssert() {
+            public void assertDeserialized(Serializable initial,
+                    Serializable deserialized) {
+                assertEquals(5, ((A1) deserialized).b1.i);
+            }
+        });
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
+     */
+    public void test_ConstructorLjava_io_InputStream() throws IOException {
+        oos.writeDouble(Double.MAX_VALUE);
         oos.close();
-        bao.write(testString.getBytes());
-        
         ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.close();
+        oos.close();
+
         try {
-            ois.readUnshared();
-            fail("Test 1: StreamCorruptedException expected.");
+            ois = new ObjectInputStream(new ByteArrayInputStream(new byte[90]));
+            fail("StreamCorruptedException expected");
         } catch (StreamCorruptedException e) {
-            // Expected.
+            // Expected
         }
-        ois.close();
     }
 
     /**
-     * @tests java.io.ObjectInputStream#readUnshared()
+     * @tests java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks IOException.",
-        method = "readUnshared",
-        args = {}
-    )    
-    public void test_readUnshared_3() throws IOException, ClassNotFoundException {
-        bao.write(testString.getBytes());
+    public void test_ConstructorLjava_io_InputStream_subtest0() throws IOException {
+        SecurityManager sm = System.getSecurityManager();
+        System.setSecurityManager(new SecurityManager() {
+            Permission golden = new SerializablePermission("enableSubclassImplementation");
+
+            @Override
+            public void checkPermission(Permission p) {
+                if (golden.equals(p)) {
+                    throw new SecurityException();
+                }
+            }
+        });
+
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            ObjectOutputStream obout = new ObjectOutputStream(out);
+            obout.write(0);
+            obout.close();
+
+            InputStream in = new ByteArrayInputStream(out.toByteArray());
+
+            // should not cause SecurityException
+            new ObjectInputStream(in);
+            in.reset();
+
+            // should not cause SecurityException
+            new ObjectInputStream(in) {};
+            in.reset();
+
+            try {
+                new ObjectInputStream(in) {
+                    @Override
+                    public Object readUnshared() throws IOException, ClassNotFoundException {
+                        return null;
+                    }
+                };
+                fail("should throw SecurityException 1");
+            } catch (SecurityException e) {
+                // Expected
+            }
+
+            in.reset();
+            try {
+                new ObjectInputStream(in) {
+                    @Override
+                    public GetField readFields() throws IOException,
+                            ClassNotFoundException, NotActiveException {
+                        return null;
+                    }
+                };
+                fail("should throw SecurityException 2");
+            } catch (SecurityException e) {
+                // Expected
+            }
+        } finally {
+            System.setSecurityManager(sm);
+        }
+    }
+    
+    /**
+     * @tests {@link java.io.ObjectInputStream#resolveProxyClass(String[])}
+     */
+    public void test_resolveProxyClass() throws IOException,
+            ClassNotFoundException {
+        oos.writeBytes("HelloWorld");
         oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        MockObjectInputStream mockIn = new MockObjectInputStream(
+                new ByteArrayInputStream(bao.toByteArray()));
+        Class[] clazzs = { java.io.ObjectInputStream.class,
+                java.io.Reader.class };
+        for (int i = 0; i < clazzs.length; i++) {
+            Class clazz = clazzs[i];
+            Class[] interfaceNames = clazz.getInterfaces();
+            String[] interfaces = new String[interfaceNames.length];
+            int index = 0;
+            for (Class c : interfaceNames) {
+                interfaces[index] = c.getName();
+                index++;
+            }
+            Class<?> s = mockIn.resolveProxyClass(interfaces);
 
-        Support_ASimpleInputStream sis = new Support_ASimpleInputStream(bao.toByteArray());
-        ois = new ObjectInputStream(sis);
-        sis.throwExceptionOnNextUse = true;
-        try {
-            ois.readUnshared();
-            fail("Test 1: IOException expected.");
-        } catch (IOException e) {
-            // Expected.
+            if (Proxy.isProxyClass(s)) {
+                Class[] implementedInterfaces = s.getInterfaces();
+                for (index = 0; index < implementedInterfaces.length; index++) {
+                    assertEquals(interfaceNames[index],
+                            implementedInterfaces[index]);
+                }
+            } else {
+                fail("Should return a proxy class that implements the interfaces named in a proxy class descriptor");
+            }
         }
-        sis.throwExceptionOnNextUse = false;
+        mockIn.close();
+    }
+
+    class MockObjectInputStream extends ObjectInputStream {
+
+        public MockObjectInputStream(InputStream input)
+                throws StreamCorruptedException, IOException {
+            super(input);
+        }
+
+        @Override
+        public Class<?> resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException {
+            return super.resolveProxyClass(interfaceNames);
+        }
+
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#available()
+     */
+    public void test_available() throws IOException {
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect bytes", 10, ois.available());
         ois.close();
     }
 
     /**
-     * Micro-scenario of de/serialization of an object with non-serializable superclass.
-     * The super-constructor only should be invoked on the deserialized instance.
+     * @tests java.io.ObjectInputStream#close()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "readObject",
-        args = {}
-    )
-    public void test_readObject_Hierarchy() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
-
-        ObjectOutputStream oos = new ObjectOutputStream(baos); 
-        oos.writeObject(new B());
-        oos.close(); 
-
-        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); 
-        B b = (B) ois.readObject();
+    public void test_close() throws IOException {
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
         ois.close();
-        
-        assertTrue("should construct super", A.list.contains(b));
-        assertFalse("should not construct self", B.list.contains(b));
-        assertEquals("super field A.s", A.DEFAULT, ((A)b).s);
-        assertNull("transient field B.s", b.s);
     }
-    
+
     /**
-     * @tests {@link java.io.ObjectInputStream#readNewLongString()}
+     * @tests java.io.ObjectInputStream#defaultReadObject()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization.",
-        method = "!SerializationSelf",
-        args = {}
-    )
-    public void test_readNewLongString() throws Exception {
-        LongString longString = new LongString();
-        SerializationTest.verifySelf(longString);
-    }
-    
-    private static class LongString implements Serializable{
-        private static final long serialVersionUID = 1L;
-        String lString;
-        
-        public LongString() {
-            StringBuilder builder = new StringBuilder();
-            // construct a string whose length > 64K
-            for (int i = 0; i < 65636; i++) {
-                builder.append('1');
-            }
-            lString = builder.toString();
-        }
-        
-        @Override
-        public boolean equals(Object o) {
-            if (o == this) {
-                return true;
-            }
-            if (o instanceof LongString) {
-                LongString l = (LongString) o;
-                return l.lString.equals(l.lString);
-            }
-            return true;
-        }
-        
-        @Override
-        public int hashCode() {
-            return lString.hashCode();
-        }
-    }
-
-    static class A { 
-        static final ArrayList<A> list = new ArrayList<A>();  
-        String s;
-        public static final String DEFAULT = "aaa";
-        public A() {
-            s = DEFAULT;
-            list.add(this);
-        }
-    } 
-
-    static class B extends A implements Serializable { 
-        private static final long serialVersionUID = 1L;
-        static final ArrayList<A> list = new ArrayList<A>();  
-        transient String s;
-        public B() {
-            s = "bbb";
-            list.add(this);
-        }
-    }     
-    
-    class OIS extends ObjectInputStream {
-        
-        OIS () throws IOException {
-            super();
-         }
-        
-        void test() throws ClassNotFoundException,IOException {
-            readClassDescriptor();
-        }
-        
-    }
- 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "readClassDescriptor",
-        args = {}
-    )
-    public void test_readClassDescriptor() throws ClassNotFoundException, IOException {
+    public void test_defaultReadObject() throws Exception {
+        // SM. This method may as well be private, as if called directly it
+        // throws an exception.
+        String s = "HelloWorld";
+        oos.writeObject(s);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
         try {
-            new OIS().test();
-            fail("Test 1: NullPointerException expected.");
-        } catch (NullPointerException e) {
-            // Expected.
+            ois.defaultReadObject();
+            fail("NotActiveException expected");
+        } catch (NotActiveException e) {
+            // Desired behavior
+        } finally {
+            ois.close();
         }
     }
 
-    static class TestObjectInputStream extends ObjectInputStream {
-        public TestObjectInputStream(InputStream in) throws IOException {
+    /**
+     * @tests java.io.ObjectInputStream#read()
+     */
+    public void test_read() throws IOException {
+        oos.write('T');
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect byte value", 'T', ois.read());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        byte[] buf = new byte[10];
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.read(buf, 0, 10);
+        ois.close();
+        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
+                10, "UTF-8"));
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readBoolean()
+     */
+    public void test_readBoolean() throws IOException {
+        oos.writeBoolean(true);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Read incorrect boolean value", ois.readBoolean());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readByte()
+     */
+    public void test_readByte() throws IOException {
+        oos.writeByte(127);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect byte value", 127, ois.readByte());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readChar()
+     */
+    public void test_readChar() throws IOException {
+        oos.writeChar('T');
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect char value", 'T', ois.readChar());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readDouble()
+     */
+    public void test_readDouble() throws IOException {
+        oos.writeDouble(Double.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Read incorrect double value",
+                ois.readDouble() == Double.MAX_VALUE);
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readFields()
+     */
+    public void test_readFields() throws Exception {
+
+        SerializableTestHelper sth;
+
+        /*
+         * "SerializableTestHelper" is an object created for these tests with
+         * two fields (Strings) and simple implementations of readObject and
+         * writeObject which simply read and write the first field but not the
+         * second
+         */
+
+        oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
+        oos.flush();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        sth = (SerializableTestHelper) (ois.readObject());
+        assertEquals("readFields / writeFields failed--first field not set",
+                "Gabba", sth.getText1());
+        assertNull(
+                "readFields / writeFields failed--second field should not have been set",
+                sth.getText2());
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readFloat()
+     */
+    public void test_readFloat() throws IOException {
+        oos.writeFloat(Float.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Read incorrect float value",
+                ois.readFloat() == Float.MAX_VALUE);
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readFully(byte[])
+     */
+    public void test_readFully$B() throws IOException {
+        byte[] buf = new byte[10];
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.readFully(buf);
+        ois.close();
+        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
+                10, "UTF-8"));
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII() throws IOException {
+        byte[] buf = new byte[10];
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.readFully(buf, 0, 10);
+        ois.close();
+        assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
+                10, "UTF-8"));
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readInt()
+     */
+    public void test_readInt() throws IOException {
+        oos.writeInt(Integer.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Read incorrect int value",
+                ois.readInt() == Integer.MAX_VALUE);
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readLine()
+     */
+    @SuppressWarnings("deprecation")
+    public void test_readLine() throws IOException {
+        oos.writeBytes("HelloWorld\nSecondLine");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.readLine();
+        assertEquals("Read incorrect string value", "SecondLine", ois
+                .readLine());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readLong()
+     */
+    public void test_readLong() throws IOException {
+        oos.writeLong(Long.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Read incorrect long value",
+                ois.readLong() == Long.MAX_VALUE);
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readObject()
+     */
+    public void test_readObject() throws Exception {
+        String s = "HelloWorld";
+        oos.writeObject(s);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect Object value", s, ois.readObject());
+        ois.close();
+
+        // Regression for HARMONY-91
+        // dynamically create serialization byte array for the next hierarchy:
+        // - class A implements Serializable
+        // - class C extends A
+
+        byte[] cName = C.class.getName().getBytes("UTF-8");
+        byte[] aName = A.class.getName().getBytes("UTF-8");
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        byte[] begStream = new byte[] { (byte) 0xac, (byte) 0xed, // STREAM_MAGIC
+                (byte) 0x00, (byte) 0x05, // STREAM_VERSION
+                (byte) 0x73, // TC_OBJECT
+                (byte) 0x72, // TC_CLASSDESC
+                (byte) 0x00, // only first byte for C class name length
+        };
+
+        out.write(begStream, 0, begStream.length);
+        out.write(cName.length); // second byte for C class name length
+        out.write(cName, 0, cName.length); // C class name
+
+        byte[] midStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x21, // serialVersionUID = 33L
+                (byte) 0x02, // flags
+                (byte) 0x00, (byte) 0x00, // fields : none
+                (byte) 0x78, // TC_ENDBLOCKDATA
+                (byte) 0x72, // Super class for C: TC_CLASSDESC for A class
+                (byte) 0x00, // only first byte for A class name length
+        };
+
+        out.write(midStream, 0, midStream.length);
+        out.write(aName.length); // second byte for A class name length
+        out.write(aName, 0, aName.length); // A class name
+
+        byte[] endStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+                (byte) 0x0b, // serialVersionUID = 11L
+                (byte) 0x02, // flags
+                (byte) 0x00, (byte) 0x01, // fields
+
+                (byte) 0x4c, // field description: type L (object)
+                (byte) 0x00, (byte) 0x04, // length
+                // field = 'name'
+                (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65,
+
+                (byte) 0x74, // className1: TC_STRING
+                (byte) 0x00, (byte) 0x12, // length
+                //
+                (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
+                (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
+                (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53,
+                (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e,
+                (byte) 0x67, (byte) 0x3b,
+
+                (byte) 0x78, // TC_ENDBLOCKDATA
+                (byte) 0x70, // NULL super class for A class
+
+                // classdata
+                (byte) 0x74, // TC_STRING
+                (byte) 0x00, (byte) 0x04, // length
+                (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, // value
+        };
+
+        out.write(endStream, 0, endStream.length);
+        out.flush();
+
+        // read created serial. form
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+                out.toByteArray()));
+        Object o = ois.readObject();
+        assertEquals(C.class, o.getClass());
+
+		// Regression for HARMONY-846
+        assertNull(new ObjectInputStream() {}.readObject());
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readObjectOverride()
+     */
+    public void test_readObjectOverride() throws Exception {
+        // Regression for HARMONY-846
+        assertNull(new ObjectInputStream() {
+
+            @Override
+            public Object readObjectOverride() throws IOException,
+                    ClassNotFoundException {
+                return super.readObjectOverride();
+            }
+
+        }.readObjectOverride());
+    }
+
+    public static class A implements Serializable {
+
+        private static final long serialVersionUID = 11L;
+
+        public String name = "name";
+    }
+
+    public static class B extends A {}
+
+    public static class C extends B {
+
+        private static final long serialVersionUID = 33L;
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readObject()
+     */
+    public void test_readObjectCorrupt() throws IOException, ClassNotFoundException {
+        byte[] bytes = { 00, 00, 00, 0x64, 0x43, 0x48, (byte) 0xFD, 0x71, 00,
+                00, 0x0B, (byte) 0xB8, 0x4D, 0x65 };
+        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+        try {
+            ObjectInputStream in = new ObjectInputStream(bin);
+            in.readObject();
+            fail("Unexpected read of corrupted stream");
+        } catch (StreamCorruptedException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readShort()
+     */
+    public void test_readShort() throws IOException {
+        oos.writeShort(Short.MAX_VALUE);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertTrue("Read incorrect short value",
+                ois.readShort() == Short.MAX_VALUE);
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readUnsignedByte()
+     */
+    public void test_readUnsignedByte() throws IOException {
+        oos.writeByte(-1);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect unsignedByte value", 255, ois
+                .readUnsignedByte());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readUnsignedShort()
+     */
+    public void test_readUnsignedShort() throws IOException {
+        oos.writeShort(-1);
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect unsignedShort value", 65535, ois
+                .readUnsignedShort());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#readUTF()
+     */
+    public void test_readUTF() throws IOException {
+        oos.writeUTF("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        assertEquals("Read incorrect utf value", "HelloWorld", ois.readUTF());
+        ois.close();
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#skipBytes(int)
+     */
+    public void test_skipBytesI() throws IOException {
+        byte[] buf = new byte[10];
+        oos.writeBytes("HelloWorld");
+        oos.close();
+        ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
+        ois.skipBytes(5);
+        ois.read(buf, 0, 5);
+        ois.close();
+        assertEquals("Skipped incorrect bytes", "World", new String(buf, 0, 5, "UTF-8"));
+
+        // Regression for HARMONY-844
+        try {
+            new ObjectInputStream() {}.skipBytes(0);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {}
+    }
+
+    // Regression Test for JIRA 2192
+	public void test_readObject_withPrimitiveClass() throws Exception {
+		File file = new File("test.ser");
+		file.deleteOnExit();
+		Test test = new Test();
+		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
+				file));
+		out.writeObject(test);
+		out.close();
+
+		ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
+		Test another = (Test) in.readObject();
+		in.close();
+		assertEquals(test, another);
+	}
+
+    //Regression Test for JIRA-2249
+    public static class ObjectOutputStreamWithWriteDesc extends
+            ObjectOutputStream {
+        public ObjectOutputStreamWithWriteDesc(OutputStream os)
+                throws IOException {
+            super(os);
+        }
+
+        @Override
+        public void writeClassDescriptor(ObjectStreamClass desc)
+                throws IOException {
+        }
+    }
+
+    public static class ObjectIutputStreamWithReadDesc extends
+            ObjectInputStream {
+        private Class returnClass;
+
+        public ObjectIutputStreamWithReadDesc(InputStream is, Class returnClass)
+                throws IOException {
+            super(is);
+            this.returnClass = returnClass;
+        }
+
+        @Override
+        public ObjectStreamClass readClassDescriptor() throws IOException,
+                ClassNotFoundException {
+            return ObjectStreamClass.lookup(returnClass);
+
+        }
+    }
+
+    static class TestClassForSerialization implements Serializable {
+		private static final long serialVersionUID = 1L;
+	}
+
+    public void test_ClassDescriptor() throws IOException,
+			ClassNotFoundException {
+
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc(
+				baos);
+		oos.writeObject(String.class);
+		oos.close();
+		Class cls = TestClassForSerialization.class;
+		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+		ObjectIutputStreamWithReadDesc ois = new ObjectIutputStreamWithReadDesc(
+				bais, cls);
+		Object obj = ois.readObject();
+		ois.close();
+		assertEquals(cls, obj);
+	}
+
+	// Regression Test for JIRA-2340
+    public static class ObjectOutputStreamWithWriteDesc1 extends
+			ObjectOutputStream {
+		public ObjectOutputStreamWithWriteDesc1(OutputStream os)
+				throws IOException {
+			super(os);
+		}
+
+		@Override
+        public void writeClassDescriptor(ObjectStreamClass desc)
+				throws IOException {
+			super.writeClassDescriptor(desc);
+		}
+	}
+
+	public static class ObjectIutputStreamWithReadDesc1 extends
+			ObjectInputStream {
+
+		public ObjectIutputStreamWithReadDesc1(InputStream is)
+				throws IOException {
+			super(is);
+		}
+
+		@Override
+        public ObjectStreamClass readClassDescriptor() throws IOException,
+				ClassNotFoundException {
+			return super.readClassDescriptor();
+		}
+	}
+
+    // Regression test for Harmony-1921
+    public static class ObjectInputStreamWithResolve extends ObjectInputStream {
+        public ObjectInputStreamWithResolve(InputStream in) throws IOException {
             super(in);
         }
 
-        protected Class<?> resolveClass(ObjectStreamClass desc)
+        @Override
+        @SuppressWarnings("unchecked")
+        protected Class resolveClass(ObjectStreamClass desc)
                 throws IOException, ClassNotFoundException {
-            if (desc.getName().endsWith("ObjectInputStreamTest$TestClass1")) {
-                return TestClass2.class;
+            if (desc.getName().equals(
+                    "org.apache.harmony.luni.tests.pkg1.TestClass")) {
+                return org.apache.harmony.luni.tests.pkg2.TestClass.class;
             }
             return super.resolveClass(desc);
         }
     }
 
-    static class TestClass1 implements Serializable { 
-        private static final long serialVersionUID = 11111L;
-        int i = 0;
-    }
-
-    static class TestClass2 implements Serializable {
-        private static final long serialVersionUID = 11111L;
-        int i = 0;
-    }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks InvalidClassException.",
-        method = "resolveClass",
-        args = {java.io.ObjectStreamClass.class}
-    )
-    public void test_resolveClass_invalidClassName()
-            throws Exception {
-        // Regression test for HARMONY-1920
-        TestClass1 to1 = new TestClass1();
+    public void test_resolveClass() throws Exception {
+        org.apache.harmony.luni.tests.pkg1.TestClass to1 = new org.apache.harmony.luni.tests.pkg1.TestClass();
+        to1.i = 555;
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(baos);
-        ByteArrayInputStream bais;
-        ObjectInputStream ois;
-
-        to1.i = 555;
         oos.writeObject(to1);
         oos.flush();
         byte[] bytes = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = new ObjectInputStreamWithResolve(bais);
+        org.apache.harmony.luni.tests.pkg2.TestClass to2 = (org.apache.harmony.luni.tests.pkg2.TestClass) ois
+                .readObject();
+
+        if (to2.i != to1.i) {
+            fail("Wrong object read. Expected val: " + to1.i + ", got: "
+                    + to2.i);
+        }
+    }
+
+    static class ObjectInputStreamWithResolveObject extends ObjectInputStream {
+
+        public static Integer intObj = Integer.valueOf(1000);
+
+        public ObjectInputStreamWithResolveObject(InputStream in) throws IOException {
+            super(in);
+            enableResolveObject(true);
+        }
+
+        @Override
+        protected Object resolveObject(Object obj) throws IOException {
+            if(obj instanceof Integer){
+                obj = intObj;
+            }
+            return super.resolveObject(obj);
+        }
+    }
+
+    /**
+     * @tests java.io.ObjectInputStream#resolveObject(Object)
+     */
+    public void test_resolveObjectLjava_lang_Object() throws Exception {
+        // Write an Integer object into memory
+        Integer original = new Integer(10);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(original);
+        oos.flush();
+        oos.close();
+
+        // Read the object from memory
+        byte[] bytes = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStreamWithResolveObject ois =
+            new ObjectInputStreamWithResolveObject(bais);
+        Integer actual = (Integer) ois.readObject();
+        ois.close();
+
+        // object should be resolved from 10 to 1000
+        assertEquals(ObjectInputStreamWithResolveObject.intObj, actual);
+    }
+
+	public void test_readClassDescriptor() throws IOException,
+			ClassNotFoundException {
+
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1(
+				baos);
+		ObjectStreamClass desc = ObjectStreamClass
+		.lookup(TestClassForSerialization.class);
+		oos.writeClassDescriptor(desc);
+		oos.close();
+
+        byte[] bytes = baos.toByteArray();
+		ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+		ObjectIutputStreamWithReadDesc1 ois = new ObjectIutputStreamWithReadDesc1(
+				bais);
+		Object obj = ois.readClassDescriptor();
+		ois.close();
+		assertEquals(desc.getClass(), obj.getClass());
+
+        //eof
         bais = new ByteArrayInputStream(bytes);
-        ois = new TestObjectInputStream(bais);
+        ExceptionalBufferedInputStream bis = new ExceptionalBufferedInputStream(
+                bais);
+        ois = new ObjectIutputStreamWithReadDesc1(bis);
+
+        bis.setEOF(true);
 
         try {
-            ois.readObject();
-            fail("Test 1: InvalidClassException expected.");
-        } catch (InvalidClassException ice) {
-            // Expected.
+            obj = ois.readClassDescriptor();
+        } catch (IOException e) {
+            //e.printStackTrace();
+        } finally {
+            ois.close();
         }
+
+        //throw exception
+        bais = new ByteArrayInputStream(bytes);
+        bis = new ExceptionalBufferedInputStream(bais);
+        ois = new ObjectIutputStreamWithReadDesc1(bis);
+
+        bis.setException(new IOException());
+
+        try {
+            obj = ois.readClassDescriptor();
+        } catch (IOException e) {
+            //e.printStackTrace();
+        } finally {
+            ois.close();
+        }
+
+        //corrupt
+        bais = new ByteArrayInputStream(bytes);
+        bis = new ExceptionalBufferedInputStream(bais);
+        ois = new ObjectIutputStreamWithReadDesc1(bis);
+
+        bis.setCorrupt(true);
+
+        try {
+            obj = ois.readClassDescriptor();
+        } catch (IOException e) {
+            //e.printStackTrace();
+        } finally {
+            ois.close();
+        }
+	}
+
+    static class ExceptionalBufferedInputStream extends BufferedInputStream {
+        private boolean eof = false;
+        private IOException exception = null;
+        private boolean corrupt = false;
+
+        public ExceptionalBufferedInputStream(InputStream in) {
+            super(in);
+        }
+
+        @Override
+        public int read() throws IOException {
+            if (exception != null) {
+                throw exception;
+            }
+
+            if (eof) {
+                return -1;
+            }
+
+            if (corrupt) {
+                return 0;
+            }
+            return super.read();
+        }
+
+        public void setEOF(boolean eof) {
+            this.eof = eof;
+        }
+
+        public void setException(IOException exception) {
+            this.exception = exception;
+        }
+
+        public void setCorrupt(boolean corrupt) {
+            this.corrupt = corrupt;
+        }
+    }
+
+    public static class ObjectIutputStreamWithReadDesc2 extends
+            ObjectInputStream {
+        private Class returnClass;
+
+        public ObjectIutputStreamWithReadDesc2(InputStream is, Class returnClass)
+                throws IOException {
+            super(is);
+            this.returnClass = returnClass;
+        }
+
+        @Override
+        public ObjectStreamClass readClassDescriptor() throws IOException,
+                ClassNotFoundException {
+            ObjectStreamClass osc = super.readClassDescriptor();
+
+            if (osc.getName().equals(returnClass.getName())) {
+                return ObjectStreamClass.lookup(returnClass);
+            }
+            return osc;
+        }
+    }
+
+    /*
+     * Testing classDescriptor replacement with the value generated by
+     * ObjectStreamClass.lookup() method.
+     * Regression test for HARMONY-4638
+     */
+    public void test_readClassDescriptor_1() throws IOException, ClassNotFoundException {
+        A a = new A();
+        a.name = "It's a test";
+        PipedOutputStream pout = new PipedOutputStream();
+        PipedInputStream pin = new PipedInputStream(pout);
+        ObjectOutputStream out = new ObjectOutputStream(pout);
+        ObjectInputStream in = new ObjectIutputStreamWithReadDesc2(pin, A.class);
+
+        // test single object
+        out.writeObject(a);
+        A a1 = (A) in.readObject();
+        assertEquals("Single case: incorrectly read the field of A", a.name, a1.name);
+
+        // test cyclic reference
+        HashMap m = new HashMap();
+        a = new A();
+        a.name = "It's a test 0";
+        a1 = new A();
+        a1.name = "It's a test 1";
+        m.put("0", a);
+        m.put("1", a1);
+        out.writeObject(m);
+        HashMap m1 = (HashMap) in.readObject();
+        assertEquals("Incorrectly read the field of A", a.name, ((A) m1.get("0")).name);
+        assertEquals("Incorrectly read the field of A1", a1.name, ((A) m1.get("1")).name);
+    }
+
+    public void test_registerValidation() throws Exception {
+        // Regression Test for Harmony-2402
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        new ObjectOutputStream(baos);
+        ObjectInputStream ois = new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray()));
+
+        try {
+            ois.registerValidation(null, 256);
+            fail("NotActiveException should be thrown");
+        } catch (NotActiveException nae) {
+            // expected
+        }
+
+        // Regression Test for Harmony-3916
+        baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(new RegisterValidationClass());
+        oos.close();
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream fis = new ObjectInputStream(bais);
+        // should not throw NotActiveException
+        fis.readObject();
+    }
+
+    private static class RegisterValidationClass implements Serializable {
+        @SuppressWarnings("unused")
+        private A a = new A();
+        private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+            stream.defaultReadObject();
+            stream.registerValidation(new MockObjectInputValidation(), 0);
+        }
+    }
+
+    private static class MockObjectInputValidation implements ObjectInputValidation {
+        public void validateObject() throws InvalidObjectException {
+
+        }
+    }
+
+    //Regression Test for HARMONY-3726
+    public void test_readObject_array() throws Exception {
+
+        final String resourcePrefix = ObjectInputStreamTest.class.getPackage().getName().replace('.', '/');
+
+//        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_strings.ser"));
+//        TestArray ta = new TestArray(new String[] { "AAA", "BBB" });
+//        oos.writeObject(ta);
+//        oos.close();
+//        oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_integers.ser"));
+//        ta = new TestArray(new Integer[] { 10, 20 });
+//        oos.writeObject(ta);
+//        oos.close();
+
+        ObjectInputStream oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
+                "serialization/" + resourcePrefix + "/test_array_strings.ser"));
+        TestArray testArray = (TestArray) oin.readObject();
+        String[] strings = new String[] { "AAA", "BBB" };
+        assertTrue(java.util.Arrays.equals(strings, testArray.array));
+
+        oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
+                "serialization/" + resourcePrefix + "/test_array_integers.ser"));
+        testArray = (TestArray) oin.readObject();
+        Integer[] integers = new Integer[] { 10, 20 };
+        assertTrue(java.util.Arrays.equals(integers, testArray.array));
+    }
+
+    public static class TestExtObject implements Externalizable {
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeInt(10);
+        }
+
+        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            in.readInt();
+        }
+    }
+
+    static class TestObjectOutputStream extends ObjectOutputStream {
+        private ObjectStreamClass[] objs;
+        private int pos = 0;
+
+        public TestObjectOutputStream(OutputStream out, ObjectStreamClass[] objs) throws IOException {
+            super(out);
+            this.objs = objs;
+        }
+
+        @Override
+        protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException {
+            objs[pos++] = osc;        }
+    }
+
+    static class TestObjectInputStream extends ObjectInputStream {
+        private ObjectStreamClass[] objs;
+        private int pos = 0;
+
+        public TestObjectInputStream(InputStream in, ObjectStreamClass[] objs) throws IOException {
+            super(in);
+            this.objs = objs;
+        }
+
+        @Override
+        protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
+            return objs[pos++];
+        }
+    }
+
+    // Regression test for HARMONY-4996
+    public void test_readObject_replacedClassDescriptor() throws Exception {
+        ObjectStreamClass[] objs = new ObjectStreamClass[1000];
+        PipedOutputStream pout = new PipedOutputStream();
+        PipedInputStream pin = new PipedInputStream(pout);
+        ObjectOutputStream oout = new TestObjectOutputStream(pout, objs);
+        oout.writeObject(new TestExtObject());
+        oout.writeObject("test");
+        oout.close();
+        ObjectInputStream oin = new TestObjectInputStream(pin, objs);
+        oin.readObject();
+        oin.readObject();
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
     }
 }
 
+class TestArray implements Serializable
+{
+    private static final long serialVersionUID = 1L;
 
+    public Object[] array;
+
+    public TestArray(Object[] array) {
+        this.array = array;
+    }
+
+}
+
+class Test implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	Class classes[] = new Class[] { byte.class, short.class, int.class,
+			long.class, boolean.class, char.class, float.class, double.class };
+
+	@Override
+    public boolean equals(Object o) {
+		if (!(o instanceof Test)) {
+			return false;
+		}
+		return Arrays.equals(classes, ((Test) o).classes);
+	}
+}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectStreamConstantsTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectStreamConstantsTest.java
index f13c537..b86e9f6 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectStreamConstantsTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/ObjectStreamConstantsTest.java
@@ -19,25 +19,27 @@
 import java.io.ObjectStreamConstants;
 
 import junit.framework.TestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 
-@TestTargetClass(ObjectStreamConstants.class)
 public class ObjectStreamConstantsTest extends TestCase {
 
     /**
      * @tests java.io.ObjectStreamConstants#TC_ENUM
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Constant test, still many constants not tested",
-        method = "!Constants",
-        args = {}
-    )
-    public void test_Constants() {
+    public void test_TC_ENUM() {
         assertEquals(126, ObjectStreamConstants.TC_ENUM);
+    }
+
+    /**
+     * @tests java.io.ObjectStreamConstants#SC_ENUM
+     */
+    public void test_SC_ENUM() {
         assertEquals(16, ObjectStreamConstants.SC_ENUM);
+    }
+
+    /**
+     * @tests java.io.ObjectStreamConstants#TC_MAX
+     */
+    public void test_TC_MAX() {
         assertEquals(126, ObjectStreamConstants.TC_MAX);
     }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/OutputStreamWriterTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/OutputStreamWriterTest.java
index 732ee50..837b443 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/OutputStreamWriterTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/OutputStreamWriterTest.java
@@ -1,81 +1,703 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
 
 import junit.framework.TestCase;
-@TestTargetClass(OutputStreamWriter.class)
+
 public class OutputStreamWriterTest extends TestCase {
-    
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks IOException",
-            method = "getEncoding",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks IOException",
-            method = "close",
-            args = {}
-        )
-    })
-    public void testGetEncoding_StreamClosed() {
-        OutputStreamWriter out = null;
-        try {
-            out = new OutputStreamWriter(new ByteArrayOutputStream(),
-                    "UTF-16BE");
-        } catch (UnsupportedEncodingException e) {
-            fail("Should not throw UnsupportedEncodingException");
-        }
-        try {
-            out.close();
-        } catch (IOException e) {
-            fail("Should not throw IOException");
-        }
-        String result = out.getEncoding();
-        assertNull(result);
+
+    private static final int UPPER = 0xd800;
+
+    private static final int BUFFER_SIZE = 10000;
+
+    private ByteArrayOutputStream out;
+
+    private OutputStreamWriter writer;
+
+    static private final String source = "This is a test message with Unicode character. \u4e2d\u56fd is China's name in Chinese";
+
+    static private final String[] MINIMAL_CHARSETS = new String[] { "US-ASCII",
+            "ISO-8859-1", "UTF-16BE", "UTF-16LE", "UTF-16", "UTF-8" };
+
+    OutputStreamWriter osw;
+
+    InputStreamReader isr;
+
+    private ByteArrayOutputStream fos;
+
+    String testString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\n";
+
+    /*
+     * @see TestCase#setUp()
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        out = new ByteArrayOutputStream();
+        writer = new OutputStreamWriter(out, "utf-8");
+
+        fos = new ByteArrayOutputStream();
+        osw = new OutputStreamWriter(fos);
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "getEncoding",
-        args = {}
-    )
-    public void testGetEncoding_NotHistorical() {
-        OutputStreamWriter out = null;
+    /*
+     * @see TestCase#tearDown()
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            writer.close();
+
+            if (isr != null) {
+                isr.close();
+            }
+            osw.close();
+        } catch (Exception e) {
+            // Ignored
+        }
+
+        super.tearDown();
+    }
+
+    public void testClose() throws Exception {
+        writer.flush();
+        writer.close();
+        try {
+            writer.flush();
+            fail();
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    public void testFlush() throws Exception {
+        writer.write(source);
+        writer.flush();
+        String result = out.toString("utf-8");
+        assertEquals(source, result);
+    }
+
+    /*
+     * Class under test for void write(char[], int, int)
+     */
+    public void testWritecharArrayintint() throws IOException {
+        char[] chars = source.toCharArray();
+
+        // Throws IndexOutOfBoundsException if offset is negative
+        try {
+            writer.write((char[]) null, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        // throws NullPointerException though count is negative
+        try {
+            writer.write((char[]) null, 1, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            writer.write((char[]) null, 1, 1);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            writer.write(new char[0], 0, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            writer.write(chars, -1, 1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            writer.write(chars, 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            writer.write(chars, 1, chars.length);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        writer.write(chars, 1, 2);
+        writer.flush();
+        assertEquals("hi", out.toString("utf-8"));
+        writer.write(chars, 0, chars.length);
+        writer.flush();
+        assertEquals("hi" + source, out.toString("utf-8"));
+
+        writer.close();
+        // After the stream is closed, should throw IOException first
+        try {
+            writer.write((char[]) null, -1, -1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // Expected
+        }
+    }
+
+    /*
+     * Class under test for void write(int)
+     */
+    public void testWriteint() throws IOException {
+        writer.write(1);
+        writer.flush();
+        String str = new String(out.toByteArray(), "utf-8");
+        assertEquals("\u0001", str);
+
+        writer.write(2);
+        writer.flush();
+        str = new String(out.toByteArray(), "utf-8");
+        assertEquals("\u0001\u0002", str);
+
+        writer.write(-1);
+        writer.flush();
+        str = new String(out.toByteArray(), "utf-8");
+        assertEquals("\u0001\u0002\uffff", str);
+
+        writer.write(0xfedcb);
+        writer.flush();
+        str = new String(out.toByteArray(), "utf-8");
+        assertEquals("\u0001\u0002\uffff\uedcb", str);
+
+        writer.close();
+        // After the stream is closed, should throw IOException
+        try {
+            writer.write(1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /*
+     * Class under test for void write(String, int, int)
+     */
+    public void testWriteStringintint() throws IOException {
+        try {
+            writer.write((String) null, 1, 1);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            writer.write("", 0, 1);
+            fail();
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            writer.write("abc", -1, 1);
+            fail();
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            writer.write("abc", 0, -1);
+            fail();
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+        try {
+            writer.write("abc", 1, 3);
+            fail();
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        // Throws IndexOutOfBoundsException before NullPointerException if count
+        // is negative
+        try {
+            writer.write((String) null, -1, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        // Throws NullPointerException before StringIndexOutOfBoundsException
+        try {
+            writer.write((String) null, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        writer.write("abc", 1, 2);
+        writer.flush();
+        assertEquals("bc", out.toString("utf-8"));
+        writer.write(source, 0, source.length());
+        writer.flush();
+        assertEquals("bc" + source, out.toString("utf-8"));
+
+        writer.close();
+        // Throws IndexOutOfBoundsException first if count is negative
+        try {
+            writer.write((String) null, 0, -1);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        try {
+            writer.write((String) null, -1, 0);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+
+        try {
+            writer.write("abc", -1, 0);
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        // Throws IOException
+        try {
+            writer.write("abc", 0, 1);
+            fail("should throw IOException");
+        } catch (IOException e) {
+            // expected
+        }
+    }
+
+    /*
+     * Class under test for void OutputStreamWriter(OutputStream)
+     */
+    public void testOutputStreamWriterOutputStream() throws IOException {
+        try {
+            writer = new OutputStreamWriter(null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        OutputStreamWriter writer2 = new OutputStreamWriter(out);
+        writer2.close();
+    }
+
+    /*
+     * Class under test for void OutputStreamWriter(OutputStream, String)
+     */
+    public void testOutputStreamWriterOutputStreamString() throws IOException {
+        try {
+            writer = new OutputStreamWriter(null, "utf-8");
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            writer = new OutputStreamWriter(out, "");
+            fail();
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+        try {
+            writer = new OutputStreamWriter(out, "badname");
+            fail();
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+        try {
+            writer = new OutputStreamWriter(out, (String) null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        OutputStreamWriter writer2 = new OutputStreamWriter(out, "ascii");
+        assertEquals(Charset.forName("ascii"), Charset.forName(writer2
+                .getEncoding()));
+        writer2.close();
+    }
+
+    /*
+     * Class under test for void OutputStreamWriter(OutputStream)
+     */
+    public void testOutputStreamWriterOutputStreamCharset() throws IOException {
+        Charset cs = Charset.forName("ascii");
+        try {
+            writer = new OutputStreamWriter(null, cs);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            writer = new OutputStreamWriter(out, (Charset) null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        OutputStreamWriter writer2 = new OutputStreamWriter(out, cs);
+        assertEquals(cs, Charset.forName(writer2.getEncoding()));
+        writer2.close();
+    }
+
+    /*
+     * Class under test for void OutputStreamWriter(OutputStream, String)
+     */
+    public void testOutputStreamWriterOutputStreamCharsetEncoder()
+            throws IOException {
+        Charset cs = Charset.forName("ascii");
+        CharsetEncoder enc = cs.newEncoder();
+        try {
+            writer = new OutputStreamWriter(null, enc);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            writer = new OutputStreamWriter(out, (CharsetEncoder) null);
+            fail();
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        OutputStreamWriter writer2 = new OutputStreamWriter(out, enc);
+        assertEquals(cs, Charset.forName(writer2.getEncoding()));
+        writer2.close();
+    }
+
+    public void testGetEncoding() {
+        Charset cs = Charset.forName("utf-8");
+        assertEquals(cs, Charset.forName(writer.getEncoding()));
+    }
+
+    public void testHandleEarlyEOFChar_1() throws IOException {
+        String str = "All work and no play makes Jack a dull boy\n"; //$NON-NLS-1$
+        int NUMBER = 2048;
+        int j = 0;
+        int len = str.length() * NUMBER;
+        char[] strChars = new char[len];
+        for (int i = 0; i < NUMBER; ++i) {
+            for (int k = 0; k < str.length(); ++k) {
+                strChars[j++] = str.charAt(k);
+            }
+        }
+
+        File f = File.createTempFile("one", "by_one");
+        f.deleteOnExit();
+        FileWriter fw = new FileWriter(f);
+        fw.write(strChars);
+        fw.close();
+        FileInputStream fis = new FileInputStream(f);
+        InputStreamReader in = new InputStreamReader(fis);
+        for (int offset = 0; offset < strChars.length; ++offset) {
+            int b = in.read();
+            assertFalse("Early EOF at offset", -1 == b);
+        }
+    }
+
+    public void testHandleEarlyEOFChar_2() throws IOException {
+        int capacity = 65536;
+        byte[] bytes = new byte[capacity];
+        byte[] bs = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = bs[i / 8192];
+        }
+        String inputStr = new String(bytes);
+        int len = inputStr.length();
+        File f = File.createTempFile("FileWriterBugTest ", null); //$NON-NLS-1$
+        f.deleteOnExit();
+        FileWriter writer = new FileWriter(f);
+        writer.write(inputStr);
+        writer.close();
+        long flen = f.length();
+
+        FileReader reader = new FileReader(f);
+        char[] outChars = new char[capacity];
+        int outCount = reader.read(outChars);
+        String outStr = new String(outChars, 0, outCount);
+
+        assertEquals(len, flen);
+        assertEquals(inputStr, outStr);
+    }
+
+    public void testSingleCharIO() throws Exception {
+        InputStreamReader isr = null;
+        for (int i = 0; i < MINIMAL_CHARSETS.length; ++i) {
+            try {
+                out = new ByteArrayOutputStream();
+                writer = new OutputStreamWriter(out, MINIMAL_CHARSETS[i]);
+
+                int upper = UPPER;
+                switch (i) {
+                case 0:
+                    upper = 128;
+                    break;
+                case 1:
+                    upper = 256;
+                    break;
+                }
+
+                for (int c = 0; c < upper; ++c) {
+                    writer.write(c);
+                }
+                writer.flush();
+                byte[] result = out.toByteArray();
+
+                isr = new InputStreamReader(new ByteArrayInputStream(result),
+                        MINIMAL_CHARSETS[i]);
+                for (int expected = 0; expected < upper; ++expected) {
+                    assertEquals("Error when reading bytes in "
+                            + MINIMAL_CHARSETS[i], expected, isr.read());
+                }
+            } finally {
+                try {
+                    isr.close();
+                } catch (Exception e) {
+                }
+                try {
+                    writer.close();
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+
+    public void testBlockIO() throws Exception {
+        InputStreamReader isr = null;
+        char[] largeBuffer = new char[BUFFER_SIZE];
+        for (int i = 0; i < MINIMAL_CHARSETS.length; ++i) {
+            try {
+                out = new ByteArrayOutputStream();
+                writer = new OutputStreamWriter(out, MINIMAL_CHARSETS[i]);
+
+                int upper = UPPER;
+                switch (i) {
+                case 0:
+                    upper = 128;
+                    break;
+                case 1:
+                    upper = 256;
+                    break;
+                }
+
+                int m = 0;
+                for (int c = 0; c < upper; ++c) {
+                    largeBuffer[m++] = (char) c;
+                    if (m == BUFFER_SIZE) {
+                        writer.write(largeBuffer);
+                        m = 0;
+                    }
+                }
+                writer.write(largeBuffer, 0, m);
+                writer.flush();
+                byte[] result = out.toByteArray();
+
+                isr = new InputStreamReader(new ByteArrayInputStream(result),
+                        MINIMAL_CHARSETS[i]);
+                int expected = 0, read = 0, j = 0;
+                while (expected < upper) {
+                    if (j == read) {
+                        read = isr.read(largeBuffer);
+                        j = 0;
+                    }
+                    assertEquals("Error when reading bytes in "
+                            + MINIMAL_CHARSETS[i], expected++, largeBuffer[j++]);
+                }
+            } finally {
+                try {
+                    isr.close();
+                } catch (Exception e) {
+                }
+                try {
+                    writer.close();
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() {
+        assertTrue("Used in tests", true);
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream,
+     *        java.lang.String)
+     */
+    public void test_ConstructorLjava_io_OutputStreamLjava_lang_String()
+            throws UnsupportedEncodingException {
+        osw = new OutputStreamWriter(fos, "8859_1");
+        try {
+            osw = new OutputStreamWriter(fos, "Bogus");
+            fail("Failed to throw Unsupported Encoding exception");
+        } catch (UnsupportedEncodingException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#close()
+     */
+    public void test_close() throws IOException {
+        osw.close();
+
+        try {
+            osw.write(testString, 0, testString.length());
+            fail("Chars written after close");
+        } catch (IOException e) {
+            // Expected
+        }
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        try {
+            OutputStreamWriter writer = new OutputStreamWriter(bout,
+                    "ISO2022JP");
+            writer.write(new char[] { 'a' });
+            writer.close();
+            // the default is ASCII, there should not be any mode changes
+            String converted = new String(bout.toByteArray(), "ISO8859_1");
+            assertTrue("invalid conversion 1: " + converted, converted
+                    .equals("a"));
+
+            bout.reset();
+            writer = new OutputStreamWriter(bout, "ISO2022JP");
+            writer.write(new char[] { '\u3048' });
+            writer.flush();
+            // the byte sequence should not switch to ASCII mode until the
+            // stream is closed
+            converted = new String(bout.toByteArray(), "ISO8859_1");
+            assertTrue("invalid conversion 2: " + converted, converted
+                    .equals("\u001b$B$("));
+            writer.close();
+            converted = new String(bout.toByteArray(), "ISO8859_1");
+            assertTrue("invalid conversion 3: " + converted, converted
+                    .equals("\u001b$B$(\u001b(B"));
+
+            bout.reset();
+            writer = new OutputStreamWriter(bout, "ISO2022JP");
+            writer.write(new char[] { '\u3048' });
+            writer.write(new char[] { '\u3048' });
+            writer.close();
+            // there should not be a mode switch between writes
+            assertEquals("invalid conversion 4", "\u001b$B$($(\u001b(B",
+                    new String(bout.toByteArray(), "ISO8859_1"));
+        } catch (UnsupportedEncodingException e) {
+            // Can't test missing converter
+            System.out.println(e);
+        }
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#flush()
+     */
+    public void test_flush() throws IOException {
+        char[] buf = new char[testString.length()];
+        osw.write(testString, 0, testString.length());
+        osw.flush();
+        openInputStream();
+        isr.read(buf, 0, buf.length);
+        assertTrue("Chars not flushed", new String(buf, 0, buf.length)
+                .equals(testString));
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#getEncoding()
+     */
+    public void test_getEncoding() throws IOException {
+        try {
+            osw = new OutputStreamWriter(fos, "8859_1");
+        } catch (UnsupportedEncodingException e) {
+            assertEquals("Returned incorrect encoding", "8859_1", osw
+                    .getEncoding());
+        }
+
+        OutputStreamWriter out = new OutputStreamWriter(
+                new ByteArrayOutputStream(), "UTF-16BE");
+        out.close();
+
+        String result = out.getEncoding();
+        assertNull(result);
+
+        out = null;
         try {
             out = new OutputStreamWriter(new ByteArrayOutputStream(),
                     "UTF-16BE");
         } catch (UnsupportedEncodingException e) {
             // ok
         }
-        String result = out.getEncoding();
+        result = out.getEncoding();
         assertEquals("UnicodeBigUnmarked", result);
     }
-}
\ No newline at end of file
+
+    /**
+     * @tests java.io.OutputStreamWriter#write(char[], int, int)
+     */
+    public void test_write$CII() throws IOException {
+        char[] buf = new char[testString.length()];
+        osw.write(testString, 0, testString.length());
+        osw.close();
+        openInputStream();
+        isr.read(buf, 0, buf.length);
+        assertTrue("Incorrect chars returned", new String(buf, 0, buf.length)
+                .equals(testString));
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#write(int)
+     */
+    public void test_writeI() throws IOException {
+        osw.write('T');
+        osw.close();
+        openInputStream();
+        int c = isr.read();
+        assertEquals("Incorrect char returned", 'T', (char) c);
+    }
+
+    /**
+     * @tests java.io.OutputStreamWriter#write(java.lang.String, int, int)
+     */
+    public void test_writeLjava_lang_StringII() throws IOException {
+        char[] buf = new char[testString.length()];
+        osw.write(testString, 0, testString.length());
+        osw.close();
+        openInputStream();
+        isr.read(buf);
+        assertTrue("Incorrect chars returned", new String(buf, 0, buf.length)
+                .equals(testString));
+    }
+
+    private void openInputStream() {
+        isr = new InputStreamReader(new ByteArrayInputStream(fos.toByteArray()));
+    }
+}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/RandomAccessFileTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/RandomAccessFileTest.java
index 4756c09..67e1fb5 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/RandomAccessFileTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/RandomAccessFileTest.java
@@ -1,51 +1,984 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.io;
 
+import java.io.EOFException;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
-import junit.framework.TestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-@TestTargetClass(RandomAccessFile.class)
-public class RandomAccessFileTest extends TestCase {
+import java.nio.channels.FileChannel;
+import java.nio.channels.NonWritableChannelException;
+
+public class RandomAccessFileTest extends junit.framework.TestCase {
+
+    public String fileName;
+
+    public boolean ufile = true;
+
+    java.io.RandomAccessFile raf;
+
+    java.io.File f;
+
+    String unihw = "\u0048\u0065\u006C\u0801\u006C\u006F\u0020\u0057\u0081\u006F\u0072\u006C\u0064";
+
+    //java.io.FileOutputStream fos;
+
+    public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_java_io_PrintStream\nTest_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
 
     /**
-     * @tests java.io.RandomAccessFile#RandomAccessFile(java.io.File, java.lang.String)
+     * @tests java.io.RandomAccessFile#RandomAccessFile(java.io.File,
+     *        java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks functionality.",
-        method = "RandomAccessFile",
-        args = {java.io.File.class, java.lang.String.class}
-    )
-    public void test_ConstructorLjava_io_FileLjava_lang_String() throws IOException {
+    public void test_ConstructorLjava_io_FileLjava_lang_String()
+            throws Exception {
+        // Test for method java.io.RandomAccessFile(java.io.File,
+        // java.lang.String)
+        RandomAccessFile raf = new java.io.RandomAccessFile(f, "rw");
+        raf.write(20);
+        raf.seek(0);
+        assertEquals("Incorrect int read/written", 20, raf.read());
+        raf.close();
+        
+        raf = new java.io.RandomAccessFile(f, "rwd");
+        raf.write(20);
+        raf.seek(0);
+        assertEquals("Incorrect int read/written", 20, raf.read());
+        raf.close();
+
+        raf = new java.io.RandomAccessFile(f, "rws");
+        raf.write(20);
+        raf.seek(0);
+        assertEquals("Incorrect int read/written", 20, raf.read());
+        raf.close();
+        
         // Regression for HARMONY-50
         File f = File.createTempFile("xxx", "yyy");
         f.deleteOnExit();
-        RandomAccessFile raf = new RandomAccessFile(f, "rws");
+        raf = new RandomAccessFile(f, "rws");
         raf.close();
 
         f = File.createTempFile("xxx", "yyy");
         f.deleteOnExit();
         raf = new RandomAccessFile(f, "rwd");
-        raf.close();            
+        raf.close();
     }
+
+    /**
+     * @tests java.io.RandomAccessFile#RandomAccessFile(java.lang.String,
+     *        java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String()
+            throws IOException {
+        // Test for method java.io.RandomAccessFile(java.lang.String,
+        // java.lang.String)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.write("Test".getBytes(), 0, 4);
+        raf.close();
+        
+        raf = new java.io.RandomAccessFile(fileName, "rwd");
+        raf.write("Test".getBytes(), 0, 4);
+        raf.close();
+
+        raf = new java.io.RandomAccessFile(fileName, "rws");
+        raf.write("Test".getBytes(), 0, 4);
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#close()
+     */
+    public void test_close() {
+        // Test for method void java.io.RandomAccessFile.close()
+        try {
+            RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+            raf.close();
+            raf.write("Test".getBytes(), 0, 4);
+            fail("Failed to close file properly");
+        } catch (IOException e) {}
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#getFD()
+     */
+    public void test_getFD() throws IOException {
+        // Test for method java.io.FileDescriptor
+        // java.io.RandomAccessFile.getFD()
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        assertTrue("Returned invalid fd", raf.getFD().valid());
+
+        raf.close();
+        assertFalse("Returned valid fd after close", raf.getFD().valid());
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#getFilePointer()
+     */
+    public void test_getFilePointer() throws IOException {
+        // Test for method long java.io.RandomAccessFile.getFilePointer()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.write(fileString.getBytes(), 0, 1000);
+        assertEquals("Incorrect filePointer returned", 1000, raf
+                .getFilePointer());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#length()
+     */
+    public void test_length() throws IOException {
+        // Test for method long java.io.RandomAccessFile.length()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.write(fileString.getBytes());
+        assertEquals("Incorrect length returned", fileString.length(), raf
+                .length());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#read()
+     */
+    public void test_read() throws IOException {
+        // Test for method int java.io.RandomAccessFile.read()
+        FileOutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes("UTF-8"), 0, fileString.length());
+        fos.close();
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+        assertEquals("Incorrect bytes returned from read",
+                fileString.charAt(0), raf.read());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[])
+     */
+    public void test_read$B() throws IOException {
+        // Test for method int java.io.RandomAccessFile.read(byte [])
+        FileOutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes(), 0, fileString.length());
+        fos.close();
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+        byte[] rbuf = new byte[4000];
+        raf.read(rbuf);
+        assertEquals("Incorrect bytes returned from read", fileString,
+                new String(rbuf, 0, fileString.length()));
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[], int, int)
+     */
+    public void test_read$BII() throws IOException {
+        // Test for method int java.io.RandomAccessFile.read(byte [], int, int)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        byte[] rbuf = new byte[4000];
+        FileOutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes(), 0, fileString.length());
+        fos.close();
+        raf.read(rbuf, 0, fileString.length());
+        assertEquals("Incorrect bytes returned from read", fileString,
+                new String(rbuf, 0, fileString.length()));
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readBoolean()
+     */
+    public void test_readBoolean() throws IOException {
+        // Test for method boolean java.io.RandomAccessFile.readBoolean()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeBoolean(true);
+        raf.seek(0);
+        assertTrue("Incorrect boolean read/written", raf.readBoolean());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readByte()
+     */
+    public void test_readByte() throws IOException {
+        // Test for method byte java.io.RandomAccessFile.readByte()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeByte(127);
+        raf.seek(0);
+        assertEquals("Incorrect bytes read/written", 127, raf.readByte());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readChar()
+     */
+    public void test_readChar() throws IOException {
+        // Test for method char java.io.RandomAccessFile.readChar()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeChar('T');
+        raf.seek(0);
+        assertEquals("Incorrect char read/written", 'T', raf.readChar());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readDouble()
+     */
+    public void test_readDouble() throws IOException {
+        // Test for method double java.io.RandomAccessFile.readDouble()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeDouble(Double.MAX_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect double read/written", Double.MAX_VALUE, raf
+                .readDouble(), 0);
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readFloat()
+     */
+    public void test_readFloat() throws IOException {
+        // Test for method float java.io.RandomAccessFile.readFloat()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeFloat(Float.MAX_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect float read/written", Float.MAX_VALUE, raf
+                .readFloat(), 0);
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readFully(byte[])
+     */
+    public void test_readFully$B() throws IOException {
+        // Test for method void java.io.RandomAccessFile.readFully(byte [])
+        byte[] buf = new byte[10];
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeBytes("HelloWorld");
+        raf.seek(0);
+        raf.readFully(buf);
+        assertEquals("Incorrect bytes read/written", "HelloWorld", new String(
+                buf, 0, 10, "UTF-8"));
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readFully(byte[], int, int)
+     */
+    public void test_readFully$BII() throws IOException {
+        // Test for method void java.io.RandomAccessFile.readFully(byte [], int,
+        // int)
+        byte[] buf = new byte[10];
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeBytes("HelloWorld");
+        raf.seek(0);
+        raf.readFully(buf, 0, buf.length);
+        assertEquals("Incorrect bytes read/written", "HelloWorld", new String(
+                buf, 0, 10, "UTF-8"));
+        try {
+            raf.readFully(buf, 0, buf.length);
+            fail("Reading past end of buffer did not throw EOFException");
+        } catch (EOFException e) {}
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readInt()
+     */
+    public void test_readInt() throws IOException {
+        // Test for method int java.io.RandomAccessFile.readInt()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeInt(Integer.MIN_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect int read/written", Integer.MIN_VALUE, raf
+                .readInt());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readLine()
+     */
+    public void test_readLine() throws IOException {
+        // Test for method java.lang.String java.io.RandomAccessFile.readLine()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        String s = "Goodbye\nCruel\nWorld\n";
+        raf.write(s.getBytes("UTF-8"), 0, s.length());
+        raf.seek(0);
+
+        assertEquals("Goodbye", raf.readLine());
+        assertEquals("Cruel", raf.readLine());
+        assertEquals("World", raf.readLine());
+        
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readLong()
+     */
+    public void test_readLong() throws IOException {
+        // Test for method long java.io.RandomAccessFile.readLong()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeLong(Long.MAX_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect long read/written", Long.MAX_VALUE, raf
+                .readLong());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readShort()
+     */
+    public void test_readShort() throws IOException {
+        // Test for method short java.io.RandomAccessFile.readShort()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeShort(Short.MIN_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect long read/written", Short.MIN_VALUE, raf
+                .readShort());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readUnsignedByte()
+     */
+    public void test_readUnsignedByte() throws IOException {
+        // Test for method int java.io.RandomAccessFile.readUnsignedByte()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeByte(-1);
+        raf.seek(0);
+        assertEquals("Incorrect byte read/written", 255, raf.readUnsignedByte());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readUnsignedShort()
+     */
+    public void test_readUnsignedShort() throws IOException {
+        // Test for method int java.io.RandomAccessFile.readUnsignedShort()
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeShort(-1);
+        raf.seek(0);
+        assertEquals("Incorrect byte read/written", 65535, raf
+                .readUnsignedShort());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#readUTF()
+     */
+    public void test_readUTF() throws IOException {
+        // Test for method java.lang.String java.io.RandomAccessFile.readUTF()
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeUTF(unihw);
+        raf.seek(0);
+        assertEquals("Incorrect utf string read", unihw, raf.readUTF());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#seek(long)
+     */
+    public void test_seekJ() throws IOException {
+        // Test for method void java.io.RandomAccessFile.seek(long)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.write(fileString.getBytes(), 0, fileString.length());
+        raf.seek(12);
+        assertEquals("Seek failed to set filePointer", 12, raf.getFilePointer());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#skipBytes(int)
+     */
+    public void test_skipBytesI() throws IOException {
+        // Test for method int java.io.RandomAccessFile.skipBytes(int)
+        byte[] buf = new byte[5];
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeBytes("HelloWorld");
+        raf.seek(0);
+        raf.skipBytes(5);
+        raf.readFully(buf);
+        assertEquals("Failed to skip bytes", "World", new String(buf, 0, 5, "UTF-8"));
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#write(byte[])
+     */
+    public void test_write$B() throws IOException {
+        // Test for method void java.io.RandomAccessFile.write(byte [])
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        
+        byte[] nullByteArray = null;
+        try {
+        	raf.write(nullByteArray);
+        	fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+        	//expected
+        }   
+        
+        byte[] rbuf = new byte[4000];
+        raf.write(fileString.getBytes());
+        raf.close();
+        
+        try {
+        	raf.write(nullByteArray);
+        	fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+        	//expected
+        }  
+        
+        //will not throw IOException if array's length is 0
+        raf.write(new byte[0]);
+        
+        try {
+        	raf.write(fileString.getBytes());
+        	fail("should throw IOException");
+        } catch (IOException e) {
+        	//expected
+        }  
+        
+        FileInputStream fis = new java.io.FileInputStream(fileName);
+        fis.read(rbuf, 0, fileString.length());
+        assertEquals("Incorrect bytes written", fileString, new String(rbuf, 0,
+                fileString.length()));    
+        fis.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#write(byte[], int, int)
+     */
+    public void test_write$BII() throws IOException {
+        // Test for method void java.io.RandomAccessFile.write(byte [], int,
+        // int)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        byte[] rbuf = new byte[4000];
+        raf.write(fileString.getBytes(), 0, fileString.length());
+        raf.close();
+        FileInputStream fis = new java.io.FileInputStream(fileName);
+        fis.read(rbuf, 0, fileString.length());
+        assertEquals("Incorrect bytes written", fileString, new String(rbuf, 0,
+                fileString.length()));
+        fis.close();
+    }
+    
+    /**
+     * @tests java.io.RandomAccessFile#write(byte[], int, int)
+     */
+    public void test_write_$BII_Exception() throws IOException {
+    	raf = new java.io.RandomAccessFile(f, "rw");
+		byte[] nullByteArray = null;
+		byte[] byteArray = new byte[10];
+		
+		try {
+			raf.write(nullByteArray, -1, -1);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+
+		try {
+			raf.write(nullByteArray, 0, 0);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		
+		try {
+			raf.write(nullByteArray, 1, -1);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+
+		try {
+			raf.write(nullByteArray, 1, 0);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		
+		try {
+			raf.write(nullByteArray, 1, 1);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		
+		try {
+			raf.write(byteArray, -1, -1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+
+		try {
+			raf.write(byteArray, -1, 0);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+		
+		try {
+			raf.write(byteArray, -1, 1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+
+		try {
+			raf.write(byteArray, 0, -1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+
+		raf.write(byteArray, 0, 0);
+        raf.write(byteArray, 0, byteArray.length);
+		raf.write(byteArray, 1, 0);
+        raf.write(byteArray, byteArray.length, 0);
+		
+		try {
+			raf.write(byteArray, byteArray.length + 1, 0);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			//expected
+		}
+		
+		try {
+			raf.write(byteArray, byteArray.length + 1, 1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			//expected
+		}
+
+		raf.close();
+
+		try {
+			raf.write(nullByteArray, -1, -1);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		
+		try {
+			raf.write(byteArray, -1, -1);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			// expected
+		}
+		
+		try {
+	        raf.write(byteArray, 0, 1);
+	        fail("should throw IOException");
+		} catch (IOException e) {
+			//expected
+		}
+		
+		try {
+	        raf.write(byteArray, 0, byteArray.length);
+	        fail("should throw IOException");
+		} catch (IOException e) {
+			//expected
+		}
+		
+		try {
+			raf.write(byteArray, 1, 1);
+	        fail("should throw IOException");
+		} catch (IOException e) {
+			//expected
+		}
+		
+		try {
+			raf.write(byteArray, byteArray.length + 1, 0);
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+			//expected
+		}
+		
+		// will not throw IOException if count = 0
+		raf.write(byteArray, 0, 0);
+		raf.write(byteArray, byteArray.length, 0);
+    }
+    
+
+    /**
+     * @tests java.io.RandomAccessFile#write(int)
+     */
+    public void test_writeI() throws IOException {
+        // Test for method void java.io.RandomAccessFile.write(int)
+        byte[] rbuf = new byte[4000];
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.write('t');
+        raf.close();
+        FileInputStream fis = new java.io.FileInputStream(fileName);
+        fis.read(rbuf, 0, 1);
+        assertEquals("Incorrect byte written", 't', rbuf[0]);
+        fis.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeBoolean(boolean)
+     */
+    public void test_writeBooleanZ() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeBoolean(boolean)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeBoolean(true);
+        raf.seek(0);
+        assertTrue("Incorrect boolean read/written", raf.readBoolean());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeByte(int)
+     */
+    public void test_writeByteI() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeByte(int)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeByte(127);
+        raf.seek(0);
+        assertEquals("Incorrect byte read/written", 127, raf.readByte());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeBytes(java.lang.String)
+     */
+    public void test_writeBytesLjava_lang_String() throws IOException {
+        // Test for method void
+        // java.io.RandomAccessFile.writeBytes(java.lang.String)
+        byte[] buf = new byte[10];
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeBytes("HelloWorld");
+        raf.seek(0);
+        raf.readFully(buf);
+        assertEquals("Incorrect bytes read/written", "HelloWorld", new String(
+                buf, 0, 10, "UTF-8"));
+        raf.close();
+
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeChar(int)
+     */
+    public void test_writeCharI() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeChar(int)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeChar('T');
+        raf.seek(0);
+        assertEquals("Incorrect char read/written", 'T', raf.readChar());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeChars(java.lang.String)
+     */
+    public void test_writeCharsLjava_lang_String() throws IOException {
+        // Test for method void
+        // java.io.RandomAccessFile.writeChars(java.lang.String)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeChars("HelloWorld");
+        char[] hchars = new char[10];
+        "HelloWorld".getChars(0, 10, hchars, 0);
+        raf.seek(0);
+        for (int i = 0; i < hchars.length; i++)
+            assertEquals("Incorrect string written", hchars[i], raf.readChar());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeDouble(double)
+     */
+    public void test_writeDoubleD() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeDouble(double)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeDouble(Double.MAX_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect double read/written", Double.MAX_VALUE, raf
+                .readDouble(), 0);
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeFloat(float)
+     */
+    public void test_writeFloatF() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeFloat(float)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeFloat(Float.MAX_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect float read/written", Float.MAX_VALUE, raf
+                .readFloat(), 0);
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeInt(int)
+     */
+    public void test_writeIntI() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeInt(int)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeInt(Integer.MIN_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect int read/written", Integer.MIN_VALUE, raf
+                .readInt());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeLong(long)
+     */
+    public void test_writeLongJ() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeLong(long)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeLong(Long.MAX_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect long read/written", Long.MAX_VALUE, raf
+                .readLong());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeShort(int)
+     */
+    public void test_writeShortI() throws IOException {
+        // Test for method void java.io.RandomAccessFile.writeShort(int)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeShort(Short.MIN_VALUE);
+        raf.seek(0);
+        assertEquals("Incorrect long read/written", Short.MIN_VALUE, raf
+                .readShort());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#writeUTF(java.lang.String)
+     */
+    public void test_writeUTFLjava_lang_String() throws IOException {
+        // Test for method void
+        // java.io.RandomAccessFile.writeUTF(java.lang.String)
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        raf.writeUTF(unihw);
+        raf.seek(0);
+        assertEquals("Incorrect utf string", unihw, raf.readUTF());
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#seek(long)
+     * 
+     * Regression for HARMONY-374
+     */
+    public void test_seekI() throws IOException {
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        try {
+            raf.seek(-1);
+            fail("IOException must be thrown if pos < 0");
+        } catch (IOException e) {
+        }
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[], int, int)
+     * 
+     * Regression for HARMONY-377
+     */
+    public void test_readBII() throws IOException {
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        try {
+            raf.read(new byte[1], -1, 1);
+            fail("IndexOutOfBoundsException must be thrown if off <0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.read(new byte[1], 0, -1);
+            fail("IndexOutOfBoundsException must be thrown if len <0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.read(new byte[1], 0, 5);
+            fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.read(new byte[10], Integer.MAX_VALUE, 5);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.read(new byte[10], 5, Integer.MAX_VALUE);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        raf.close();
+    }
+    
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[],int,int) 
+     */
+    public void test_read_$BII_IndexOutOfBoundsException() throws IOException {
+        FileOutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes(), 0, fileString.length());
+        fos.close();
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+        byte[] rbuf = new byte[100];
+        raf.close();
+        try {
+            raf.read(rbuf,-1,0);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+          //expected
+        }
+    }
+    
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[],int,int) 
+     */
+    public void test_read_$BII_IOException() throws IOException {
+        FileOutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes(), 0, fileString.length());
+        fos.close();
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+        byte[] rbuf = new byte[100];
+        raf.close();
+        int read = raf.read(rbuf,0,0);
+        assertEquals(0,read);
+    }
+    
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[])
+     */
+    public void test_read_$B_IOException() throws IOException {
+        FileOutputStream fos = new java.io.FileOutputStream(fileName);
+        fos.write(fileString.getBytes(), 0, fileString.length());
+        fos.close();
+
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+        byte[] rbuf = new byte[0];
+        raf.close();
+        int read = raf.read(rbuf);
+        assertEquals(0,read);
+    }
+    
+    /**
+     * @tests java.io.RandomAccessFile#read(byte[],int,int) 
+     */
+    public void test_read_$BII_NullPointerException() throws IOException {
+        File f = File.createTempFile("tmp", "tmp");
+        f.deleteOnExit();
+        RandomAccessFile raf = new RandomAccessFile(f, "r");
+        byte[] rbuf = null;
+        try {
+            raf.read(rbuf, 0, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        raf.close();
+    }
+
+    /**
+     * @tests java.io.RandomAccessFile#write(byte[], int, int)
+     * 
+     * Regression for HARMONY-377
+     */
+    public void test_writeBII() throws IOException {
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "rw");
+        try {
+            raf.write(new byte[1], -1, 1);
+            fail("IndexOutOfBoundsException must be thrown if off <0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.write(new byte[1], 0, -1);
+            fail("IndexOutOfBoundsException must be thrown if len <0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.write(new byte[1], 0, 5);
+            fail("IndexOutOfBoundsException must be thrown if off+len > b.length");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.write(new byte[10], Integer.MAX_VALUE, 5);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            raf.write(new byte[10], 5, Integer.MAX_VALUE);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+        }
+        raf.close();
+    }
+
+    /**
+     * Regression for HARMONY-69
+     */
+    public void testRandomAccessFile_String_String() throws IOException {
+        f.createNewFile();
+        RandomAccessFile raf = new java.io.RandomAccessFile(fileName, "r");
+        FileChannel fcr = raf.getChannel();
+
+        try {
+            fcr.lock(0L, Long.MAX_VALUE, false);
+            fail("NonWritableChannelException expected!");
+        } catch (NonWritableChannelException e) {}
+        raf.close();
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        f = File.createTempFile("raf", "tst");
+        if (!f.delete()) {
+            fail("Unable to delete test file : " + f);
+        }
+        fileName = f.getAbsolutePath();
+    }
+
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     * @throws Exception
+     */
+    protected void tearDown() throws Exception {
+        if (f.exists()) {
+            f.delete();
+        }
+        super.tearDown();
+    }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/WriterTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/WriterTest.java
index 5bad541..da3185e 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/WriterTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/WriterTest.java
@@ -4,67 +4,78 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.io;
 
 import java.io.IOException;
 import java.io.Writer;
 
 import junit.framework.TestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 
-@TestTargetClass(Writer.class) 
 public class WriterTest extends TestCase {
 
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            method = "Writer",
-            args = {}
-        )
-    public void test_Writer() {
-        MockWriter w = new MockWriter();
-        assertTrue("Test 1: Lock has not been set correctly.", w.lockSet(w));
-    }
-    
-    @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            method = "Writer",
-            args = {java.lang.Object.class}
-        )
-    public void test_WriterLjava_lang_Object() {
-        Object o = new Object();
-        MockWriter w;
-        
-        try {
-            w = new MockWriter(null);
-            fail("Test 1: NullPointerException expected.");
-        } catch (NullPointerException e) {
-            // Expected.
-        }
-        w = new MockWriter(o);
-        assertTrue("Test 2: Lock has not been set correctly.", w.lockSet(o));
+    /**
+     * @tests java.io.Writer#append(char)
+     */
+    public void test_appendChar() throws IOException {
+        char testChar = ' ';
+        MockWriter writer = new MockWriter(20);
+        writer.append(testChar);
+        assertEquals(String.valueOf(testChar), String.valueOf(writer
+                .getContents()));
+        writer.close();
     }
 
-    class MockWriter extends Writer {
+    /**
+     * @tests java.io.Writer#append(CharSequence)
+     */
+    public void test_appendCharSequence() throws IOException {
+        String testString = "My Test String";
+        MockWriter writer = new MockWriter(20);
+        writer.append(testString);
+        assertEquals(testString, String.valueOf(writer.getContents()));
+        writer.close();
+
+    }
+
+    /**
+     * @tests java.io.Writer#append(CharSequence, int, int)
+     */
+    public void test_appendCharSequenceIntInt() throws IOException {
+        String testString = "My Test String";
+        MockWriter writer = new MockWriter(20);
+        writer.append(testString, 1, 3);
+        assertEquals(testString.substring(1, 3), String.valueOf(writer
+                .getContents()));
+        writer.close();
+
+    }
+
+
+
+    /**
+     * @tests java.io.Writer#write(String)
+     */
+    public void test_writeLjava_lang_String() throws IOException {
+        // Regression for HARMONY-51
+        Object lock = new Object();
+        Writer wr = new MockLockWriter(lock);
+        wr.write("Some string");
+        wr.close();
+    }
+
+    class MockLockWriter extends Writer {
         final Object myLock;
 
-        MockWriter() {
-            super();
-            myLock = this;
-        }
-        
-        MockWriter(Object lock) {
+        MockLockWriter(Object lock) {
             super(lock);
             myLock = lock;
         }
@@ -83,9 +94,55 @@
         public void write(char[] arg0, int arg1, int arg2) throws IOException {
             assertTrue(Thread.holdsLock(myLock));
         }
+    }
 
-        public boolean lockSet(Object o) {
-            return (lock == o);
+    
+    class MockWriter extends Writer {
+        private char[] contents;
+
+        private int length;
+
+        private int offset;
+
+        MockWriter(int capacity) {
+            contents = new char[capacity];
+            length = capacity;
+            offset = 0;
+        }
+
+        public synchronized void close() throws IOException {
+            flush();
+            contents = null;
+        }
+
+        public synchronized void flush() throws IOException {
+            // do nothing
+        }
+
+        public void write(char[] buffer, int offset, int count)
+                throws IOException {
+            if (null == contents) {
+                throw new IOException();
+            }
+            if (offset < 0 || count < 0 || offset >= buffer.length) {
+                throw new IndexOutOfBoundsException();
+            }
+            count = Math.min(count, buffer.length - offset);
+            count = Math.min(count, this.length - this.offset);
+            for (int i = 0; i < count; i++) {
+                contents[this.offset + i] = buffer[offset + i];
+            }
+            this.offset += count;
+
+        }
+
+        public char[] getContents() {
+            char[] result = new char[offset];
+            for (int i = 0; i < offset; i++) {
+                result[i] = contents[i];
+            }
+            return result;
         }
     }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AbstractMethodErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AbstractMethodErrorTest.java
index c3679f1..2166716 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AbstractMethodErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AbstractMethodErrorTest.java
@@ -1,51 +1,62 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import org.apache.harmony.testframework.serialization.SerializationTest;
 
-import junit.framework.TestCase;
+public class AbstractMethodErrorTest extends junit.framework.TestCase {
 
-@TestTargetClass(AbstractMethodError.class)
-public class AbstractMethodErrorTest extends TestCase {
+    /**
+     * @tests {@link java.lang.AbstractMethodError#AbstractMethodError()}
+     */
+    public void test_Constructor() {
+        // Test for method java.lang.AbstractMethodError()
+        Error error = new AbstractMethodError();
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AbstractMethodError",
-        args = {}
-    )
-    public void test_AbstractMethodError() {
-        AbstractMethodError ame = new AbstractMethodError();
-        assertNull(ame.getMessage());
+    /**
+     * @tests {@link java.lang.AbstractMethodError#AbstractMethodError(String)}
+     */
+    public void test_ConstructorLjava_lang_String() {
+        // Test for method java.lang.AbstractMethodError(java.lang.String)
+        Error error = new AbstractMethodError(null);
+        assertNull(error.getMessage());
+        assertNull(error.getCause());
+
+        error = new AbstractMethodError("msg");
+        assertEquals("msg", error.getMessage());
+        assertNull(error.getCause());
     }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AbstractMethodError",
-        args = {java.lang.String.class}
-    )
-    public void test_AbstractMethodError_String() {
-        String message = "Test Message";
-        AbstractMethodError ame = new AbstractMethodError(message);
-        assertEquals(message, ame.getMessage());
+    /**
+     * @tests serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+        SerializationTest.verifySelf(new AbstractMethodError());
     }
+
+    /**
+     * @tests serialization/deserialization compatibility with RI.
+     */
+    public void testSerializationCompatibility() throws Exception {
+        SerializationTest.verifyGolden(this, new AbstractMethodError());
+    }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java
index 438e560..d6fb8ab 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AllTests.java
@@ -30,7 +30,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.lang");
+        TestSuite suite = new TestSuite("Tests for java.lang");
 
         suite.addTestSuite(AbstractMethodErrorTest.class);
         suite.addTestSuite(ArithmeticExceptionTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArithmeticExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArithmeticExceptionTest.java
index bce6f5d..f99be20 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArithmeticExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArithmeticExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(ArithmeticException.class) 
 public class ArithmeticExceptionTest extends TestCase {
 
     /**
      * @tests java.lang.ArithmeticException#ArithmeticException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArithmeticException",
-        args = {}
-    )
     public void test_Constructor() {
         ArithmeticException e = new ArithmeticException();
         assertNull(e.getMessage());
@@ -45,12 +33,6 @@
     /**
      * @tests java.lang.ArithmeticException#ArithmeticException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArithmeticException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         ArithmeticException e = new ArithmeticException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
index 3117e49..c7537c0 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayIndexOutOfBoundsExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(ArrayIndexOutOfBoundsException.class) 
 public class ArrayIndexOutOfBoundsExceptionTest extends TestCase {
 
-    /**
+	/**
      * @tests java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArrayIndexOutOfBoundsException",
-        args = {int.class}
-    )
     public void test_ConstructorI() {
         ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException(-1);
         assertNotNull(e.getMessage());
@@ -47,12 +35,6 @@
     /**
      * @tests java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArrayIndexOutOfBoundsException",
-        args = {}
-    )
     public void test_Constructor() {
         ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException();
         assertNull(e.getMessage());
@@ -62,12 +44,6 @@
     /**
      * @tests java.lang.ArrayIndexOutOfBoundsException#ArrayIndexOutOfBoundsException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArrayIndexOutOfBoundsException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayStoreExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayStoreExceptionTest.java
index d2345cb..c8979d0 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayStoreExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ArrayStoreExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(ArrayStoreException.class) 
 public class ArrayStoreExceptionTest extends TestCase {
 
     /**
      * @tests java.lang.ArrayStoreException#ArrayStoreException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArrayStoreException",
-        args = {}
-    )
     public void test_Constructor() {
         ArrayStoreException e = new ArrayStoreException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.ArrayStoreException#ArrayStoreException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ArrayStoreException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         ArrayStoreException e = new ArrayStoreException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AssertionErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AssertionErrorTest.java
index ec0d40f..e5a51cc 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AssertionErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/AssertionErrorTest.java
@@ -17,33 +17,16 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(AssertionError.class) 
 public class AssertionErrorTest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {}
-    )
     public void test_Constructor() {
         AssertionError e = new AssertionError();
         assertNull(e.getMessage());
         assertNull(e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {java.lang.Object.class}
-    )
+
     public void test_ConstructorObject() {
         Object obj = "toString";
         AssertionError e = new AssertionError(obj);
@@ -55,67 +38,37 @@
         assertEquals(npe.toString(), e.getMessage());
         assertSame(npe, e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {boolean.class}
-    )
+
     public void test_ConstructorBoolean() {
         AssertionError e = new AssertionError(true);
         assertEquals("true", e.getMessage());
         assertNull(e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {char.class}
-    )
+
     public void test_ConstructorChar() {
         AssertionError e = new AssertionError('a');
         assertEquals("a", e.getMessage());
         assertNull(e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {int.class}
-    )
+
     public void test_ConstructorInt() {
         AssertionError e = new AssertionError(1);
         assertEquals("1", e.getMessage());
         assertNull(e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {long.class}
-    )
+
     public void test_ConstructorLong() {
         AssertionError e = new AssertionError(1L);
         assertEquals("1", e.getMessage());
         assertNull(e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {float.class}
-    )
+
     public void test_ConstructorFloat() {
         AssertionError e = new AssertionError(1.0F);
         assertEquals("1.0", e.getMessage());
         assertNull(e.getCause());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AssertionError",
-        args = {double.class}
-    )
+
     public void test_ConstructorDouble() {
         AssertionError e = new AssertionError(1.0D);
         assertEquals("1.0", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/BooleanTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/BooleanTest.java
index 23f9575..4c7c3e4 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/BooleanTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/BooleanTest.java
@@ -16,25 +16,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Boolean.class) 
 public class BooleanTest extends TestCase {
 
     /**
      * @tests java.lang.Boolean#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         assertEquals(1231, Boolean.TRUE.hashCode());
         assertEquals(1237, Boolean.FALSE.hashCode());
@@ -43,12 +31,6 @@
     /**
      * @tests java.lang.Boolean#Boolean(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Boolean",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         assertEquals(Boolean.TRUE, new Boolean("TRUE"));
         assertEquals(Boolean.TRUE, new Boolean("true"));
@@ -61,12 +43,6 @@
     /**
      * @tests java.lang.Boolean#Boolean(boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Boolean",
-        args = {boolean.class}
-    )
     public void test_ConstructorZ() {
         assertEquals(Boolean.TRUE, new Boolean(true));
         assertEquals(Boolean.FALSE, new Boolean(false));
@@ -75,12 +51,6 @@
     /**
      * @tests java.lang.Boolean#booleanValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "booleanValue",
-        args = {}
-    )
     public void test_booleanValue() {
         assertTrue(Boolean.TRUE.booleanValue());
         assertFalse(Boolean.FALSE.booleanValue());
@@ -89,12 +59,6 @@
     /**
      * @tests java.lang.Boolean#equals(Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         assertTrue(Boolean.TRUE.equals(Boolean.TRUE));
         assertTrue(Boolean.TRUE.equals(new Boolean(true)));
@@ -108,12 +72,6 @@
     /**
      * @tests java.lang.Boolean#getBoolean(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getBoolean",
-        args = {java.lang.String.class}
-    )
     public void test_getBooleanLjava_lang_String() {
         System.setProperty(getClass().getName(), "true");
         assertTrue(Boolean.getBoolean(getClass().getName()));
@@ -128,12 +86,6 @@
     /**
      * @tests java.lang.Boolean#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         assertEquals("true", Boolean.TRUE.toString());
         assertEquals("false", Boolean.FALSE.toString());
@@ -142,12 +94,6 @@
     /**
      * @tests java.lang.Boolean#toString(boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {boolean.class}
-    )
     public void test_toStringZ() {
         assertEquals("true", Boolean.toString(true));
         assertEquals("false", Boolean.toString(false));
@@ -156,12 +102,6 @@
     /**
      * @tests java.lang.Boolean#valueOf(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String() {
         assertEquals(Boolean.TRUE, Boolean.valueOf("true"));
         assertEquals(Boolean.FALSE, Boolean.valueOf("false"));
@@ -182,12 +122,6 @@
     /**
      * @tests java.lang.Boolean#valueOf(boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {boolean.class}
-    )
     public void test_valueOfZ() {
         assertEquals(Boolean.TRUE, Boolean.valueOf(true));
         assertEquals(Boolean.FALSE, Boolean.valueOf(false));
@@ -196,12 +130,6 @@
     /**
      * @tests java.lang.Boolean#parseBoolean(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "parseBoolean",
-        args = {java.lang.String.class}
-    )
     public void test_parseBooleanLjava_lang_String() {
         assertTrue(Boolean.parseBoolean("true"));
         assertTrue(Boolean.parseBoolean("TRUE"));
@@ -214,12 +142,6 @@
     /**
      * @tests java.lang.Boolean#compareTo(Boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.lang.Boolean.class}
-    )
     public void test_compareToLjava_lang_Boolean() {
         assertTrue(Boolean.TRUE.compareTo(Boolean.TRUE) == 0);
         assertTrue(Boolean.FALSE.compareTo(Boolean.FALSE) == 0);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ByteTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ByteTest.java
index d99223a..c1317cc 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ByteTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ByteTest.java
@@ -16,25 +16,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Byte.class) 
 public class ByteTest extends TestCase {
 
     /**
      * @tests java.lang.Byte#valueOf(byte)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {byte.class}
-    )
     public void test_valueOfB() {
         assertEquals(new Byte(Byte.MIN_VALUE), Byte.valueOf(Byte.MIN_VALUE));
         assertEquals(new Byte(Byte.MAX_VALUE), Byte.valueOf(Byte.MAX_VALUE));
@@ -51,12 +39,6 @@
     /**
      * @tests java.lang.Byte#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         assertEquals(1, new Byte((byte) 1).hashCode());
         assertEquals(2, new Byte((byte) 2).hashCode());
@@ -67,12 +49,6 @@
     /**
      * @tests java.lang.Byte#Byte(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Byte",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         assertEquals(new Byte((byte) 0), new Byte("0"));
         assertEquals(new Byte((byte) 1), new Byte("1"));
@@ -106,12 +82,6 @@
     /**
      * @tests java.lang.Byte#Byte(byte)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Byte",
-        args = {byte.class}
-    )
     public void test_ConstructorB() {
         assertEquals(1, new Byte((byte) 1).byteValue());
         assertEquals(2, new Byte((byte) 2).byteValue());
@@ -122,13 +92,7 @@
     /**
      * @tests java.lang.Byte#byteValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "byteValue",
-        args = {}
-    )
-    public void test_byteValue1() {
+    public void test_booleanValue() {
         assertEquals(1, new Byte((byte) 1).byteValue());
         assertEquals(2, new Byte((byte) 2).byteValue());
         assertEquals(0, new Byte((byte) 0).byteValue());
@@ -138,12 +102,6 @@
     /**
      * @tests java.lang.Byte#equals(Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         assertEquals(new Byte((byte) 0), Byte.valueOf((byte) 0));
         assertEquals(new Byte((byte) 1), Byte.valueOf((byte) 1));
@@ -158,12 +116,6 @@
     /**
      * @tests java.lang.Byte#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         assertEquals("-1", new Byte((byte) -1).toString());
         assertEquals("0", new Byte((byte) 0).toString());
@@ -174,12 +126,6 @@
     /**
      * @tests java.lang.Byte#toString(byte)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {byte.class}
-    )
     public void test_toStringB() {
         assertEquals("-1", Byte.toString((byte) -1));
         assertEquals("0", Byte.toString((byte) 0));
@@ -190,12 +136,6 @@
     /**
      * @tests java.lang.Byte#valueOf(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Checks only positive functionality.",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String() {
         assertEquals(new Byte((byte) 0), Byte.valueOf("0"));
         assertEquals(new Byte((byte) 1), Byte.valueOf("1"));
@@ -229,12 +169,6 @@
     /**
      * @tests java.lang.Byte#valueOf(String,int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check boundary values.",
-        method = "valueOf",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_valueOfLjava_lang_StringI() {
         assertEquals(new Byte((byte) 0), Byte.valueOf("0", 10));
         assertEquals(new Byte((byte) 1), Byte.valueOf("1", 10));
@@ -272,12 +206,6 @@
     /**
      * @tests java.lang.Byte#parseByte(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "parseByte",
-        args = {java.lang.String.class}
-    )
     public void test_parseByteLjava_lang_String() {
         assertEquals(0, Byte.parseByte("0"));
         assertEquals(1, Byte.parseByte("1"));
@@ -311,12 +239,6 @@
     /**
      * @tests java.lang.Byte#parseByte(String,int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check boundary values.",
-        method = "parseByte",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_parseByteLjava_lang_StringI() {
         assertEquals(0, Byte.parseByte("0", 10));
         assertEquals(1, Byte.parseByte("1", 10));
@@ -354,12 +276,6 @@
     /**
      * @tests java.lang.Byte#decode(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "decode",
-        args = {java.lang.String.class}
-    )
     public void test_decodeLjava_lang_String() {
         assertEquals(new Byte((byte) 0), Byte.decode("0"));
         assertEquals(new Byte((byte) 1), Byte.decode("1"));
@@ -392,12 +308,6 @@
     /**
      * @tests java.lang.Byte#doubleValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "No boundary verification.",
-        method = "doubleValue",
-        args = {}
-    )
     public void test_doubleValue() {
         assertEquals(-1D, new Byte((byte) -1).doubleValue(), 0D);
         assertEquals(0D, new Byte((byte) 0).doubleValue(), 0D);
@@ -407,12 +317,6 @@
     /**
      * @tests java.lang.Byte#floatValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify boundary values.",
-        method = "floatValue",
-        args = {}
-    )
     public void test_floatValue() {
         assertEquals(-1F, new Byte((byte) -1).floatValue(), 0F);
         assertEquals(0F, new Byte((byte) 0).floatValue(), 0F);
@@ -422,12 +326,6 @@
     /**
      * @tests java.lang.Byte#intValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "No boundary verification.",
-        method = "intValue",
-        args = {}
-    )
     public void test_intValue() {
         assertEquals(-1, new Byte((byte) -1).intValue());
         assertEquals(0, new Byte((byte) 0).intValue());
@@ -437,12 +335,6 @@
     /**
      * @tests java.lang.Byte#longValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "No boundary verification.",
-        method = "longValue",
-        args = {}
-    )
     public void test_longValue() {
         assertEquals(-1L, new Byte((byte) -1).longValue());
         assertEquals(0L, new Byte((byte) 0).longValue());
@@ -452,12 +344,6 @@
     /**
      * @tests java.lang.Byte#shortValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check boundary values.",
-        method = "shortValue",
-        args = {}
-    )
     public void test_shortValue() {
         assertEquals(-1, new Byte((byte) -1).shortValue());
         assertEquals(0, new Byte((byte) 0).shortValue());
@@ -467,12 +353,6 @@
     /**
      * @tests java.lang.Byte#compareTo(Byte)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.lang.Byte.class}
-    )
     public void test_compareToLjava_lang_Byte() {
         final Byte min = new Byte(Byte.MIN_VALUE);
         final Byte zero = new Byte((byte) 0);
@@ -501,12 +381,6 @@
     /**
      * @tests java.lang.Byte#Byte(byte)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Boundary test.",
-        method = "Byte",
-        args = {byte.class}
-    )
     public void test_ConstructorB2() {
         // Test for method java.lang.Byte(byte)
 
@@ -517,12 +391,6 @@
     /**
      * @tests java.lang.Byte#Byte(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't check empty string or null.",
-        method = "Byte",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String2() {
         // Test for method java.lang.Byte(java.lang.String)
 
@@ -536,12 +404,6 @@
     /**
      * @tests java.lang.Byte#byteValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Boundary test.",
-        method = "byteValue",
-        args = {}
-    )
     public void test_byteValue() {
         // Test for method byte java.lang.Byte.byteValue()
         assertTrue("Returned incorrect byte value",
@@ -551,12 +413,6 @@
     /**
      * @tests java.lang.Byte#compareTo(java.lang.Byte)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.lang.Byte.class}
-    )
     public void test_compareToLjava_lang_Byte2() {
         // Test for method int java.lang.Byte.compareTo(java.lang.Byte)
         assertTrue("Comparison failed", new Byte((byte) 1).compareTo(new Byte((byte) 2)) < 0);
@@ -567,12 +423,6 @@
     /**
      * @tests java.lang.Byte#decode(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "decode",
-        args = {java.lang.String.class}
-    )
     public void test_decodeLjava_lang_String2() {
         // Test for method java.lang.Byte
         // java.lang.Byte.decode(java.lang.String)
@@ -633,12 +483,6 @@
     /**
      * @tests java.lang.Byte#doubleValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks boundary value.",
-        method = "doubleValue",
-        args = {}
-    )
     public void test_doubleValue2() {
         assertEquals(127D, new Byte((byte) 127).doubleValue(), 0.0);
     }
@@ -646,12 +490,6 @@
     /**
      * @tests java.lang.Byte#equals(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Checks that negative value doesn't equal to positive.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object2() {
         // Test for method boolean java.lang.Byte.equals(java.lang.Object)
         Byte b1 = new Byte((byte) 90);
@@ -664,12 +502,6 @@
     /**
      * @tests java.lang.Byte#floatValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Boundary test.",
-        method = "floatValue",
-        args = {}
-    )
     public void test_floatValue2() {
         assertEquals(127F, new Byte((byte) 127).floatValue(), 0.0);
     }
@@ -677,12 +509,6 @@
     /**
      * @tests java.lang.Byte#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Boundary test.",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode2() {
         // Test for method int java.lang.Byte.hashCode()
         assertEquals("Incorrect hash returned", 127, new Byte((byte) 127).hashCode());
@@ -691,12 +517,6 @@
     /**
      * @tests java.lang.Byte#intValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Boundary test.",
-        method = "intValue",
-        args = {}
-    )
     public void test_intValue2() {
         // Test for method int java.lang.Byte.intValue()
         assertEquals("Returned incorrect int value", 127, new Byte((byte) 127).intValue());
@@ -705,12 +525,6 @@
     /**
      * @tests java.lang.Byte#longValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies boundary values.",
-        method = "longValue",
-        args = {}
-    )
     public void test_longValue2() {
         // Test for method long java.lang.Byte.longValue()
         assertEquals("Returned incorrect long value", 127L, new Byte((byte) 127).longValue());
@@ -719,12 +533,6 @@
     /**
      * @tests java.lang.Byte#parseByte(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Boundary verification.",
-        method = "parseByte",
-        args = {java.lang.String.class}
-    )
     public void test_parseByteLjava_lang_String2() {
         assertEquals((byte)127, Byte.parseByte("127"));
         assertEquals((byte)-128, Byte.parseByte("-128"));
@@ -754,12 +562,6 @@
     /**
      * @tests java.lang.Byte#parseByte(java.lang.String, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Boundary test.",
-        method = "parseByte",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_parseByteLjava_lang_StringI2() {
         // Test for method byte java.lang.Byte.parseByte(java.lang.String, int)
         byte b = Byte.parseByte("127", 10);
@@ -811,12 +613,6 @@
     /**
      * @tests java.lang.Byte#shortValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Boundary test.",
-        method = "shortValue",
-        args = {}
-    )
     public void test_shortValue2() {
         assertEquals((short)127, new Byte((byte)127).shortValue());
     }
@@ -824,12 +620,6 @@
     /**
      * @tests java.lang.Byte#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Boundary test.",
-        method = "toString",
-        args = {}
-    )
     public void test_toString2() {
         assertEquals("Returned incorrect String", "127", new Byte((byte) 127).toString());
         assertEquals("Returned incorrect String", "-127", new Byte((byte) -127).toString());
@@ -839,12 +629,6 @@
     /**
      * @tests java.lang.Byte#toString(byte)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Boundary test.",
-        method = "toString",
-        args = {byte.class}
-    )
     public void test_toStringB2() {
         assertEquals("Returned incorrect String", "127", Byte.toString((byte) 127));
         assertEquals("Returned incorrect String", "-127", Byte.toString((byte) -127));
@@ -854,12 +638,6 @@
     /**
      * @tests java.lang.Byte#valueOf(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Boundary test.",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String2() {
         assertEquals("Returned incorrect byte", 0, Byte.valueOf("0").byteValue());
         assertEquals("Returned incorrect byte", 127, Byte.valueOf("127").byteValue());
@@ -876,12 +654,6 @@
     /**
      * @tests java.lang.Byte#valueOf(java.lang.String, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Boundary test.",
-        method = "valueOf",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_valueOfLjava_lang_StringI2() {
         assertEquals("Returned incorrect byte", 10, Byte.valueOf("A", 16).byteValue());
         assertEquals("Returned incorrect byte", 127, Byte.valueOf("127", 10).byteValue());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java
index 9a10cc4..a81775e 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CharacterImplTest.java
@@ -16,23 +16,10 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Character.class)
 public class CharacterImplTest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {char.class}
-    )
     public void test_valueOfC() {
         // test the cache range
 // BEGIN android-changed
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_SubsetTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_SubsetTest.java
index f99fb86..a44a31d 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_SubsetTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_SubsetTest.java
@@ -92,8 +92,4 @@
       assertFalse(subset1.hashCode() == subset2.hashCode());      
       assertFalse(subset1.hashCode() == subset3.hashCode());
     }
-    
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(Character_SubsetTest.class);
-    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_UnicodeBlockTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_UnicodeBlockTest.java
index 0766f28..cd485f2 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_UnicodeBlockTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/Character_UnicodeBlockTest.java
@@ -16,22 +16,10 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Character.UnicodeBlock.class) 
 public class Character_UnicodeBlockTest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "of",
-        args = {char.class}
-    )
     public void test_ofC() {
         assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of((char)0x0));
         assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of((char)0x7f));
@@ -270,12 +258,6 @@
         assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of((char)0xfff0));
         assertEquals(Character.UnicodeBlock.SPECIALS, Character.UnicodeBlock.of((char)0xffff));
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check exception.",
-        method = "of",
-        args = {int.class}
-    )
     public void test_ofI() {
         assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of(0x0));
         assertEquals(Character.UnicodeBlock.BASIC_LATIN, Character.UnicodeBlock.of(0x7f));
@@ -578,12 +560,7 @@
         assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.of(0x100000));
         assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.of(0x10ffff));
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks IllegalArgumentException.",
-        method = "of",
-        args = {int.class}
-    )
+    
     public void test_ofIExceptions() {
         try {
             Character.UnicodeBlock.of(Character.MAX_CODE_POINT + 1);
@@ -591,12 +568,7 @@
         } catch(IllegalArgumentException e) {
         }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check null.",
-        method = "forName",
-        args = {java.lang.String.class}
-    )
+    
     @SuppressWarnings("deprecation")
     public void test_forNameLjava_lang_String() {
         assertEquals(Character.UnicodeBlock.SURROGATES_AREA, Character.UnicodeBlock.forName("SURROGATES_AREA"));
@@ -891,12 +863,6 @@
         assertEquals(Character.UnicodeBlock.SUPPLEMENTARY_PRIVATE_USE_AREA_B, Character.UnicodeBlock.forName("SupplementaryPrivateUseArea-B"));
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks null as a parameter.",
-        method = "forName",
-        args = {java.lang.String.class}
-    )
     public void test_forNameLjava_lang_StringExceptions() {
         try {
             Character.UnicodeBlock.forName(null);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCastExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCastExceptionTest.java
index 1e61f87..bc56cef 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCastExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCastExceptionTest.java
@@ -17,44 +17,26 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(ClassCastException.class) 
 public class ClassCastExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.ClassCastException#ClassCastException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassCastException",
-        args = {}
-    )
-    public void test_Constructor() {
+	/**
+	 * @tests java.lang.ClassCastException#ClassCastException()
+	 */
+	public void test_Constructor() {
         ClassCastException e = new ClassCastException();
         assertNull(e.getMessage());
         assertNull(e.getLocalizedMessage());
         assertNull(e.getCause());
-    }
+	}
 
-    /**
-     * @tests java.lang.ClassCastException#ClassCastException(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassCastException",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
+	/**
+	 * @tests java.lang.ClassCastException#ClassCastException(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
         ClassCastException e = new ClassCastException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
-    }
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCircularityErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCircularityErrorTest.java
index 7acf714..b062a8c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCircularityErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassCircularityErrorTest.java
@@ -1,51 +1,39 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import junit.framework.TestCase; // android-changed
 
-import junit.framework.TestCase;
-
-@TestTargetClass(ClassCircularityError.class) 
-public class ClassCircularityErrorTest extends TestCase {
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassCircularityError",
-        args = {}
-    )
+public class ClassCircularityErrorTest extends TestCase { // android-changed
+    // Thrown when a circularity has been detected while initializing a class.
+    /**
+     * @tests java.lang.ClassCircularityError#ClassCircularityError()
+     */
     public void test_ClassCircularityError() {
-      ClassCircularityError cce = new ClassCircularityError();
-      assertNull(cce.getMessage());
+        new ClassCircularityError();
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassCircularityError",
-        args = {java.lang.String.class}
-    )
-    public void test_ClassCircularityError_String() {
-      String message = "Test message";
-      ClassCircularityError cce = new ClassCircularityError(message);
-      assertEquals(message, cce.getMessage());
-    }    
+
+    /**
+     * @tests java.lang.ClassCircularityError#ClassCircularityError(java.lang.String)
+     */
+    public void test_ClassCircularityError_LString() {
+        ClassCircularityError e = new ClassCircularityError(
+                "Some Error message");
+        assertEquals("Wrong message", "Some Error message", e.getMessage());
+    }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassFormatErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassFormatErrorTest.java
index 0aeef9b..2fd9aac 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassFormatErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassFormatErrorTest.java
@@ -1,51 +1,43 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import junit.framework.TestCase; // android-changed
 
-import junit.framework.TestCase;
+public class ClassFormatErrorTest extends TestCase { // android-changed
+    /**
+     * Thrown when the Java Virtual Machine attempts to read a class file and
+     * determines that the file is malformed or otherwise cannot be interpreted
+     * as a class file.
+     */
 
-@TestTargetClass(ClassFormatError.class) 
-public class ClassFormatErrorTest extends TestCase {
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassFormatError",
-        args = {}
-    )
+    /**
+     * @tests java.lang.ClassFormatError#ClassFormatError()
+     */
     public void test_ClassFormatError() {
-      ClassFormatError cfe = new ClassFormatError();
-      assertNull(cfe.getMessage());
+        new ClassFormatError();
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassFormatError",
-        args = {java.lang.String.class}
-    )
-    public void test_ClassFormatError_String() {
-      String message = "Test message";
-      ClassFormatError cfe = new ClassFormatError(message);
-      assertEquals(message, cfe.getMessage());
-    }    
+
+    /**
+     * @tests java.lang.ClassFormatError#ClassFormatError(java.lang.String)
+     */
+    public void test_ClassFormatError_LString() {
+        ClassFormatError e = new ClassFormatError("Some Error Message");
+        assertEquals("Wrong message", "Some Error Message", e.getMessage());
+    }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
index 43a73ed..22f49bb 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassLoaderTest.java
@@ -17,304 +17,41 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.ByteBuffer;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.Policy;
 import java.security.ProtectionDomain;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
+import java.security.SecurityPermission;
 
-@TestTargetClass(ClassLoader.class) 
+import junit.framework.TestCase;
+
 public class ClassLoaderTest extends TestCase {
-    
-    private static final String SYSTEM_RESOURCE_PATH = "META-INF/MANIFEST.MF";
+
     public static volatile int flag;
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassLoader",
-        args = {}
-    )
-    public void test_ClassLoader() {
-        PublicClassLoader pcl = new PublicClassLoader();
-        SecurityManager sm = new SecurityManager() {
-            RuntimePermission rp = new RuntimePermission("getProtectionDomain");
-
-            public void checkCreateClassLoader() {
-                throw new SecurityException();
-            }
-            
-            public void checkPermission(Permission perm) {
-                if (perm.equals(rp)) {
-                    throw new SecurityException();
-                }
-            }
-        };
-
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            new PublicClassLoader();
-            fail("SecurityException should be thrown.");
-        } catch (SecurityException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldSm);
-        }
-    } 
- 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassLoader",
-        args = {java.lang.ClassLoader.class}
-    )
-    @BrokenTest("Infinite loop in classloader. Actually a known failure.")
-    public void test_ClassLoaderLClassLoader() {
-      PublicClassLoader pcl = new PublicClassLoader(
-                                            ClassLoader.getSystemClassLoader());
-      assertEquals(ClassLoader.getSystemClassLoader(), pcl.getParent());
-      
-      SecurityManager sm = new SecurityManager() {
-          RuntimePermission rp = new RuntimePermission("getProtectionDomain");
-
-          public void checkCreateClassLoader() {
-              throw new SecurityException();
-          }
-                  
-          public void checkPermission(Permission perm) {
-              if (perm.equals(rp)) {
-                  throw new SecurityException();
-              }
-          }
-      };
-
-      SecurityManager oldSm = System.getSecurityManager();
-      System.setSecurityManager(sm);
-      try {
-          new PublicClassLoader(ClassLoader.getSystemClassLoader());
-          fail("SecurityException should be thrown.");
-      } catch (SecurityException e) {
-          // expected
-      } finally {
-          System.setSecurityManager(oldSm);
-      }
-    }     
-
-    @TestTargetNew(
-        level = TestLevel.NOT_NECESSARY,
-        notes = "",
-        method = "clearAssertionStatus",
-        args = {}
-    )
-    @KnownFailure("Android doesn't support assertions to be activated " +
-            "through the api")
-    public void test_clearAssertionStatus() {
-        String className = getClass().getPackage().getName() + ".TestAssertions";
-        String className1 = getClass().getPackage().getName() + ".TestAssertions1";
-        ClassLoader cl = getClass().getClassLoader();
-        cl.setClassAssertionStatus("TestAssertions", true);
-        cl.setDefaultAssertionStatus(true);
-        try {
-          
-            Class clazz = cl.loadClass(className);
-            
-              TestAssertions ta = (TestAssertions) clazz.newInstance();
-              try {
-                  ta.test();
-                  fail("AssertionError should be thrown.");
-              } catch(AssertionError ae) {
-                  //expected
-              }
-              cl.clearAssertionStatus();
-              clazz = cl.loadClass(className1);
-              
-              TestAssertions1 ta1 = (TestAssertions1) clazz.newInstance();
-              try {
-                  ta1.test();
-              } catch(AssertionError ae) {
-                  fail("AssertionError should not be thrown.");
-              }
-              
-        } catch(Exception cnfe) {
-            fail("Unexpected exception: " + cnfe.toString());
-        }
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This method is not supported. " +
-                "UnsupportedOperationException should be thrown.",
-        method = "defineClass",
-        args = {byte[].class, int.class, int.class}
-    )
-    @AndroidOnly("define methods re not supported on Android. " +
-            "UnsupportedOperationException should be thrown.")
-    public void test_defineClassLbyteArrayLintLint() throws Exception {
-
-        try {
-            Class<?> a = new Ldr().define(Ldr.TEST_CASE_DEFINE_1);
-            //assertEquals("org.apache.harmony.luni.tests.java.lang.A", a.getName());
-            fail("UnsupportedOperationException was not thrown.");
-        } catch(UnsupportedOperationException uoe) {
-            //expected
-        }
-        
-        try {
-            new Ldr().define(1000, Ldr.TEST_CASE_DEFINE_1);
-            fail("IndexOutOfBoundsException is not thrown.");
-        } catch(IndexOutOfBoundsException  ioobe) {
-            fail("UnsupportedOperationException should be thrown.");
-        } catch(UnsupportedOperationException uoe) {
-            //expected  
-        }
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This method is not supported. UnsupportedOperationException should be thrown.",
-        method = "defineClass",
-        args = {java.lang.String.class, byte[].class, int.class, int.class, java.security.ProtectionDomain.class}
-    )
-    @AndroidOnly("define methods re not supported on Android. " +
-            "UnsupportedOperationException should be thrown.")    
-    public void test_defineClassLjava_lang_StringLbyteArrayLintLintLProtectionDomain()
-                    throws Exception {
-        
-        try {
-            Class<?> a = new Ldr().define(Ldr.TEST_CASE_DEFINE_2);
-            //assertEquals("org.apache.harmony.luni.tests.java.lang.A", a.getName());
-            //assertEquals(getClass().getProtectionDomain(), a.getProtectionDomain());
-            fail("UnsupportedOperationException was not thrown.");
-        } catch(UnsupportedOperationException uoe) {
-            //expected
-        }        
-        
-        try {
-            new Ldr().define(1000, Ldr.TEST_CASE_DEFINE_2);
-            fail("IndexOutOfBoundsException is not thrown.");
-        } catch(IndexOutOfBoundsException  ioobe) {
-            fail("UnsupportedOperationException should be thrown.");
-        } catch(UnsupportedOperationException uoe) {
-            //expected  
-        }
-        
-      /*try {
-            ErrorLdr loader = new ErrorLdr();
-            
-            try {
-                loader.define("WrongFormatClass", Ldr.TEST_CASE_DEFINE_2);
-                fail("ClassFormatError should be thrown.");
-            } catch (ClassFormatError le) {
-                //expected
-            } catch(UnsupportedOperationException uoe) {
-                //expected  
-            }
-            
-            try {
-                loader.defineWrongName("TestClass", 0);
-                fail("NoClassDefFoundError should be thrown.");
-            } catch (NoClassDefFoundError ncdfe) {
-                //expected
-            } catch(UnsupportedOperationException uoe) {
-                //expected  
-            }            
-            
-            try {
-                Class<?> clazz = loader.defineNullDomain("TestClass", 0);
-                assertEquals(getClass().getProtectionDomain(), 
-                        clazz.getProtectionDomain());
-            } catch(UnsupportedOperationException uoe) {
-                //expected  
-            }
-                      
-        } catch(Exception e) {
-            fail("Unexpected exception was thrown: " + e.toString());
-        }
-        */
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This method is not supported. UnsupportedOperationException should be thrown.",
-        method = "defineClass",
-        args = {java.lang.String.class, java.nio.ByteBuffer.class, java.security.ProtectionDomain.class}
-    )
-    @AndroidOnly("define methods re not supported on Android. " +
-            "UnsupportedOperationException should be thrown.")    
-    public void test_defineClassLjava_lang_StringLByteBufferLProtectionDomain() {
-         
-        try {
-            try {
-                Class<?> a = new Ldr().define(Ldr.TEST_CASE_DEFINE_3);
-                //assertEquals("org.apache.harmony.luni.tests.java.lang.A", a.getName());
-                //assertEquals(getClass().getProtectionDomain(), a.getProtectionDomain());
-                fail("UnsupportedOperationException was not thrown.");
-            } catch(UnsupportedOperationException uoe) {
-                //expected
-            }                  
-        
-            try {
-                new Ldr().define(1000, Ldr.TEST_CASE_DEFINE_3);
-                fail("IndexOutOfBoundsException is not thrown.");
-            } catch(IndexOutOfBoundsException  ioobe) {
-                fail("UnsupportedOperationException should be thrown.");
-            } catch(UnsupportedOperationException uoe) {
-                //expected  
-            }
-    
-        } catch(Exception e) {
-            fail("Unexpected exception was thrown: " + e.toString());
-        }        
-    }
-    
     /**
      * Tests that Classloader.defineClass() assigns appropriate 
      * default domains to the defined classes.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This method is not supported. " +
-                "UnsupportedOperationException should be thrown.",
-        method = "defineClass",
-        args = {java.lang.String.class, byte[].class, int.class, int.class}
-    )
-    @AndroidOnly("define methods re not supported on Android. " +
-            "UnsupportedOperationException should be thrown.")  
     public void test_defineClass_defaultDomain() throws Exception {
+        // Regression for HARMONY-765 
+        DynamicPolicy plc = new DynamicPolicy();
+        Policy back = Policy.getPolicy();
         try {
-            Class<?> a = new Ldr().define(Ldr.TEST_CASE_DEFINE_0);
-            fail("UnsupportedOperationException was not thrown.");
-        } catch(UnsupportedOperationException uoe) {
-            //expected
-        }  
-        
-        try {
-            new Ldr().define(1000, Ldr.TEST_CASE_DEFINE_0);
-            fail("IndexOutOfBoundsException is not thrown.");
-        } catch(IndexOutOfBoundsException  ioobe) {
-            fail("UnsupportedOperationException should be thrown.");
-        } catch(UnsupportedOperationException uoe) {
-            //expected  
+            Policy.setPolicy(plc);
+
+            Class<?> a = new Ldr().define();
+
+            Permission p = new SecurityPermission("abc");
+            assertFalse("impossible! misconfiguration?", a.getProtectionDomain().implies(p));
+
+            plc.pc = p.newPermissionCollection();
+            plc.pc.add(p);
+            assertTrue("default domain is not dynamic", a.getProtectionDomain().implies(p));
+        } finally {
+            Policy.setPolicy(back);
         }
     }
     
@@ -354,7 +91,8 @@
             0, 1, 0, 1, 0, 8, 0, 0, 0, 2,
             0, 9 };
 
-        protected Class findClass(String name) throws ClassNotFoundException {
+        @Override
+        protected Class<?> findClass(String name) throws ClassNotFoundException {
             try {
                 while (flag != 2) {
                     synchronized (lock) {
@@ -366,21 +104,21 @@
             if (name.equals("TestClass")) {
                 numFindClassCalled++;
                 return defineClass(null, classData, 0, classData.length);
-            } else {
-                throw new ClassNotFoundException("Class " + name + " not found.");
             }
+            throw new ClassNotFoundException("Class " + name + " not found.");
         }
     }
     
     static class SyncLoadTestThread extends Thread {
         volatile boolean started;
         ClassLoader cl;
-        Class cls;
+        Class<?> cls;
         
         SyncLoadTestThread(ClassLoader cl) {
             this.cl = cl;
         }
         
+        @Override
         public void run() {
             try {
                 started = true;
@@ -397,14 +135,6 @@
      * and the same classloader. It is expected that both threads succeed but
      * class must be defined just once.  
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Regression test.",
-        method = "loadClass",
-        args = {java.lang.String.class}
-    )
-    @BrokenTest("Defining classes not supported, unfortunately the test appears"
-            + " to succeed, which is not true, so marking it broken.")
     public void test_loadClass_concurrentLoad() throws Exception 
     {    
         Object lock = new Object();
@@ -430,109 +160,13 @@
         assertEquals("Both threads tried to define class", 1, cl.numFindClassCalled);
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "loadClass",
-        args = {java.lang.String.class}
-    )    
-    public void test_loadClassLjava_lang_String() {
-        
-        String [] classNames = {"org.apache.harmony.luni.tests.java.lang.TestClass1",
-                "org.apache.harmony.luni.tests.java.lang.TestClass3",
-                "org.apache.harmony.luni.tests.java.lang.A"};
-        
-        ClassLoader cl = getClass().getClassLoader();
-        for(String str:classNames) {
-            try {
-                Class<?> clazz = cl.loadClass(str);
-                assertNotNull(clazz);
-                assertEquals(str, clazz.getName());
-                if(str.endsWith("A"))
-                    clazz.newInstance();
-                if(str.endsWith("TestClass1")) {
-                    try {
-                        clazz.newInstance();
-                        fail("ExceptionInInitializerError was not thrown.");
-                    } catch(ExceptionInInitializerError eiine) {
-                        //expected
-                    }
-                }
-                if(str.endsWith("TestClass3")) {
-                    try {
-                        clazz.newInstance();
-                        fail("IllegalAccessException was not thrown.");
-                    } catch(IllegalAccessException ie) {
-                        //expected
-                    }
-                }
-            } catch (ClassNotFoundException e) {
-                fail("ClassNotFoundException was thrown." + e.getMessage());
-            } catch (InstantiationException e) {
-                fail("InstantiationException was thrown.");                
-            } catch (IllegalAccessException e) {
-                fail("IllegalAccessException was thrown.");                 
-            }            
-        }
-        
-        try {
-            Class<?> clazz = cl.loadClass("org.apache.harmony.luni.tests.java.lang.TestClass4");
-            fail("ClassNotFoundException was not thrown.");
-        } catch (ClassNotFoundException e) {
-            //expected
-        }   
-        
-        try {
-            Class<?> clazz = cl.loadClass("org.apache.harmony.luni.tests.java.lang.TestClass5");
-            fail("ClassNotFoundException was not thrown.");
-        } catch (ClassNotFoundException e) {
-            //expected
-        }                
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "loadClass",
-        args = {java.lang.String.class, boolean.class}
-    )
-    public void test_loadClassLjava_lang_StringLZ() throws
-            IllegalAccessException, InstantiationException,
-            ClassNotFoundException {
-        PackageClassLoader pcl = new PackageClassLoader(
-                getClass().getClassLoader());
-        String className = getClass().getPackage().getName() + ".A";
-
-        Class<?> clazz = pcl.loadClass(className, false);
-        assertEquals(className, clazz.getName());
-        assertNotNull(clazz.newInstance());
-        
-        clazz = pcl.loadClass(className, true);
-        assertEquals(className, clazz.getName());
-        assertNotNull(clazz.newInstance());
-            
-        try {
-            clazz = pcl.loadClass("UnknownClass", false);
-            assertEquals("TestClass", clazz.getName());
-            fail("ClassNotFoundException was not thrown.");
-        } catch (ClassNotFoundException e) {
-            //expected
-        }
-    }
-    
     /**
      * @tests java.lang.ClassLoader#getResource(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getResource",
-        args = {java.lang.String.class}
-    )
     public void test_getResourceLjava_lang_String() {
         // Test for method java.net.URL
         // java.lang.ClassLoader.getResource(java.lang.String)
-        java.net.URL u = getClass().getClassLoader().getResource("hyts_Foo.c");
+        java.net.URL u = ClassLoader.getSystemClassLoader().getResource("hyts_Foo.c");
         assertNotNull("Unable to find resource", u);
         java.io.InputStream is = null;
         try {
@@ -542,577 +176,61 @@
         } catch (java.io.IOException e) {
             fail("IOException getting stream for resource : " + e.getMessage());
         }
-        
-        
-        
-        assertNull(getClass().getClassLoader()
-                .getResource("not.found.resource"));
     }
 
     /**
      * @tests java.lang.ClassLoader#getResourceAsStream(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getResourceAsStream",
-        args = {java.lang.String.class}
-    )
     public void test_getResourceAsStreamLjava_lang_String() {
         // Test for method java.io.InputStream
         // java.lang.ClassLoader.getResourceAsStream(java.lang.String)
         // Need better test...
 
         java.io.InputStream is = null;
-        assertNotNull("Failed to find resource: HelloWorld.txt",
-                (is = getClass().getClassLoader()
-                        .getResourceAsStream("HelloWorld.txt")));
-
-        byte [] array = new byte[13];
-        try {
-            is.read(array);
-        } catch(IOException ioe) {
-            fail("IOException was not thrown.");
-        } finally {
-            try {
-                is.close();
-            } catch(IOException ioe) {}
-        }       
-        
-        assertEquals("Hello, World.", new String(array));
-                
-        
+        assertNotNull("Failed to find resource: hyts_Foo.c", (is = ClassLoader
+                .getSystemClassLoader().getResourceAsStream("hyts_Foo.c")));
         try {
             is.close();
         } catch (java.io.IOException e) {
             fail("Exception during getResourceAsStream: " + e.toString());
         }
-        
-        assertNull(getClass().getClassLoader().
-                getResourceAsStream("unknownResource.txt"));
     }
 
     /**
      * @tests java.lang.ClassLoader#getSystemClassLoader()
      */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "",
-        method = "getSystemClassLoader",
-        args = {}
-    )
     public void test_getSystemClassLoader() {
         // Test for method java.lang.ClassLoader
         // java.lang.ClassLoader.getSystemClassLoader()
         ClassLoader cl = ClassLoader.getSystemClassLoader();
-
-        java.io.InputStream is = cl.getResourceAsStream(SYSTEM_RESOURCE_PATH);
+        java.io.InputStream is = cl.getResourceAsStream("hyts_Foo.c");
         assertNotNull("Failed to find resource from system classpath", is);
         try {
             is.close();
         } catch (java.io.IOException e) {
         }
 
-        SecurityManager sm = new SecurityManager() {
-            public void checkPermission(Permission perm) {
-                if(perm.getName().equals("getClassLoader")) {
-                   throw new SecurityException(); 
-                }
-            }
-        };    
-        
-        SecurityManager oldManager = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            ClassLoader.getSystemClassLoader();
-        } catch(SecurityException se) {
-            //expected
-        } finally {
-            System.setSecurityManager(oldManager);
-        }
-/* 
- *       // java.lang.Error is not thrown on RI, but it's specified.  
- *       
- *       String keyProp = "java.system.class.loader";
- *       String oldProp = System.getProperty(keyProp);
- *       System.setProperty(keyProp, "java.test.UnknownClassLoader");
- *       boolean isFailed = false;
- *       try {
- *           ClassLoader.getSystemClassLoader();
- *           isFailed = true;
- *       } catch(java.lang.Error e) {
- *           //expected
- *       } finally {
- *           if(oldProp == null) {
- *               System.clearProperty(keyProp);
- *           }  else {
- *               System.setProperty(keyProp, oldProp);
- *           }
- *       }
- *       assertFalse("java.lang.Error was not thrown.", isFailed);
- */       
     }
 
     /**
      * @tests java.lang.ClassLoader#getSystemResource(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getSystemResource",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("The RI doesn't have a classes.dex as resource in the "
-            + "core-tests.jar. Also on Android this file is the only one "
-            + "that is sure to exist.")
-    public void test_getSystemResourceLjava_lang_String() throws IOException {
+    public void test_getSystemResourceLjava_lang_String() {
+        // Test for method java.net.URL
         // java.lang.ClassLoader.getSystemResource(java.lang.String)
         // Need better test...
-
-        
-        //String classResource = getClass().getPackage().getName().replace(".", "/") + "/" +
-        //                        getClass().getSimpleName()  + ".class";
-        //assertNotNull("Failed to find resource: " + classResource, 
-        //        ClassLoader.getSystemResource(classResource));   
-        
-        URL url = getClass().getClassLoader().getSystemResource(SYSTEM_RESOURCE_PATH);
-        assertNotNull(String.format("Failed to find resource: %s", SYSTEM_RESOURCE_PATH), url);
-        java.io.InputStream is = url.openStream();
-
-        assertTrue("System resource not found", is.available() > 0);
-        assertNull("Doesn't return null for unknown resource.", 
-                getClass().getClassLoader().getSystemResource("NotFound"));   
-    }
-        
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getSystemResourceAsStream",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("The RI doesn't have a classes.dex as resource in the "
-            + "core-tests.jar. Also on Android this file is the only one "
-            + "that is sure to exist.")
-    public void test_getSystemResourceAsStreamLjava_lang_String()
-            throws IOException {
-
-        //String classResource = getClass().getPackage().getName().replace(".", "/") + "/" +
-        //                    getClass().getSimpleName()  + ".class";
-        //assertNotNull("Failed to find resource: " + classResource, 
-        //            ClassLoader.getSystemResourceAsStream(classResource));   
-
-        java.io.InputStream is = getClass().getClassLoader()
-                .getSystemResourceAsStream(SYSTEM_RESOURCE_PATH);
-        assertNotNull(String.format("Failed to find resource: %s", SYSTEM_RESOURCE_PATH), is);
-        
-        assertTrue("System resource not found", is.available() > 0);
-        
-        assertNull(ClassLoader.getSystemResourceAsStream("NotFoundResource"));
+        assertNotNull("Failed to find resource: hyts_Foo.c", ClassLoader
+                .getSystemResource("hyts_Foo.c"));
     }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getSystemResources",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("The RI doesn't have a classes.dex as resource in the "
-            + "core-tests.jar. Also on Android this file is the only one "
-            + "that is sure to exist.")
-    public void test_getSystemResources() {
-        
-        String textResource = SYSTEM_RESOURCE_PATH;
-        
-        try {
-            Enumeration<URL> urls = ClassLoader.getSystemResources(textResource);
-            assertNotNull(urls);
-            assertTrue(urls.nextElement().getPath().endsWith(textResource));
-            while (urls.hasMoreElements()) {
-                assertNotNull(urls.nextElement());
-            }
-            try {
-                urls.nextElement();
-                fail("NoSuchElementException was not thrown.");
-            } catch(NoSuchElementException nse) {
-                //expected
-            }
-        } catch(IOException ioe) {
-            fail("IOException was thrown.");
-        }
-    }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPackage",
-        args = {java.lang.String.class}
-    )
-    @KnownFailure("PackageClassLoader.getPackage returns null.")
-    public void test_getPackageLjava_lang_String() {
-        PackageClassLoader pcl = new PackageClassLoader(
-                getClass().getClassLoader());
-        
-        String [] packageProperties = { "test.package", "title", "1.0", 
-                "Vendor", "Title", "1.1", "implementation vendor"};
-        
-        URL url = null;
-        try {
-            url = new URL("file:");
-        } catch (MalformedURLException e) {
-            fail("MalformedURLException was thrown.");
-        }
-        pcl.definePackage(packageProperties[0], 
-                          packageProperties[1], 
-                          packageProperties[2], 
-                          packageProperties[3], 
-                          packageProperties[4],
-                          packageProperties[5],
-                          packageProperties[6],
-                          url);
-        
-       assertNotNull(pcl.getPackage(packageProperties[0])); 
-       
-       assertEquals("should define current package", getClass().getPackage(), 
-               pcl.getPackage(getClass().getPackage().getName()));
-       
-       assertNull(pcl.getPackage("not.found.package"));
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPackages",
-        args = {}
-    )
-    @KnownFailure("The package canot be found. Seems like the cache is not " +
-            "shared between the class loaders. But this test seems to " +
-            "expect exactly that. this tests works on the RI.")
-    public void test_getPackages() {
-        
-        PackageClassLoader pcl = new PackageClassLoader(
-                getClass().getClassLoader());
-        
-        String [] packageProperties = { "test.package", "title", "1.0", 
-                "Vendor", "Title", "1.1", "implementation vendor"};
-        
-        URL url = null;
-        try {
-            url = new URL("file:");
-        } catch (MalformedURLException e) {
-            fail("MalformedURLException was thrown.");
-        }
-        pcl.definePackage(packageProperties[0], 
-                          packageProperties[1], 
-                          packageProperties[2], 
-                          packageProperties[3], 
-                          packageProperties[4],
-                          packageProperties[5],
-                          packageProperties[6],
-                          url);
-        
-        Package [] packages = pcl.getPackages();
-        assertTrue(packages.length != 0);
-        
-        pcl = new PackageClassLoader(getClass().getClassLoader());
-        packages = pcl.getPackages();
-        assertNotNull(packages);
-        
-        boolean isThisFound = false;
-        for(Package p:packages) {
-            if(p.equals(getClass().getPackage())) {
-                isThisFound = true;
-            }
-        }
-        assertTrue(isThisFound);
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getParent",
-        args = {}
-    )
-    public void test_getParent() {
-        PublicClassLoader pcl = new PublicClassLoader();
-        assertNotNull(pcl.getParent());
-        ClassLoader cl = getClass().getClassLoader().getParent();
-        assertNotNull(cl); 
-        
-        SecurityManager sm = new SecurityManager() {
-            
-            final String perName = "getClassLoader";
-
-            public void checkPermission(Permission perm) {
-                if (perm.getName().equals(perName)) {
-                    throw new SecurityException();
-                }
-            }
-        };
-        
-        SecurityManager oldSm = System.getSecurityManager();
-        System.setSecurityManager(sm);
-        try {
-            getClass().getClassLoader().getParent();
-            fail("Should throw SecurityException");
-        } catch (SecurityException e) {
-            // expected
-        } finally {
-            System.setSecurityManager(oldSm);
-        }
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getResources",
-        args = {java.lang.String.class}
-    )
-    public void test_getResourcesLjava_lang_String() {
-        Enumeration<java.net.URL> urls = null;
-        FileInputStream fis = null;
-        try {
-            urls = getClass().getClassLoader().getResources("HelloWorld.txt");
-            URL url = urls.nextElement();
-            fis = new FileInputStream(url.getFile());
-            byte [] array = new byte[13];
-            fis.read(array);
-            assertEquals("Hello, World.", new String(array));
-        } catch (IOException e) {
-
-        } finally {
-            try {
-                fis.close();
-            } catch(Exception e) {}
-        }
-        
-        assertNull(getClass().getClassLoader()
-                .getResource("not.found.resource")); 
-
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "definePackage",
-        args = {java.lang.String.class, java.lang.String.class, 
-                java.lang.String.class, java.lang.String.class, 
-                java.lang.String.class, java.lang.String.class, 
-                java.lang.String.class, java.net.URL.class }
-    )
-    public void test_definePackage() {
-        
-        PackageClassLoader pcl = new PackageClassLoader(
-                getClass().getClassLoader());
-        
-        String [] packageProperties = { "test.package", "title", "1.0", 
-                "Vendor", "Title", "1.1", "implementation vendor"};
-        
-        URL url = null;
-        try {
-            url = new URL("file:");
-        } catch (MalformedURLException e) {
-            fail("MalformedURLException was thrown.");
-        }
-        pcl.definePackage(packageProperties[0], 
-                          packageProperties[1], 
-                          packageProperties[2], 
-                          packageProperties[3], 
-                          packageProperties[4],
-                          packageProperties[5],
-                          packageProperties[6],
-                          url);
-        
-       Package pack = pcl.getPackage(packageProperties[0]);
-       assertEquals(packageProperties[1], pack.getSpecificationTitle()); 
-       assertEquals(packageProperties[2], pack.getSpecificationVersion()); 
-       assertEquals(packageProperties[3], pack.getSpecificationVendor()); 
-       assertEquals(packageProperties[4], pack.getImplementationTitle());
-       assertEquals(packageProperties[5], pack.getImplementationVersion());  
-       assertEquals(packageProperties[6], pack.getImplementationVendor()); 
-       assertTrue(pack.isSealed(url));
-       assertTrue(pack.isSealed());
-        
-       try {
-           pcl.definePackage(packageProperties[0], 
-                   packageProperties[1], 
-                   packageProperties[2], 
-                   packageProperties[3], 
-                   packageProperties[4],
-                   packageProperties[5],
-                   packageProperties[6],
-                   null);           
-           fail("IllegalArgumentException was not thrown.");
-       } catch(IllegalArgumentException  iae) {
-           //expected
-       }
-       
-       pcl.definePackage("test.package.test", null, null, null, null, 
-               null, null, null);
-       pack = pcl.getPackage("test.package.test");
-       assertNull(pack.getSpecificationTitle()); 
-       assertNull(pack.getSpecificationVersion()); 
-       assertNull(pack.getSpecificationVendor()); 
-       assertNull(pack.getImplementationTitle());
-       assertNull(pack.getImplementationVersion());  
-       assertNull(pack.getImplementationVendor());  
-       assertFalse(pack.isSealed());
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "findClass",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("findClass method throws ClassNotFoundException exception.")
-    public void test_findClass(){
-        
-        try {
-            PackageClassLoader pcl = new PackageClassLoader(
-                    getClass().getClassLoader());
-            pcl.findClass(getClass().getPackage().getName() + ".A");
-            fail("ClassNotFoundException was not thrown.");
-        } catch(ClassNotFoundException cnfe) {
-            //expected
-        } 
-        
-       try {
-           PackageClassLoader pcl = new PackageClassLoader(
-                   getClass().getClassLoader());
-           pcl.findClass("TestClass");
-           fail("ClassNotFoundException was not thrown.");
-       } catch(ClassNotFoundException cnfe) {
-           //expected
-       }
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "findLibrary",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("findLibrary method is not supported, it returns null.")
-    public void test_findLibrary() {
-        PackageClassLoader pcl = new PackageClassLoader(
-                getClass().getClassLoader());
-        assertNull(pcl.findLibrary("libjvm.so"));
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "findResource",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("findResource method is not supported, it returns null.")    
-    public void test_findResourceLjava_lang_String() {
-        assertNull(new PackageClassLoader(
-                getClass().getClassLoader()).findResource("hyts_Foo.c"));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "findResources",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("findResources method is not supported, it returns " +
-            "empty Enumeration.")      
-    public void test_findResourcesLjava_lang_String() throws IOException {
-        assertFalse(new PackageClassLoader(
-                getClass().getClassLoader()).findResources("hyts_Foo.c").
-                hasMoreElements());
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "findSystemClass",
-        args = {java.lang.String.class}
-    )    
-    public void test_findSystemClass() {
-        PackageClassLoader pcl = new PackageClassLoader(
-                getClass().getClassLoader());
-        
-        Class [] classes = { String.class, Integer.class, Object.class,
-                Object[].class };
-        
-        for(Class clazz:classes) {
-            try {
-                String className = clazz.getName();
-                assertEquals(clazz, pcl.findSystemClazz(className));
-            } catch(ClassNotFoundException cnfe) {
-                fail("ClassNotFoundException was thrown: " + cnfe.getMessage());
-            }
-        }
-        try {
-            pcl.findSystemClazz("unknownClass");
-            fail("ClassNotFoundException was not thrown.");
-        } catch(ClassNotFoundException cnfe) {
-            //expected
-        }
-    }
-  
-   @TestTargetNew(
-       level = TestLevel.COMPLETE,
-       notes = "",
-       method = "findLoadedClass",
-       args = {java.lang.String.class }
-    )
-    public void test_findLoadedClass() {
-       PackageClassLoader pcl = new PackageClassLoader(
-               getClass().getClassLoader());
-       
-       Class [] classes = { A.class, PublicTestClass.class,
-               TestAnnotation.class, TestClass1.class };
-       
-       for(Class clazz:classes) {
-           String className = clazz.getName();
-           assertNull(pcl.findLoadedClazz(className));
-       }
-
-       assertNull(pcl.findLoadedClazz("unknownClass"));
-    }
-    
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.NOT_NECESSARY,
-            notes = "setClassAssertionStatus is not supported.",
-            method = "setClassAssertionStatus",
-            args = {java.lang.String.class, boolean.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.NOT_NECESSARY,
-            notes = "setDefaultAssertionStatus is not supported.",
-            method = "setDefaultAssertionStatus",
-            args = {boolean.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.NOT_NECESSARY,
-            notes = "setPackageAssertionStatus is not supported.",
-            method = "setPackageAssertionStatus",
-            args = {java.lang.String.class, boolean.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.NOT_NECESSARY,
-            notes = "resolveClass is not supported.",
-            method = "resolveClass",
-            args = {java.lang.Class.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.NOT_NECESSARY,
-            notes = "setSigners is not supported.",
-            method = "setSigners",
-            args = {java.lang.Class.class, java.lang.Object[].class}
-        )
-    })
-    public void test_notSupported() {
-        getClass().getClassLoader().setClassAssertionStatus(getName(), true);
-        getClass().getClassLoader().setDefaultAssertionStatus(true);
-        getClass().getClassLoader().setPackageAssertionStatus(
-                getClass().getPackage().getName(), true);
-    }
+    //Regression Test for JIRA-2047
+    public void test_getResourceAsStream_withSharpChar() throws Exception {
+		InputStream in = this.getClass().getClassLoader().getResourceAsStream(
+				ClassTest.FILENAME);
+		assertNotNull(in);
+		in.close();
+	}
 }
 
 class DynamicPolicy extends Policy {
@@ -1138,127 +256,14 @@
 }
 
 class Ldr extends ClassLoader {
-
-    /*
-     * These bytes are the content of the file
-     * /org/apache/harmony/luni/tests/java/lang/A.class
-     */
-    byte[] classBytes = new byte[] { -54, -2, -70, -66, 0, 0, 0, 49, 0, 16, 7,
-            0, 2, 1, 0, 41, 111, 114, 103, 47, 97, 112, 97, 99, 104, 101, 47,
-            104, 97, 114, 109, 111, 110, 121, 47, 108, 117, 110, 105, 47, 116,
-            101, 115, 116, 115, 47, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
-            65, 7, 0, 4, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
-            79, 98, 106, 101, 99, 116, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1,
-            0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 10, 0, 3, 0, 9, 12, 0,
-            5, 0, 6, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114,
-            84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114,
-            105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105,
-            115, 1, 0, 43, 76, 111, 114, 103, 47, 97, 112, 97, 99, 104, 101, 47,
-            104, 97, 114, 109, 111, 110, 121, 47, 108, 117, 110, 105, 47, 116,
-            101, 115, 116, 115, 47, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
-            65, 59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1,
-            0, 20, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 84, 101,
-            115, 116, 46, 106, 97, 118, 97, 0, 32, 0, 1, 0, 3, 0, 0, 0, 0, 0, 1,
-            0, 0, 0, 5, 0, 6, 0, 1, 0, 7, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5,
-            42, -73, 0, 8, -79, 0, 0, 0, 2, 0, 10, 0, 0, 0, 6, 0, 1, 0, 0, 4,
-            -128, 0, 11, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 12, 0, 13, 0, 0, 0,
-            1, 0, 14, 0, 0, 0, 2, 0, 15 };
-    
-    public static final int TEST_CASE_DEFINE_0 = 0;
-    public static final int TEST_CASE_DEFINE_1 = 1;
-    public static final int TEST_CASE_DEFINE_2 = 2;
-    public static final int TEST_CASE_DEFINE_3 = 3;
-    
     @SuppressWarnings("deprecation")
-    public Class<?> define(int len, int testCase) throws Exception {
-        
-        if(len < 0) len = classBytes.length;
-        Class<?> clazz = null;
-        String className = "org.apache.harmony.luni.tests.java.lang.A";
-        switch(testCase) {
-            case TEST_CASE_DEFINE_0:
-                clazz = defineClass(className, classBytes, 0, len);
-                break;
-            case TEST_CASE_DEFINE_1:
-                clazz = defineClass(classBytes, 0, len);                
-                break;
-            case TEST_CASE_DEFINE_2:
-                clazz = defineClass(className, classBytes, 0, len, 
-                        getClass().getProtectionDomain());
-                break;
-            case TEST_CASE_DEFINE_3:
-                ByteBuffer bb = ByteBuffer.wrap(classBytes);
-                clazz = defineClass(className, 
-                        bb, getClass().getProtectionDomain());                
-                break;
-        }
-        return clazz;
+    public Class<?> define() throws Exception {
+        Package p = getClass().getPackage();
+        // Class loader paths use '/' character as separator
+        String path = p == null ? "" : p.getName().replace('.', '/') + '/';
+        InputStream is = getResourceAsStream(path + "A.class");
+        byte[] buf = new byte[512];
+        int len = is.read(buf);
+        return defineClass(buf, 0, len);
     }
-   
-    public Class<?> define(int testCase) throws Exception {
-        return  define(-1, testCase);
-    }   
-
 }
-
-class PackageClassLoader extends ClassLoader { 
-    public PackageClassLoader() {
-        super();
-    }
-
-    public PackageClassLoader(ClassLoader parent) {
-        super(parent);
-    }
-
-    public Package definePackage(String name,
-            String specTitle,
-            String specVersion,
-            String specVendor,
-            String implTitle,
-            String implVersion,
-            String implVendor,
-            URL sealBase)
-     throws IllegalArgumentException {
-        return super.definePackage(name, specTitle, specVersion, 
-                specVendor, implTitle, implVersion, implVendor, sealBase);
-    }
-    
-    public Package getPackage(String name) {
-        return super.getPackage(name);
-    }
-    
-    public Package[] getPackages() {
-        return super.getPackages();
-    }
-    
-    public Class<?> findClass(String name)
-        throws ClassNotFoundException {
-       return super.findClass(name); 
-    }
-    
-    public String findLibrary(String libname) {
-        return super.findLibrary(libname);
-    }
-    
-    public Class<?> loadClass(String name, boolean resolve) 
-                                            throws ClassNotFoundException {
-        return super.loadClass(name, resolve);
-    }
-    
-    public URL findResource(String name) {
-        return super.findResource(name);
-    }
-    
-    public Enumeration<URL> findResources(String resName) 
-                                            throws IOException {
-        return super.findResources(resName);
-    }
-    
-    public Class<?> findSystemClazz(String name) throws ClassNotFoundException {
-        return super.findSystemClass(name);
-    }
-
-    public Class<?> findLoadedClazz(String name) {
-        return super.findLoadedClass(name);
-    }
-} 
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassNotFoundExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassNotFoundExceptionTest.java
index b8051cc..3a26a79 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassNotFoundExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassNotFoundExceptionTest.java
@@ -17,114 +17,44 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.io.IOException;
 
 import junit.framework.TestCase;
 
-@TestTargetClass(ClassNotFoundException.class) 
 public class ClassNotFoundExceptionTest extends TestCase {
-
     /**
-     * @tests java.lang.ClassNotFoundException#ClassNotFoundException()
+     * Thrown when an application tries to load in a class through its string
+     * name using the forName method in class Class.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassNotFoundException",
-        args = {}
-    )
-    public void test_Constructor() {
+
+	/**
+	 * @tests java.lang.ClassNotFoundException#ClassNotFoundException()
+	 */
+	public void test_Constructor() {
         ClassNotFoundException e = new ClassNotFoundException();
         assertNull(e.getMessage());
         assertNull(e.getLocalizedMessage());
         assertNull(e.getCause());
-    }
+	}
 
-    /**
-     * @tests java.lang.ClassNotFoundException#ClassNotFoundException(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassNotFoundException",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
+	/**
+	 * @tests java.lang.ClassNotFoundException#ClassNotFoundException(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
         ClassNotFoundException e = new ClassNotFoundException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
+	}
+	
+    /**
+     * @tests java.lang.ClassNotFoundException#ClassNotFoundException(java.lang.String, java.lang.Throwable)
+     */
+    public void test_ClassNotFoundException_LString_LThrowable() {
+        IOException in = new IOException();
+        ClassNotFoundException e = new ClassNotFoundException("SomeMessage", in);
+        assertEquals("Wrong Exception", in, e.getException());
+        assertEquals("Wrong message", "SomeMessage", e.getMessage());
+        assertEquals("Wrong cause", in, e.getCause());
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ClassNotFoundException",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
-    public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
-        String testMessage = "Test Message";
-        Throwable thr = new Throwable();
-        ClassNotFoundException cnfe = new ClassNotFoundException(testMessage, thr);
-        assertEquals(testMessage, cnfe.getMessage());
-        assertEquals(thr, cnfe.getException());
-        
-        cnfe = new ClassNotFoundException(null, thr);
-        assertNull(cnfe.getMessage());
-        assertEquals(thr, cnfe.getException());
-        
-        cnfe = new ClassNotFoundException(testMessage, null);
-        assertNull(cnfe.getException());
-        assertEquals(testMessage, cnfe.getMessage());
-        
-        cnfe = new ClassNotFoundException(null, null);
-        assertNull(cnfe.getMessage());
-        assertNull(cnfe.getException());
-    } 
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCause",
-        args = {}
-    )
-    public void test_getCause() {
-        ClassNotFoundException e = new ClassNotFoundException();
-        assertNull(e.getCause());
-        
-        e = new ClassNotFoundException("Message");
-        assertNull(e.getCause());
-        
-        NullPointerException cause = new NullPointerException();
-        Throwable thr = new Throwable(cause);
-        e = new ClassNotFoundException("Message", thr);
-        assertEquals(thr, e.getCause());
-        
-        e = new ClassNotFoundException("Message", null);
-        assertEquals(null, e.getCause());       
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getException",
-        args = {}
-    )
-    public void test_getException() {
-        ClassNotFoundException e = new ClassNotFoundException();
-        assertNull(e.getException());
-              
-        e = new ClassNotFoundException("Message");
-        assertNull(e.getException());
-              
-        NullPointerException cause = new NullPointerException();
-        Throwable thr = new Throwable(cause);
-        e = new ClassNotFoundException("Message", thr);
-        assertEquals(thr, e.getException());
-              
-        e = new ClassNotFoundException("Message", null);
-        assertEquals(null, e.getException());       
-    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CloneNotSupportedExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CloneNotSupportedExceptionTest.java
index 58e86fa..da66da9 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CloneNotSupportedExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CloneNotSupportedExceptionTest.java
@@ -17,44 +17,26 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(CloneNotSupportedException.class) 
 public class CloneNotSupportedExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.CloneNotSupportedException#CloneNotSupportedException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "CloneNotSupportedException",
-        args = {}
-    )
-    public void test_Constructor() {
+	/**
+	 * @tests java.lang.CloneNotSupportedException#CloneNotSupportedException()
+	 */
+	public void test_Constructor() {
         CloneNotSupportedException e = new CloneNotSupportedException();
         assertNull(e.getMessage());
         assertNull(e.getLocalizedMessage());
         assertNull(e.getCause());
-    }
+	}
 
-    /**
-     * @tests java.lang.CloneNotSupportedException#CloneNotSupportedException(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "CloneNotSupportedException",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
+	/**
+	 * @tests java.lang.CloneNotSupportedException#CloneNotSupportedException(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
         CloneNotSupportedException e = new CloneNotSupportedException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
-    }
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CompilerTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CompilerTest.java
index 5c01a36..4793a42 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CompilerTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/CompilerTest.java
@@ -17,117 +17,49 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Compiler.class) 
 public class CompilerTest extends TestCase {
 
     /**
      * @tests java.lang.Compiler#command(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "command",
-        args = {java.lang.Object.class}
-    )
     public void test_commandLjava_lang_Object() {
-       
-        if(System.getProperty("java.compiler") != null) {
-            try {
-                assertNull("Incorrect behavior.", Compiler.command(new Object()));
-            } catch (Exception e) {
-                fail("Exception during test : " + e.getMessage());
-            }
-            // NullPointerException is not specified.
-            Compiler.command(null);
-        } else {
-            Compiler.command("");
-        }
+        assertNull("Incorrect behavior.", Compiler.command(new Object()));
     }
 
     /**
      * @tests java.lang.Compiler#compileClass(java.lang.Class)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compileClass",
-        args = {java.lang.Class.class}
-    )
     public void test_compileClassLjava_lang_Class() {
-        try {
-            // Do not test return value, may return true or false depending on
-            // if the jit is enabled. Make the call to ensure it doesn't crash.
-            Compiler.compileClass(Compiler.class);
-        } catch (Exception e) {
-            fail("Exception during test.");
-        }
-        
-        // NullPointerException is not specified.
-        Compiler.compileClass((Class) null);
+        // Do not test return value, may return true or false depending on
+        // if the jit is enabled. Make the call to ensure it doesn't crash.
+        Compiler.compileClass(Compiler.class);
     }
 
     /**
      * @tests java.lang.Compiler#compileClasses(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compileClasses",
-        args = {java.lang.String.class}
-    )
     public void test_compileClassesLjava_lang_String() {
-        try {
-            // Do not test return value, may return true or false depending on
-            // if the jit is enabled. Make the call to ensure it doesn't crash.
+        // Do not test return value, may return true or false depending on
+        // if the jit is enabled. Make the call to ensure it doesn't crash.
             Compiler.compileClasses("Compiler");
-        } catch (Exception e) {
-            fail("Exception during test.");
-        }
-        
-        // NullPointerException is not specified.
-        Compiler.compileClasses((String) null);
     }
 
     /**
      * @tests java.lang.Compiler#disable()
      */
-    @TestTargetNew(
-        level = TestLevel.NOT_NECESSARY,
-        notes = "Doesn't verify that disable() method causes the Compiler to cease operation.",
-        method = "disable",
-        args = {}
-    )
     public void test_disable() {
-        try {
-            Compiler.disable();
-            Compiler.compileClass(Compiler.class);
-        } catch (Exception e) {
-            fail("Exception during test : " + e.getMessage());
-        }
+        Compiler.disable();
+        Compiler.compileClass(Compiler.class);
     }
 
     /**
      * @tests java.lang.Compiler#enable()
      */
-    @TestTargetNew(
-        level = TestLevel.NOT_NECESSARY,
-        notes = "Doesn't verify that enable() method causes the Compiler to resume operation.",
-        method = "enable",
-        args = {}
-    )
     public void test_enable() {
-        try {
-            Compiler.disable();
-            Compiler.enable();
-            Compiler.compileClass(Compiler.class);
-        } catch (Exception e) {
-            fail("Exception during test : " + e.getMessage());
-        }
+        Compiler.disable();
+        Compiler.enable();
+        Compiler.compileClass(Compiler.class);
     }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java
index 3b2d405..44039df 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/DoubleTest.java
@@ -541,8 +541,6 @@
         method = "parseDouble",
         args = {java.lang.String.class}
     )
-    @KnownFailure("parseDouble returns different value on Android " +
-            "for 0x44b52d02c7e14af6L, it returns 1.0e23.")
     public void test_parseDoubleLjava_lang_String() {
         assertEquals("Incorrect double returned, expected zero.", 0.0, Double
                 .parseDouble("2.4703282292062327208828439643411e-324"), 0.0);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumConstantNotPresentExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumConstantNotPresentExceptionTest.java
index d91584b..2fea1b1 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumConstantNotPresentExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumConstantNotPresentExceptionTest.java
@@ -16,14 +16,8 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(EnumConstantNotPresentException.class) 
 public class EnumConstantNotPresentExceptionTest extends TestCase {
 
     public enum Fixture {
@@ -34,20 +28,7 @@
      * @test java.lang.EnumConstantNotPresentException#EnumConstantNotPresentException(Class<?
      * extends Enum>, String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "EnumConstantNotPresentException",
-        args = {java.lang.Class.class, java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_ClassLjava_lang_String() {
-        String tm = "Test Message";
-        EnumConstantNotPresentException ecnpe = new 
-                    EnumConstantNotPresentException(Fixture.class, tm);
-
-        assertEquals("Constant name is incorrect: " + ecnpe.constantName() + 
-                " instead of " + tm, tm, ecnpe.constantName());
-        
         try {
             new EnumConstantNotPresentException(null, "");
             fail("No NPE");
@@ -58,12 +39,6 @@
     /**
      * @test java.lang.EnumConstantNotPresentException#enumType()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "enumType",
-        args = {}
-    )
     public void test_enumType() {
         EnumConstantNotPresentException e = new EnumConstantNotPresentException(Fixture.class, "FOUR");
         assertEquals(Fixture.class, e.enumType());
@@ -72,12 +47,6 @@
     /**
      * @test java.lang.EnumConstantNotPresentException#constantName()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "constantName",
-        args = {}
-    )
     public void test_constantName() {
         EnumConstantNotPresentException e = new EnumConstantNotPresentException(Fixture.class, "FOUR");
         assertEquals("FOUR", e.constantName());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java
index 94b495f..afe1146 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/EnumTest.java
@@ -16,9 +16,7 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
+import java.util.HashMap;
 
 import junit.framework.TestCase;
 
@@ -26,9 +24,6 @@
 
 import tests.util.SerializationTester;
 
-import java.util.HashMap;
-
-@TestTargetClass(Enum.class) 
 public class EnumTest extends TestCase {
 
     enum Sample {
@@ -49,37 +44,18 @@
     enum Color {
         Red, Green, Blue {};
     }
-
     
-    @TestTargetNew(
-        level = TestLevel.NOT_FEASIBLE,
-        notes = "Can't be tested, according to the spec this constructor can't be invoked.",
-        method = "Enum",
-        args = {java.lang.String.class, int.class}
-    )
-    public void test_EnumLStringLlang() {
-        //TODO
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.NOT_FEASIBLE,
-        notes = "Can't be tested, according to the spec.",
-        method = "clone",
-        args = {}
-    )
-    public void test_clone() {
-      //TODO
+    enum MockCloneEnum {
+        ONE;
+        
+        public void callClone() throws CloneNotSupportedException{
+            super.clone();
+        }
     }
     
     /**
      * @tests java.lang.Enum#compareTo(java.lang.Enum) 
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.lang.Enum.class}
-    )
     public void test_compareToLjava_lang_Enum() {
         assertTrue(0 < Sample.MOE.compareTo(Sample.LARRY));
         assertEquals(0, Sample.MOE.compareTo(Sample.MOE));
@@ -95,12 +71,6 @@
     /**
      * @tests java.lang.Enum#equals(Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         assertFalse(moe.equals("bob"));
         assertTrue(moe.equals(Sample.MOE));
@@ -112,12 +82,6 @@
     /**
      * @tests java.lang.Enum#getDeclaringClass()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getDeclaringClass",
-        args = {}
-    )
     public void test_getDeclaringClass() {
         assertEquals(Sample.class, moe.getDeclaringClass());
     }
@@ -125,27 +89,13 @@
     /**
      * @tests java.lang.Enum#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         assertEquals (moe.hashCode(), moe.hashCode());
-        assertTrue (moe.hashCode() != Sample.LARRY.hashCode());
-        
     }
 
     /**
      * @tests java.lang.Enum#name()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "name",
-        args = {}
-    )
     public void test_name() {
         assertEquals("MOE", moe.name());
     }
@@ -153,12 +103,6 @@
     /**
      * @tests java.lang.Enum#ordinal()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ordinal",
-        args = {}
-    )
     public void test_ordinal() {
         assertEquals(0, larry.ordinal());
         assertEquals(1, moe.ordinal());
@@ -168,12 +112,6 @@
     /**
      * @tests java.lang.Enum#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         assertTrue(moe.toString().equals("MOE"));
     }
@@ -181,12 +119,6 @@
     /**
      * @tests java.lang.Enum#valueOf(Class, String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.Class.class, java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String() {
         assertSame(Sample.CURLY, Sample.valueOf("CURLY"));
         assertSame(Sample.LARRY, Sample.valueOf("LARRY"));
@@ -248,13 +180,6 @@
     /**
      * @tests java.lang.Enum#values
      */
-    @TestTargetNew(
-        level = TestLevel.TODO,
-        notes = "Tests the values() method which is not in the API since it is" +
-                "automatically created by the compiler for enum types",
-        method = "!values",
-        args = {}
-    )
     public void test_values() {
         Sample[] myValues = Sample.values();
         assertEquals(3, myValues.length);
@@ -265,31 +190,32 @@
         
         assertEquals(0, Empty.values().length);
     }
+
+    /**
+     * @tests java.lang.Enum#clone()
+     */
+    public void test_clone() {
+        try {
+            MockCloneEnum.ONE.callClone();
+            fail("Should throw CloneNotSupprotedException");
+        } catch (CloneNotSupportedException e1) {
+            // expected
+        }
+
+    }
     
     /**
      * @test Serialization/deserilazation compatibility with Harmony.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Serialization/deserilazation compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void test_compatibilitySerialization_inClass_Complex_Harmony() throws Exception{
         // TODO migrate to the new testing framework 
         assertTrue(SerializationTester.assertCompabilityEquals(new MockEnum2(),
-            "/serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser"));
+            "serialization/org/apache/harmony/luni/tests/java/lang/EnumTest.harmony.ser"));
     }
     
     /**
      * @tests serialization/deserialization compatibility.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         // test a map class that has enums.
@@ -315,18 +241,11 @@
         assertEquals(mock2.i, test2.i);
         assertEquals(mock2.str, test2.str);
         assertEquals(mock2.samEnum, test2.samEnum);
-        
     }
 
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         // regression test for Harmony-1163
@@ -342,5 +261,4 @@
 
         SerializationTest.verifyGolden(this, testCases);
     }
-    
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ErrorTest.java
index 03735c2..32db9b3 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Error.class) 
 public class ErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.Error#Error()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Error",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.Error#Error()
+	 */
     public void test_Constructor() {
         Error e = new Error();
         assertNull(e.getMessage());
@@ -46,41 +34,9 @@
     /**
      * @tests java.lang.Error#Error(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Error",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         Error e = new Error("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
     }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Error",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
-    public void test_ConstructorLjava_lang_StringLThrowable() {
-        Throwable thr = new Throwable();
-        String message = "Test message";
-        Error err = new Error(message, thr);
-        assertEquals(message, err.getMessage());
-        assertEquals(thr, err.getCause());
-    }   
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Error",
-        args = {java.lang.Throwable.class}
-    )
-    public void test_ConstructorLThrowable() {
-      Throwable thr = new Throwable();
-      Error err = new Error(thr);
-      assertEquals(thr, err.getCause());
-    }  
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionInInitializerErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionInInitializerErrorTest.java
index 6614090..83c6cd8 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionInInitializerErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionInInitializerErrorTest.java
@@ -17,31 +17,11 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-@TestTargetClass(ExceptionInInitializerError.class) 
 public class ExceptionInInitializerErrorTest extends junit.framework.TestCase {
 
-    /**
-     * @tests java.lang.ExceptionInInitializerError#ExceptionInInitializerError()
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "ExceptionInInitializerError",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getCause",
-            args = {}
-        )
-    })
+	/**
+	 * @tests java.lang.ExceptionInInitializerError#ExceptionInInitializerError()
+	 */
     public void test_Constructor() {
         ExceptionInInitializerError e = new ExceptionInInitializerError();
         assertNull(e.getMessage());
@@ -52,56 +32,22 @@
     /**
      * @tests java.lang.ExceptionInInitializerError#ExceptionInInitializerError(java.lang.String)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "ExceptionInInitializerError",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getCause",
-            args = {}
-        )
-    })
     public void test_ConstructorLjava_lang_String() {
         ExceptionInInitializerError e = new ExceptionInInitializerError("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
     }
 
-    /**
-     * @tests java.lang.ExceptionInInitializerExceptionInInitializerError#ExceptionInInitializerError(java.lang.Throwable)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "ExceptionInInitializerError",
-            args = {java.lang.Throwable.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getCause",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getException",
-            args = {}
-        )
-    })
-    public void test_ConstructorLjava_lang_Throwable() {
-        NullPointerException npe = new NullPointerException("fixture");
+	/**
+	 * @tests java.lang.ExceptionInInitializerExceptionInInitializerError#ExceptionInInitializerError(java.lang.Throwable)
+	 */
+	public void test_ConstructorLjava_lang_Throwable() {
+	    NullPointerException npe = new NullPointerException("fixture");
         ExceptionInInitializerError e = new ExceptionInInitializerError(npe);
         assertNull(e.getMessage());
         assertNull(e.getLocalizedMessage());
         assertSame(npe, e.getException());
         assertSame(npe, e.getCause());
-    }
+	}
 
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionTest.java
index 9057269..88cc2e4 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Exception.class) 
 public class ExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.Exception#Exception()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Exception",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.Exception#Exception()
+	 */
     public void test_Constructor() {
         Exception e = new Exception();
         assertNull(e.getMessage());
@@ -46,42 +34,9 @@
     /**
      * @tests java.lang.Exception#Exception(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Exception",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         Exception e = new Exception("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Exception",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
-    public void test_ConstructorLjava_lang_StringLThrowable() {
-      Throwable thr = new Throwable();
-      String message = "Test message";
-      Exception err = new Exception(message, thr);
-      assertEquals(message, err.getMessage());
-      assertEquals(thr, err.getCause());
-    }   
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Exception",
-        args = {java.lang.Throwable.class}
-    )
-    public void test_ConstructorLThrowable() {
-      Throwable thr = new Throwable();
-      Exception err = new Exception(thr);
-      assertEquals(thr, err.getCause());
-    } 
-
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessErrorTest.java
index caec351..5b032e1 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(IllegalAccessError.class) 
 public class IllegalAccessErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.IllegalAccessError#IllegalAccessError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalAccessError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.IllegalAccessError#IllegalAccessError()
+	 */
     public void test_Constructor() {
         IllegalAccessError e = new IllegalAccessError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.IllegalAccessError#IllegalAccessError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalAccessError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IllegalAccessError e = new IllegalAccessError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessExceptionTest.java
index a14ae66..2a984cb 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalAccessExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(IllegalAccessException.class) 
 public class IllegalAccessExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.IllegalAccessException#IllegalAccessException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalAccessException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.IllegalAccessException#IllegalAccessException()
+	 */
     public void test_Constructor() {
         IllegalAccessException e = new IllegalAccessException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.IllegalAccessException#IllegalAccessException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalAccessException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IllegalAccessException e = new IllegalAccessException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalArgumentExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalArgumentExceptionTest.java
index 3acc8e4..9acf54c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalArgumentExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalArgumentExceptionTest.java
@@ -17,57 +17,51 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(IllegalArgumentException.class) 
 public class IllegalArgumentExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.IllegalArgumentException#IllegalArgumentException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalArgumentException",
-        args = {}
-    )
-    public void test_Constructor() {
-        IllegalArgumentException e = new IllegalArgumentException();
+	/**
+	 * @tests java.lang.IllegalArgumentException#IllegalArgumentException()
+	 */
+	public void test_Constructor() {
+		IllegalArgumentException e = new IllegalArgumentException();
         assertNull(e.getMessage());
         assertNull(e.getLocalizedMessage());
         assertNull(e.getCause());
-    }
+	}
 
-    /**
-     * @tests java.lang.IllegalArgumentException#IllegalArgumentException(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalArgumentException",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
+	/**
+	 * @tests java.lang.IllegalArgumentException#IllegalArgumentException(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
         IllegalArgumentException e = new IllegalArgumentException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
+	}
+    
+    /**
+     * @tests {@link java.lang.IllegalArgumentException#IllegalArgumentException(Throwable)}
+     */
+    public void test_ConstructorLjava_lang_Throwable() {
+        Throwable emptyThrowable = new Exception();
+        IllegalArgumentException emptyException = new IllegalArgumentException(emptyThrowable);
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+        Throwable exception = new Exception("msg");
+        IllegalArgumentException e = new IllegalArgumentException(exception);
+        assertEquals(exception.getClass().getName() + ": " + "msg", e.getMessage());
+        assertEquals(exception.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(exception.getClass().getName(), emptyException.getCause().toString());
     }
     
     /**
      * @tests java.lang.IllegalArgumentException#IllegalArgumentException(String,Throwable)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalArgumentException",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
     @SuppressWarnings("nls")
     public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
         NullPointerException npe = new NullPointerException();
@@ -77,27 +71,9 @@
         assertSame(npe, e.getCause());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalArgumentException",
-        args = {java.lang.Throwable.class}
-    )
-    public void test_ConstructorLjava_lang_Throwable() {
-              NullPointerException npe = new NullPointerException();
-              IllegalArgumentException e = new IllegalArgumentException(npe);
-              assertSame(npe, e.getCause());
-    }    
-    
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
         SerializationTest.verifySelf(new IllegalArgumentException());
     }
@@ -105,12 +81,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
         SerializationTest.verifyGolden(this, new IllegalArgumentException());
     }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalMonitorStateExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalMonitorStateExceptionTest.java
index adc155f..37ce9c3 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalMonitorStateExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalMonitorStateExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(IllegalMonitorStateException.class) 
 public class IllegalMonitorStateExceptionTest extends TestCase {
 
     /**
      * @tests java.lang.IllegalMonitorStateException#IllegalMonitorStateException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalMonitorStateException",
-        args = {}
-    )
     public void test_Constructor() {
         IllegalMonitorStateException e = new IllegalMonitorStateException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.IllegalMonitorStateException#IllegalMonitorStateException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalMonitorStateException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IllegalMonitorStateException e = new IllegalMonitorStateException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalStateExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalStateExceptionTest.java
index 03acac6..2d55d6c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalStateExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalStateExceptionTest.java
@@ -17,26 +17,15 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(IllegalStateException.class) 
 public class IllegalStateExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.IllegalStateException#IllegalStateException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalStateException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.IllegalStateException#IllegalStateException()
+	 */
     public void test_Constructor() {
         IllegalStateException e = new IllegalStateException();
         assertNull(e.getMessage());
@@ -47,60 +36,50 @@
     /**
      * @tests java.lang.IllegalStateException#IllegalStateException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalStateException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IllegalStateException e = new IllegalStateException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
     }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalStateException",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
-    public void test_ConstructorLjava_lang_StringLThrowable() {
-        String message = "Test message";
-        NullPointerException npe = new NullPointerException();
-        IllegalStateException e = new IllegalStateException(message, npe);
-        assertEquals(message, e.getMessage());
-        assertEquals(npe, e.getCause());
-        
-        e = new IllegalStateException(message, null);
-        assertEquals(message, e.getMessage());
-        assertNull(e.getCause());
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalStateException",
-        args = {java.lang.Throwable.class}
-    )
-    public void test_ConstructorLThrowable() {
-      NullPointerException npe = new NullPointerException();
-      IllegalStateException e = new IllegalStateException(npe);
-      assertEquals(npe, e.getCause());
-      
-      e = new IllegalStateException((Throwable)null);
-      assertNull(e.getCause());
-    }
     
     /**
+     * @tests {@link java.land.IllegalStateException#IllIllegalStateException(java.lang.Throwable)}
+     */
+    public void test_ConstructorLjava_lang_Throwable() {
+        Throwable emptyThrowable = new Exception();
+        IllegalStateException emptyException = new IllegalStateException(emptyThrowable);
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+        Throwable throwable = new Exception("msg");
+        IllegalStateException exception = new IllegalStateException(throwable);
+        assertEquals(throwable.getClass().getName() + ": " + "msg", exception.getMessage());
+        assertEquals(throwable.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(throwable.getClass().getName(), emptyException.getCause().toString());
+    }
+
+    /**
+     * @tests {@link java.land.IllegalStateException#IllIllegalStateException(java.lang.String, java.lang.Throwable)}
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+        Throwable emptyThrowable = new Exception();
+        IllegalStateException emptyException = new IllegalStateException("msg", emptyThrowable);
+        assertEquals("msg", emptyException.getMessage());
+        assertEquals("msg", emptyException.getLocalizedMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+        Throwable throwable = new Exception("msg_exception");
+        IllegalStateException exception = new IllegalStateException("msg", throwable);
+        assertEquals("msg", exception.getMessage());
+        assertEquals("msg", exception.getLocalizedMessage());
+        assertEquals(throwable.getClass().getName() + ": " + throwable.getMessage(), exception
+                .getCause().toString());
+    }
+
+    /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization.",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new IllegalStateException());
@@ -109,12 +88,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new IllegalStateException());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalThreadStateExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalThreadStateExceptionTest.java
index 1b3a03d..475f6bb 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalThreadStateExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IllegalThreadStateExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(IllegalThreadStateException.class) 
 public class IllegalThreadStateExceptionTest extends TestCase {
 
-    /**
+	/**
      * @tests java.lang.IllegalThreadStateException#IllegalThreadStateException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalThreadStateException",
-        args = {}
-    )
     public void test_Constructor() {
         IllegalThreadStateException e = new IllegalThreadStateException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.IllegalThreadStateException#IllegalThreadStateException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalThreadStateException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IllegalThreadStateException e = new IllegalThreadStateException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IncompatibleClassChangeErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IncompatibleClassChangeErrorTest.java
index 7893b29..b6a8d6a 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IncompatibleClassChangeErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IncompatibleClassChangeErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(IncompatibleClassChangeError.class) 
 public class IncompatibleClassChangeErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IncompatibleClassChangeError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError()
+	 */
     public void test_Constructor() {
         IncompatibleClassChangeError e = new IncompatibleClassChangeError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.IncompatibleClassChangeError#IncompatibleClassChangeError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IncompatibleClassChangeError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IncompatibleClassChangeError e = new IncompatibleClassChangeError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IndexOutOfBoundsExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IndexOutOfBoundsExceptionTest.java
index d897e47..617c71c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IndexOutOfBoundsExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IndexOutOfBoundsExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(IndexOutOfBoundsException.class) 
 public class IndexOutOfBoundsExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IndexOutOfBoundsException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException()
+	 */
     public void test_Constructor() {
         IndexOutOfBoundsException e = new IndexOutOfBoundsException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.IndexOutOfBoundsException#IndexOutOfBoundsException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IndexOutOfBoundsException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         IndexOutOfBoundsException e = new IndexOutOfBoundsException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationErrorTest.java
index 5601755..1d9722c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(InstantiationError.class) 
 public class InstantiationErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.InstantiationError#InstantiationError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InstantiationError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.InstantiationError#InstantiationError()
+	 */
     public void test_Constructor() {
         InstantiationError e = new InstantiationError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.InstantiationError#InstantiationError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InstantiationError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         InstantiationError e = new InstantiationError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationExceptionTest.java
index febeee2..5f636d5 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InstantiationExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(InstantiationException.class) 
 public class InstantiationExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.InstantiationException#InstantiationException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InstantiationException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.InstantiationException#InstantiationException()
+	 */
     public void test_Constructor() {
         InstantiationException e = new InstantiationException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.InstantiationException#InstantiationException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InstantiationException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         InstantiationException e = new InstantiationException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InternalErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InternalErrorTest.java
index 4b93777..3ff4711 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InternalErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InternalErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(InternalError.class) 
 public class InternalErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.InternalError#InternalError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InternalError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.InternalError#InternalError()
+	 */
     public void test_Constructor() {
         InternalError e = new InternalError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.InternalError#InternalError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InternalError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         InternalError e = new InternalError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InterruptedExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InterruptedExceptionTest.java
index 4faa301..96c85e6 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InterruptedExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/InterruptedExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(InterruptedException.class) 
 public class InterruptedExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.InterruptedException#InterruptedException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InterruptedException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.InterruptedException#InterruptedException()
+	 */
     public void test_Constructor() {
         InterruptedException e = new InterruptedException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.InterruptedException#InterruptedException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InterruptedException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         InterruptedException e = new InterruptedException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/LinkageErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/LinkageErrorTest.java
index c856705..9c1adcb 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/LinkageErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/LinkageErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(LinkageError.class) 
 public class LinkageErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.LinkageError#LinkageError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "LinkageError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.LinkageError#LinkageError()
+	 */
     public void test_Constructor() {
         LinkageError e = new LinkageError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.LinkageError#LinkageError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "LinkageError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         LinkageError e = new LinkageError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
index 02bed3c..4ff0a09 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/MathTest.java
@@ -17,247 +17,107 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-@TestTargetClass(Math.class) 
 public class MathTest extends junit.framework.TestCase {
 
-    double HYP = Math.sqrt(2.0);
+	double HYP = Math.sqrt(2.0);
 
-    double OPP = 1.0;
+	double OPP = 1.0;
 
-    double ADJ = 1.0;
+	double ADJ = 1.0;
 
-    /* Required to make previous preprocessor flags work - do not remove */
-    int unused = 0;
+	/* Required to make previous preprocessor flags work - do not remove */
+	int unused = 0;
 
-    public static void assertEquals(String message, double expected, double actual, double delta) {
-        if (delta == 0D)
-            junit.framework.Assert.assertEquals(message, expected, actual, Math.ulp(expected));
-        else
-            junit.framework.Assert.assertEquals(message, expected, actual, delta);
-    }
+	/**
+	 * @tests java.lang.Math#abs(double)
+	 */
+	public void test_absD() {
+		// Test for method double java.lang.Math.abs(double)
 
-    public static void assertEquals(String message, float expected, float actual, float delta) {
-        if (delta == 0F)
-            junit.framework.Assert.assertEquals(message, expected, actual, Math.ulp(expected));
-        else
-            junit.framework.Assert.assertEquals(message, expected, actual, delta);
-    }
-    
-    /**
-     * @tests java.lang.Math#abs(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {double.class}
-    )
-    public void test_absD() {
-        // Test for method double java.lang.Math.abs(double)
-        assertTrue("Incorrect double abs value",
-                (Math.abs(-1908.8976) == 1908.8976));
-        assertTrue("Incorrect double abs value",
-                (Math.abs(1908.8976) == 1908.8976));
-        assertEquals(0.0, Math.abs(0.0));
-        assertEquals(0.0, Math.abs(-0.0));
-        assertEquals(Double.POSITIVE_INFINITY, 
-                                            Math.abs(Double.POSITIVE_INFINITY));
-        assertEquals(Double.POSITIVE_INFINITY, 
-                                            Math.abs(Double.NEGATIVE_INFINITY));
-        
-        assertEquals(Double.NaN, Math.abs(Double.NaN));        
-    }
+		assertTrue("Incorrect double abs value",
+				(Math.abs(-1908.8976) == 1908.8976));
+		assertTrue("Incorrect double abs value",
+				(Math.abs(1908.8976) == 1908.8976));
+	}
 
-    /**
-     * @tests java.lang.Math#abs(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {float.class}
-    )
-    public void test_absF() {
-        // Test for method float java.lang.Math.abs(float)
-        assertTrue("Incorrect float abs value",
-                (Math.abs(-1908.8976f) == 1908.8976f));
-        assertTrue("Incorrect float abs value",
-                (Math.abs(1908.8976f) == 1908.8976f));
-        
-        assertEquals(0.0f, Math.abs(0.0f));
-        assertEquals(0.0f, Math.abs(-0.0f));
-        assertEquals(Float.POSITIVE_INFINITY, 
-                                            Math.abs(Float.POSITIVE_INFINITY));
-        assertEquals(Float.POSITIVE_INFINITY, 
-                                            Math.abs(Float.NEGATIVE_INFINITY));
-        
-        assertEquals(Float.NaN, Math.abs(Float.NaN));
-    }
+	/**
+	 * @tests java.lang.Math#abs(float)
+	 */
+	public void test_absF() {
+		// Test for method float java.lang.Math.abs(float)
+		assertTrue("Incorrect float abs value",
+				(Math.abs(-1908.8976f) == 1908.8976f));
+		assertTrue("Incorrect float abs value",
+				(Math.abs(1908.8976f) == 1908.8976f));
+	}
 
-    /**
-     * @tests java.lang.Math#abs(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {int.class}
-    )
-    public void test_absI() {
-        // Test for method int java.lang.Math.abs(int)
-        assertTrue("Incorrect int abs value", (Math.abs(-1908897) == 1908897));
-        assertTrue("Incorrect int abs value", (Math.abs(1908897) == 1908897));
-        
-        assertEquals(Integer.MIN_VALUE, Math.abs(Integer.MIN_VALUE));
-    }
+	/**
+	 * @tests java.lang.Math#abs(int)
+	 */
+	public void test_absI() {
+		// Test for method int java.lang.Math.abs(int)
+		assertTrue("Incorrect int abs value", (Math.abs(-1908897) == 1908897));
+		assertTrue("Incorrect int abs value", (Math.abs(1908897) == 1908897));
+	}
 
-    /**
-     * @tests java.lang.Math#abs(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {long.class}
-    )
-    public void test_absJ() {
-        // Test for method long java.lang.Math.abs(long)
-        assertTrue("Incorrect long abs value",
-                (Math.abs(-19088976000089L) == 19088976000089L));
-        assertTrue("Incorrect long abs value",
-                (Math.abs(19088976000089L) == 19088976000089L));
-        
-        assertEquals(Long.MIN_VALUE, Math.abs(Long.MIN_VALUE));        
-    }
+	/**
+	 * @tests java.lang.Math#abs(long)
+	 */
+	public void test_absJ() {
+		// Test for method long java.lang.Math.abs(long)
+		assertTrue("Incorrect long abs value",
+				(Math.abs(-19088976000089L) == 19088976000089L));
+		assertTrue("Incorrect long abs value",
+				(Math.abs(19088976000089L) == 19088976000089L));
+	}
 
-    /**
-     * @tests java.lang.Math#acos(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "acos",
-        args = {double.class}
-    )
-    public void test_acosD() {
-        // Test for method double java.lang.Math.acos(double)
-        double r = Math.cos(Math.acos(ADJ / HYP));
-        long lr = Double.doubleToLongBits(r);
-        long t = Double.doubleToLongBits(ADJ / HYP);
-        assertTrue("Returned incorrect arc cosine", lr == t || (lr + 1) == t
-                || (lr - 1) == t);
-        
-        assertEquals(Double.NaN, Math.acos(Double.MAX_VALUE));
-        assertEquals(Double.NaN, Math.acos(Double.NaN));
-    }
+	/**
+	 * @tests java.lang.Math#acos(double)
+	 */
+	public void test_acosD() {
+		// Test for method double java.lang.Math.acos(double)
+		double r = Math.cos(Math.acos(ADJ / HYP));
+		long lr = Double.doubleToLongBits(r);
+		long t = Double.doubleToLongBits(ADJ / HYP);
+		assertTrue("Returned incorrect arc cosine", lr == t || (lr + 1) == t
+				|| (lr - 1) == t);
+	}
 
-    /**
-     * @tests java.lang.Math#asin(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "asin",
-        args = {double.class}
-    )
-    public void test_asinD() {
-        // Test for method double java.lang.Math.asin(double)
-        double r = Math.sin(Math.asin(OPP / HYP));
-        long lr = Double.doubleToLongBits(r);
-        long t = Double.doubleToLongBits(OPP / HYP);
-        assertTrue("Returned incorrect arc sine", lr == t || (lr + 1) == t
-                || (lr - 1) == t);
-        
-        assertEquals(Double.NaN, Math.asin(Double.MAX_VALUE));
-        assertEquals(Double.NaN, Math.asin(Double.NaN));
-        assertEquals(0, Math.asin(0), 0);
-        assertEquals(-0, Math.asin(-0), 0);        
-    }
+	/**
+	 * @tests java.lang.Math#asin(double)
+	 */
+	public void test_asinD() {
+		// Test for method double java.lang.Math.asin(double)
+		double r = Math.sin(Math.asin(OPP / HYP));
+		long lr = Double.doubleToLongBits(r);
+		long t = Double.doubleToLongBits(OPP / HYP);
+		assertTrue("Returned incorrect arc sine", lr == t || (lr + 1) == t
+				|| (lr - 1) == t);
+	}
 
-    /**
-     * @tests java.lang.Math#atan(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "atan",
-        args = {double.class}
-    )
-    public void test_atanD() {
-        // Test for method double java.lang.Math.atan(double)
-        double answer = Math.tan(Math.atan(1.0));
-        assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
-                && answer >= 9.9999999999999983E-1);
-        
-        assertEquals(Double.NaN, Math.atan(Double.NaN));
-        assertEquals(0.0, Math.atan(0.0), 0.0);
-        assertEquals(-0.0, Math.atan(-0.0), 0.0);
-    }
+	/**
+	 * @tests java.lang.Math#atan(double)
+	 */
+	public void test_atanD() {
+		// Test for method double java.lang.Math.atan(double)
+		double answer = Math.tan(Math.atan(1.0));
+		assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+				&& answer >= 9.9999999999999983E-1);
+	}
 
-    /**
-     * @tests java.lang.Math#atan2(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "atan2",
-        args = {double.class, double.class}
-    )
-    public void test_atan2DD() {
-        double pi = 3.141592653589793;
-        // Test for method double java.lang.Math.atan2(double, double)
-        double answer = Math.atan(Math.tan(1.0));
-        assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
-                && answer >= 9.9999999999999983E-1);
-        
-        assertEquals(Double.NaN, Math.atan2(Double.NaN, 1.0));
-        assertEquals(Double.NaN, Math.atan2(1.0, Double.NaN));
-        
-        assertEquals(0.0, Math.atan2(0, 1));
-        assertEquals(0.0, Math.atan2(1, Double.POSITIVE_INFINITY));
-        
-        assertEquals(-0.0, Math.atan2(-0.0, 1.0));
-        assertEquals(-0.0, Math.atan2(-1.0, Double.POSITIVE_INFINITY));
-        
-        assertEquals(pi, Math.atan2(0.0, -1.0));
-        assertEquals(pi, Math.atan2(1.0, Double.NEGATIVE_INFINITY));       
-        
-        assertEquals(-pi, Math.atan2(-0.0, -1.0));
-        assertEquals(-pi, Math.atan2(-1.0, Double.NEGATIVE_INFINITY)); 
-        
-        assertEquals(pi/2, Math.atan2(1.0, 0.0));
-        assertEquals(pi/2, Math.atan2(1.0, -0.0));
-        
-        assertEquals(pi/2, Math.atan2(Double.POSITIVE_INFINITY, 1));
-        assertEquals(pi/2, Math.atan2(Double.POSITIVE_INFINITY, -1));     
-        
-        assertEquals(-pi/2, Math.atan2(-1, 0));
-        assertEquals(-pi/2, Math.atan2(-1, -0));        
-        assertEquals(-pi/2, Math.atan2(Double.NEGATIVE_INFINITY, 1)); 
-        
-        assertEquals(pi/4, Math.atan2(Double.POSITIVE_INFINITY, 
-                                                     Double.POSITIVE_INFINITY));
-        assertEquals(3*pi/4, Math.atan2(Double.POSITIVE_INFINITY, 
-                                                     Double.NEGATIVE_INFINITY));    
-        assertEquals(-pi/4, Math.atan2(Double.NEGATIVE_INFINITY, 
-                                                     Double.POSITIVE_INFINITY)); 
-        assertEquals(-3*pi/4, Math.atan2(Double.NEGATIVE_INFINITY, 
-                                                     Double.NEGATIVE_INFINITY));        
-    }
+	/**
+	 * @tests java.lang.Math#atan2(double, double)
+	 */
+	public void test_atan2DD() {
+		// Test for method double java.lang.Math.atan2(double, double)
+		double answer = Math.atan(Math.tan(1.0));
+		assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+				&& answer >= 9.9999999999999983E-1);
+	}
     
      /**
      * @tests java.lang.Math#cbrt(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "cbrt",
-        args = {double.class}
-    )
     public void test_cbrt_D() {
         //Test for special situations
         assertTrue("Should return Double.NaN", Double.isNaN(Math
@@ -269,11 +129,11 @@
                 Double.NEGATIVE_INFINITY, Math
                         .cbrt(Double.NEGATIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
-                .cbrt(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double.doubleToLongBits(Math
-                .cbrt(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double.doubleToLongBits(Math
-                .cbrt(-0.0)));
+				.cbrt(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double.doubleToLongBits(Math
+				.cbrt(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double.doubleToLongBits(Math
+				.cbrt(-0.0)));
 
         assertEquals("Should return 3.0", 3.0, Math.cbrt(27.0), 0D);
         assertEquals("Should return 23.111993172558684", 23.111993172558684,
@@ -290,62 +150,173 @@
         assertEquals("Should return -0.01", -0.01, Math.cbrt(-0.000001), 0D);
     }
 
-    /**
-     * @tests java.lang.Math#ceil(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ceil",
-        args = {double.class}
-    )
-    public void test_ceilD() {
-        // Test for method double java.lang.Math.ceil(double)
+	/**
+	 * @tests java.lang.Math#ceil(double)
+	 */
+	public void test_ceilD() {
+		// Test for method double java.lang.Math.ceil(double)
                 assertEquals("Incorrect ceiling for double",
                              79, Math.ceil(78.89), 0);
-        assertEquals("Incorrect ceiling for double",
+		assertEquals("Incorrect ceiling for double",
                              -78, Math.ceil(-78.89), 0);
-        
-        assertEquals("Incorrect ceiling for double",
-                -78, Math.ceil(-78), 0);
-        
-        double [] args = {0.0, -0.0, Double.NaN, Double.POSITIVE_INFINITY, 
-                Double.NEGATIVE_INFINITY};
-        for(int i = 0; i < args.length; i++) {
-            assertEquals(args[i], Math.ceil(args[i]));
+	}
+	
+	/**
+     * cases for test_copySign_DD in MathTest/StrictMathTest
+     */
+    static final double[] COPYSIGN_DD_CASES = new double[] {
+            Double.POSITIVE_INFINITY, Double.MAX_VALUE, 3.4E302, 2.3,
+            Double.MIN_NORMAL, Double.MIN_NORMAL / 2, Double.MIN_VALUE, +0.0,
+            0.0, -0.0, -Double.MIN_VALUE, -Double.MIN_NORMAL / 2,
+            -Double.MIN_NORMAL, -4.5, -3.4E102, -Double.MAX_VALUE,
+            Double.NEGATIVE_INFINITY };
+
+    /**
+     * @tests {@link java.lang.Math#copySign(double, double)}
+     * @since 1.6
+     * 
+     */
+    @SuppressWarnings("boxing")
+    public void test_copySign_DD() {
+        for (int i = 0; i < COPYSIGN_DD_CASES.length; i++) {
+            final double magnitude = COPYSIGN_DD_CASES[i];
+            final long absMagnitudeBits = Double.doubleToLongBits(Math
+                    .abs(magnitude));
+            final long negMagnitudeBits = Double.doubleToLongBits(-Math
+                    .abs(magnitude));
+
+            // cases for NaN
+            assertEquals("If the sign is NaN, the result should be positive.",
+                    absMagnitudeBits, Double.doubleToLongBits(Math.copySign(
+                            magnitude, Double.NaN)));
+            assertTrue("The result should be NaN.", Double.isNaN(Math.copySign(
+                    Double.NaN, magnitude)));
+
+            for (int j = 0; j < COPYSIGN_DD_CASES.length; j++) {
+                final double sign = COPYSIGN_DD_CASES[j];
+                final long resultBits = Double.doubleToLongBits(Math.copySign(
+                        magnitude, sign));
+
+                if (sign > 0 || Double.valueOf(+0.0).equals(sign)
+                        || Double.valueOf(0.0).equals(sign)) {
+                    assertEquals(
+                            "If the sign is positive, the result should be positive.",
+                            absMagnitudeBits, resultBits);
+                }
+                if (sign < 0 || Double.valueOf(-0.0).equals(sign)) {
+                    assertEquals(
+                            "If the sign is negative, the result should be negative.",
+                            negMagnitudeBits, resultBits);
+                }
+            }
         }
-        assertEquals(-0.0, Math.ceil(-0.5));
+
+        assertTrue("The result should be NaN.", Double.isNaN(Math.copySign(
+                Double.NaN, Double.NaN)));
+
+        try {
+            Math.copySign((Double) null, 2.3);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.copySign(2.3, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.copySign((Double) null, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.Math#cos(double)
+     * cases for test_copySign_FF in MathTest/StrictMathTest
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "cos",
-        args = {double.class}
-    )
-    public void test_cosD() {
-        // Test for method double java.lang.Math.cos(double)
-        assertEquals("Incorrect answer", 1.0, Math.cos(0), 0D);
-        assertEquals("Incorrect answer", 0.5403023058681398, Math.cos(1), 0D);
-        double [] args = {Double.NaN, Double.POSITIVE_INFINITY, 
-                          Double.NEGATIVE_INFINITY};
-        for(int i = 0; i < args.length; i++) {
-            assertEquals(args[i], Math.ceil(args[i]));
-        }        
+    static final float[] COPYSIGN_FF_CASES = new float[] {
+            Float.POSITIVE_INFINITY, Float.MAX_VALUE, 3.4E12f, 2.3f,
+            Float.MIN_NORMAL, Float.MIN_NORMAL / 2, Float.MIN_VALUE, +0.0f,
+            0.0f, -0.0f, -Float.MIN_VALUE, -Float.MIN_NORMAL / 2,
+            -Float.MIN_NORMAL, -4.5f, -5.6442E21f, -Float.MAX_VALUE,
+            Float.NEGATIVE_INFINITY };
+
+    /**
+     * @tests {@link java.lang.Math#copySign(float, float)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_copySign_FF() {
+        for (int i = 0; i < COPYSIGN_FF_CASES.length; i++) {
+            final float magnitude = COPYSIGN_FF_CASES[i];
+            final int absMagnitudeBits = Float.floatToIntBits(Math
+                    .abs(magnitude));
+            final int negMagnitudeBits = Float.floatToIntBits(-Math
+                    .abs(magnitude));
+
+            // cases for NaN
+            assertEquals("If the sign is NaN, the result should be positive.",
+                    absMagnitudeBits, Float.floatToIntBits(Math.copySign(
+                            magnitude, Float.NaN)));
+            assertTrue("The result should be NaN.", Float.isNaN(Math.copySign(
+                    Float.NaN, magnitude)));
+
+            for (int j = 0; j < COPYSIGN_FF_CASES.length; j++) {
+                final float sign = COPYSIGN_FF_CASES[j];
+                final int resultBits = Float.floatToIntBits(Math.copySign(
+                        magnitude, sign));
+                if (sign > 0 || Float.valueOf(+0.0f).equals(sign)
+                        || Float.valueOf(0.0f).equals(sign)) {
+                    assertEquals(
+                            "If the sign is positive, the result should be positive.",
+                            absMagnitudeBits, resultBits);
+                }
+                if (sign < 0 || Float.valueOf(-0.0f).equals(sign)) {
+                    assertEquals(
+                            "If the sign is negative, the result should be negative.",
+                            negMagnitudeBits, resultBits);
+                }
+            }
+        }
+
+        assertTrue("The result should be NaN.", Float.isNaN(Math.copySign(
+                Float.NaN, Float.NaN)));
+
+        try {
+            Math.copySign((Float) null, 2.3f);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.copySign(2.3f, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.copySign((Float) null, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
+	/**
+	 * @tests java.lang.Math#cos(double)
+	 */
+	public void test_cosD() {
+		// Test for method double java.lang.Math.cos(double)
+		assertEquals("Incorrect answer", 1.0, Math.cos(0), 0D);
+		assertEquals("Incorrect answer", 0.5403023058681398, Math.cos(1), 0D);
+	}
+
     /**
      * @tests java.lang.Math#cosh(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "cosh",
-        args = {double.class}
-    )
     public void test_cosh_D() {
         // Test for special situations
         assertTrue(Double.isNaN(Math.cosh(Double.NaN)));
@@ -372,40 +343,21 @@
         assertEquals("Should return 1.0", 1.0, Math.cosh(Double.MIN_VALUE), 0D);
     }
     
-    /**
-     * @tests java.lang.Math#exp(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "exp",
-        args = {double.class}
-    )
-    public void test_expD() {
-        // Test for method double java.lang.Math.exp(double)
-        assertTrue("Incorrect answer returned for simple power", Math.abs(Math
-                .exp(4D)
-                - Math.E * Math.E * Math.E * Math.E) < 0.1D);
-        assertTrue("Incorrect answer returned for larger power", Math.log(Math
-                .abs(Math.exp(5.5D)) - 5.5D) < 10.0D);
-        
-        assertEquals("Incorrect returned value for NaN", 
-                                              Double.NaN, Math.exp(Double.NaN));
-        assertEquals("Incorrect returned value for positive infinity", 
-                  Double.POSITIVE_INFINITY, Math.exp(Double.POSITIVE_INFINITY));
-        assertEquals("Incorrect returned value for negative infinity", 
-                                      0, Math.exp(Double.NEGATIVE_INFINITY), 0);        
-    }
+	/**
+	 * @tests java.lang.Math#exp(double)
+	 */
+	public void test_expD() {
+		// Test for method double java.lang.Math.exp(double)
+		assertTrue("Incorrect answer returned for simple power", Math.abs(Math
+				.exp(4D)
+				- Math.E * Math.E * Math.E * Math.E) < 0.1D);
+		assertTrue("Incorrect answer returned for larger power", Math.log(Math
+				.abs(Math.exp(5.5D)) - 5.5D) < 10.0D);
+	}
     
     /**
      * @tests java.lang.Math#expm1(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "expm1",
-        args = {double.class}
-    )
     public void test_expm1_D() {
         // Test for special cases
         assertTrue("Should return NaN", Double.isNaN(Math.expm1(Double.NaN)));
@@ -414,11 +366,11 @@
         assertEquals("Should return -1.0", -1.0, Math
                 .expm1(Double.NEGATIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
-                .expm1(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(Math.expm1(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(Math.expm1(-0.0)));
+				.expm1(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(Math.expm1(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(Math.expm1(-0.0)));
 
         assertEquals("Should return -9.999950000166666E-6",
                 -9.999950000166666E-6, Math.expm1(-0.00001), 0D);
@@ -436,36 +388,123 @@
     /**
      * @tests java.lang.Math#floor(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "floor",
-        args = {double.class}
-    )
     public void test_floorD() {
-        // Test for method double java.lang.Math.floor(double)
-                assertEquals("Incorrect floor for double",
-                             78, Math.floor(78.89), 0);
-        assertEquals("Incorrect floor for double",
-                             -79, Math.floor(-78.89), 0);
-        assertEquals("Incorrect floor for integer",
-                              -78, Math.floor(-78), 0);
-        double [] args = {0, -0, Double.NaN, Double.POSITIVE_INFINITY, 
-                Double.NEGATIVE_INFINITY};
-        for(int i = 0; i < args.length; i++) {
-            assertEquals(args[i], Math.floor(args[i]));
-        }        
+        assertEquals("Incorrect floor for int", 42, Math.floor(42), 0);
+        assertEquals("Incorrect floor for -int", -2, Math.floor(-2), 0);
+        assertEquals("Incorrect floor for zero", 0d, Math.floor(0d), 0);
+
+        assertEquals("Incorrect floor for +double", 78, Math.floor(78.89), 0);
+        assertEquals("Incorrect floor for -double", -79, Math.floor(-78.89), 0);
+        assertEquals("floor large +double", 3.7314645675925406E19, Math.floor(3.7314645675925406E19), 0);
+        assertEquals("floor large -double", -8.173521839218E12, Math.floor(-8.173521839218E12), 0);
+        assertEquals("floor small double", 0.0d, Math.floor(1.11895241315E-102), 0);
+
+        // Compare toString representations here since -0.0 = +0.0, and
+        // NaN != NaN and we need to distinguish
+        assertEquals("Floor failed for NaN",
+                Double.toString(Double.NaN), Double.toString(Math.floor(Double.NaN)));
+        assertEquals("Floor failed for +0.0",
+                Double.toString(+0.0d), Double.toString(Math.floor(+0.0d)));
+        assertEquals("Floor failed for -0.0",
+                Double.toString(-0.0d), Double.toString(Math.floor(-0.0d)));
+        assertEquals("Floor failed for +infinity",
+                Double.toString(Double.POSITIVE_INFINITY), Double.toString(Math.floor(Double.POSITIVE_INFINITY)));
+        assertEquals("Floor failed for -infinity",
+                Double.toString(Double.NEGATIVE_INFINITY), Double.toString(Math.floor(Double.NEGATIVE_INFINITY)));
+    }
+	
+	/**
+     * cases for test_getExponent_D in MathTest/StrictMathTest
+     */
+    static final double GETEXPONENT_D_CASES[] = new double[] {
+            Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,
+            Double.MAX_VALUE, -Double.MAX_VALUE, 2.342E231, -2.342E231, 2800.0,
+            -2800.0, 5.323, -5.323, 1.323, -1.323, 0.623, -0.623, 0.323,
+            -0.323, Double.MIN_NORMAL * 24, -Double.MIN_NORMAL * 24,
+            Double.MIN_NORMAL, -Double.MIN_NORMAL, Double.MIN_NORMAL / 2,
+            -Double.MIN_NORMAL / 2, Double.MIN_VALUE, -Double.MIN_VALUE, +0.0,
+            0.0, -0.0, Double.NaN };
+
+    /**
+     * result for test_getExponent_D in MathTest/StrictMathTest
+     */
+    static final int GETEXPONENT_D_RESULTS[] = new int[] {
+            Double.MAX_EXPONENT + 1, Double.MAX_EXPONENT + 1,
+            Double.MAX_EXPONENT, Double.MAX_EXPONENT, 768, 768, 11, 11, 2, 2,
+            0, 0, -1, -1, -2, -2, -1018, -1018, Double.MIN_EXPONENT,
+            Double.MIN_EXPONENT, Double.MIN_EXPONENT - 1,
+            Double.MIN_EXPONENT - 1, Double.MIN_EXPONENT - 1,
+            Double.MIN_EXPONENT - 1, Double.MIN_EXPONENT - 1,
+            Double.MIN_EXPONENT - 1, Double.MIN_EXPONENT - 1,
+            Double.MAX_EXPONENT + 1 };
+
+    /**
+     * @tests {@link java.lang.Math#getExponent(double)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_getExponent_D() {
+        for (int i = 0; i < GETEXPONENT_D_CASES.length; i++) {
+            final double number = GETEXPONENT_D_CASES[i];
+            final int result = GETEXPONENT_D_RESULTS[i];
+            assertEquals("Wrong result of getExponent(double).", result, Math
+                    .getExponent(number));
+        }
+
+        try {
+            Math.getExponent((Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * cases for test_getExponent_F in MathTest/StrictMathTest
+     */
+    static final float GETEXPONENT_F_CASES[] = new float[] {
+            Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.MAX_VALUE,
+            -Float.MAX_VALUE, 3.4256E23f, -3.4256E23f, 2800.0f, -2800.0f,
+            5.323f, -5.323f, 1.323f, -1.323f, 0.623f, -0.623f, 0.323f, -0.323f,
+            Float.MIN_NORMAL * 24, -Float.MIN_NORMAL * 24, Float.MIN_NORMAL,
+            -Float.MIN_NORMAL, Float.MIN_NORMAL / 2, -Float.MIN_NORMAL / 2,
+            Float.MIN_VALUE, -Float.MIN_VALUE, +0.0f, 0.0f, -0.0f, Float.NaN,1,Float.MIN_NORMAL * 1.5f };
+
+    /**
+     * result for test_getExponent_F in MathTest/StrictMathTest
+     */
+    static final int GETEXPONENT_F_RESULTS[] = new int[] {
+            Float.MAX_EXPONENT + 1, Float.MAX_EXPONENT + 1, Float.MAX_EXPONENT,
+            Float.MAX_EXPONENT, 78, 78, 11, 11, 2, 2, 0, 0, -1, -1, -2, -2,
+            -122, -122, Float.MIN_EXPONENT, Float.MIN_EXPONENT,
+            Float.MIN_EXPONENT - 1, Float.MIN_EXPONENT - 1,
+            Float.MIN_EXPONENT - 1, Float.MIN_EXPONENT - 1,
+            Float.MIN_EXPONENT - 1, Float.MIN_EXPONENT - 1,
+            Float.MIN_EXPONENT - 1, Float.MAX_EXPONENT + 1,0,Float.MIN_EXPONENT };
+    
+    /**
+     * @tests {@link java.lang.Math#getExponent(float)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_getExponent_F() {
+        for (int i = 0; i < GETEXPONENT_F_CASES.length; i++) {
+            final float number = GETEXPONENT_F_CASES[i];
+            final int result = GETEXPONENT_F_RESULTS[i];
+            assertEquals("Wrong result of getExponent(float).", result, Math
+                    .getExponent(number));
+        }
+        try {
+            Math.getExponent((Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
     
     /**
      * @tests java.lang.Math#hypot(double, double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hypot",
-        args = {double.class, double.class}
-    )
     public void test_hypot_DD() {
         // Test for special cases
         assertEquals("Should return POSITIVE_INFINITY",
@@ -501,63 +540,34 @@
                 -5413.7185, Double.MIN_VALUE), 0D);
     }
 
-    /**
-     * @tests java.lang.Math#IEEEremainder(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IEEEremainder",
-        args = {double.class, double.class}
-    )
-    public void test_IEEEremainderDD() {
-        // Test for method double java.lang.Math.IEEEremainder(double, double)
-        assertEquals("Incorrect remainder returned",
-                0.0, Math.IEEEremainder(1.0, 1.0), 0D);
-        assertTrue("Incorrect remainder returned", Math.IEEEremainder(1.32,
-                89.765) >= 1.4705063220631647E-2
-                || Math.IEEEremainder(1.32, 89.765) >= 1.4705063220631649E-2);
-        
-        assertEquals(Double.NaN, Math.IEEEremainder(Double.NaN, Double.NaN));
-        assertEquals(Double.NaN, Math.IEEEremainder(Double.NaN, 1.0));    
-        assertEquals(Double.NaN, Math.IEEEremainder(1.0, Double.NaN)); 
+	/**
+	 * @tests java.lang.Math#IEEEremainder(double, double)
+	 */
+	public void test_IEEEremainderDD() {
+		// Test for method double java.lang.Math.IEEEremainder(double, double)
+		assertEquals("Incorrect remainder returned",
+				0.0, Math.IEEEremainder(1.0, 1.0), 0D);
+		assertTrue("Incorrect remainder returned", Math.IEEEremainder(1.32,
+				89.765) >= 1.4705063220631647E-2
+				|| Math.IEEEremainder(1.32, 89.765) >= 1.4705063220631649E-2);
+	}
 
-        assertEquals(Double.NaN, Math.IEEEremainder(Double.POSITIVE_INFINITY, 1.0));     
-        assertEquals(Double.NaN, Math.IEEEremainder(Double.NEGATIVE_INFINITY, 1.0));
-        assertEquals(1.0, Math.IEEEremainder(1.0, Double.POSITIVE_INFINITY));
-        assertEquals(1.0, Math.IEEEremainder(1.0, Double.NEGATIVE_INFINITY));
-        assertEquals(Double.NaN, Math.IEEEremainder(1.0, 0.0));
-        assertEquals(Double.NaN, Math.IEEEremainder(1.0, -0.0));        
-    }
-
-    /**
-     * @tests java.lang.Math#log(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {double.class}
-    )
-    public void test_logD() {
-        // Test for method double java.lang.Math.log(double)
-        for (double d = 10; d >= -10; d -= 0.5) {
-            double answer = Math.log(Math.exp(d));
-            assertTrue("Answer does not equal expected answer for d = " + d
-                    + " answer = " + answer, Math.abs(answer - d) <= Math
-                    .abs(d * 0.00000001));
-        }
-    }
+	/**
+	 * @tests java.lang.Math#log(double)
+	 */
+	public void test_logD() {
+		// Test for method double java.lang.Math.log(double)
+		for (double d = 10; d >= -10; d -= 0.5) {
+			double answer = Math.log(Math.exp(d));
+			assertTrue("Answer does not equal expected answer for d = " + d
+					+ " answer = " + answer, Math.abs(answer - d) <= Math
+					.abs(d * 0.00000001));
+		}
+	}
     
     /**
      * @tests java.lang.Math#log10(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log10",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_log10_D() {
         // Test for special cases
@@ -581,12 +591,6 @@
     /**
      * @tests java.lang.Math#log1p(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log1p",
-        args = {double.class}
-    )
     public void test_log1p_D() {
         // Test for special cases
         assertTrue("Should return NaN", Double.isNaN(Math.log1p(Double.NaN)));
@@ -594,11 +598,11 @@
         assertEquals("Should return POSITIVE_INFINITY",
                 Double.POSITIVE_INFINITY, Math.log1p(Double.POSITIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
-                .log1p(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(Math.log1p(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(Math.log1p(-0.0)));
+				.log1p(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(Math.log1p(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(Math.log1p(-0.0)));
 
         assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
                 Math.log1p(-0.254856327), 0D);
@@ -612,323 +616,1032 @@
                 .log1p(Double.MIN_VALUE), 0D);
     }
 
-    /**
-     * @tests java.lang.Math#max(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {double.class, double.class}
-    )
-    public void test_maxDD() {
-        // Test for method double java.lang.Math.max(double, double)
-        assertEquals("Incorrect double max value", 1908897.6000089, 
-                Math.max(-1908897.6000089,
-                1908897.6000089), 0D);
-        assertEquals("Incorrect double max value",
-                1908897.6000089, Math.max(2.0, 1908897.6000089), 0D);
-        assertEquals("Incorrect double max value", -2.0, Math.max(-2.0,
-                -1908897.6000089), 0D);
+	/**
+	 * @tests java.lang.Math#max(double, double)
+	 */
+	public void test_maxDD() {
+		// Test for method double java.lang.Math.max(double, double)
+		assertEquals("Incorrect double max value", 1908897.6000089, Math.max(-1908897.6000089,
+				1908897.6000089), 0D);
+		assertEquals("Incorrect double max value",
+				1908897.6000089, Math.max(2.0, 1908897.6000089), 0D);
+		assertEquals("Incorrect double max value", -2.0, Math.max(-2.0,
+				-1908897.6000089), 0D);
 
-        assertEquals("Incorrect returned value", Double.NaN, 
-                                                Math.max(-1.0, Double.NaN));
-        assertEquals("Incorrect returned value", Double.NaN, 
-                                                Math.max(Double.NaN, -1.0));
-        assertEquals("Incorrect returned value", 0, Math.max(0, -0), 0D);          
+		// Compare toString representations here since -0.0 = +0.0, and
+		// NaN != NaN and we need to distinguish
+        assertEquals("Max failed for NaN",
+                Double.toString(Double.NaN), Double.toString(Math.max(Double.NaN, 42.0d)));
+        assertEquals("Max failed for NaN",
+                Double.toString(Double.NaN), Double.toString(Math.max(42.0d, Double.NaN)));
+        assertEquals("Max failed for 0.0",
+                Double.toString(+0.0d), Double.toString(Math.max(+0.0d, -0.0d)));
+        assertEquals("Max failed for 0.0",
+                Double.toString(+0.0d), Double.toString(Math.max(-0.0d, +0.0d)));
+        assertEquals("Max failed for -0.0d",
+                Double.toString(-0.0d), Double.toString(Math.max(-0.0d, -0.0d)));
+        assertEquals("Max failed for 0.0",
+                Double.toString(+0.0d), Double.toString(Math.max(+0.0d, +0.0d)));
+	}
+
+	/**
+	 * @tests java.lang.Math#max(float, float)
+	 */
+	public void test_maxFF() {
+		// Test for method float java.lang.Math.max(float, float)
+		assertTrue("Incorrect float max value", Math.max(-1908897.600f,
+				1908897.600f) == 1908897.600f);
+		assertTrue("Incorrect float max value",
+				Math.max(2.0f, 1908897.600f) == 1908897.600f);
+		assertTrue("Incorrect float max value",
+				Math.max(-2.0f, -1908897.600f) == -2.0f);
+		
+	    // Compare toString representations here since -0.0 = +0.0, and
+        // NaN != NaN and we need to distinguish
+        assertEquals("Max failed for NaN",
+                Float.toString(Float.NaN), Float.toString(Math.max(Float.NaN, 42.0f)));
+        assertEquals("Max failed for NaN",
+                Float.toString(Float.NaN), Float.toString(Math.max(42.0f, Float.NaN)));
+        assertEquals("Max failed for 0.0",
+                Float.toString(+0.0f), Float.toString(Math.max(+0.0f, -0.0f)));
+        assertEquals("Max failed for 0.0",
+                Float.toString(+0.0f), Float.toString(Math.max(-0.0f, +0.0f)));
+        assertEquals("Max failed for -0.0f",
+                Float.toString(-0.0f), Float.toString(Math.max(-0.0f, -0.0f)));
+        assertEquals("Max failed for 0.0",
+                Float.toString(+0.0f), Float.toString(Math.max(+0.0f, +0.0f)));
+	}
+
+	/**
+	 * @tests java.lang.Math#max(int, int)
+	 */
+	public void test_maxII() {
+		// Test for method int java.lang.Math.max(int, int)
+		assertEquals("Incorrect int max value",
+				19088976, Math.max(-19088976, 19088976));
+		assertEquals("Incorrect int max value",
+				19088976, Math.max(20, 19088976));
+		assertEquals("Incorrect int max value", -20, Math.max(-20, -19088976));
+	}
+
+	/**
+	 * @tests java.lang.Math#max(long, long)
+	 */
+	public void test_maxJJ() {
+		// Test for method long java.lang.Math.max(long, long)
+		assertEquals("Incorrect long max value", 19088976000089L, Math.max(-19088976000089L,
+				19088976000089L));
+		assertEquals("Incorrect long max value",
+				19088976000089L, Math.max(20, 19088976000089L));
+		assertEquals("Incorrect long max value",
+				-20, Math.max(-20, -19088976000089L));
+	}
+
+	/**
+	 * @tests java.lang.Math#min(double, double)
+	 */
+	public void test_minDD() {
+		// Test for method double java.lang.Math.min(double, double)
+		assertEquals("Incorrect double min value", -1908897.6000089, Math.min(-1908897.6000089,
+				1908897.6000089), 0D);
+		assertEquals("Incorrect double min value",
+				2.0, Math.min(2.0, 1908897.6000089), 0D);
+		assertEquals("Incorrect double min value", -1908897.6000089, Math.min(-2.0,
+				-1908897.6000089), 0D);
+		assertEquals("Incorrect double min value", 1.0d, Math.min(1.0d, 1.0d));
+		
+	    // Compare toString representations here since -0.0 = +0.0, and
+        // NaN != NaN and we need to distinguish
+        assertEquals("Min failed for NaN",
+                Double.toString(Double.NaN), Double.toString(Math.min(Double.NaN, 42.0d)));
+        assertEquals("Min failed for NaN",
+                Double.toString(Double.NaN), Double.toString(Math.min(42.0d, Double.NaN)));
+        assertEquals("Min failed for -0.0",
+                Double.toString(-0.0d), Double.toString(Math.min(+0.0d, -0.0d)));
+        assertEquals("Min failed for -0.0",
+                Double.toString(-0.0d), Double.toString(Math.min(-0.0d, +0.0d)));
+        assertEquals("Min failed for -0.0d",
+                Double.toString(-0.0d), Double.toString(Math.min(-0.0d, -0.0d)));
+        assertEquals("Min failed for 0.0",
+                Double.toString(+0.0d), Double.toString(Math.min(+0.0d, +0.0d)));
+	}
+
+	/**
+	 * @tests java.lang.Math#min(float, float)
+	 */
+	public void test_minFF() {
+		// Test for method float java.lang.Math.min(float, float)
+		assertTrue("Incorrect float min value", Math.min(-1908897.600f,
+				1908897.600f) == -1908897.600f);
+		assertTrue("Incorrect float min value",
+				Math.min(2.0f, 1908897.600f) == 2.0f);
+		assertTrue("Incorrect float min value",
+				Math.min(-2.0f, -1908897.600f) == -1908897.600f);
+		assertEquals("Incorrect float min value", 1.0f, Math.min(1.0f, 1.0f));
+
+        // Compare toString representations here since -0.0 = +0.0, and
+        // NaN != NaN and we need to distinguish
+        assertEquals("Min failed for NaN",
+                Float.toString(Float.NaN), Float.toString(Math.min(Float.NaN, 42.0f)));
+        assertEquals("Min failed for NaN",
+                Float.toString(Float.NaN), Float.toString(Math.min(42.0f, Float.NaN)));
+        assertEquals("Min failed for -0.0",
+                Float.toString(-0.0f), Float.toString(Math.min(+0.0f, -0.0f)));
+        assertEquals("Min failed for -0.0",
+                Float.toString(-0.0f), Float.toString(Math.min(-0.0f, +0.0f)));
+        assertEquals("Min failed for -0.0f",
+                Float.toString(-0.0f), Float.toString(Math.min(-0.0f, -0.0f)));
+        assertEquals("Min failed for 0.0",
+                Float.toString(+0.0f), Float.toString(Math.min(+0.0f, +0.0f)));
+	}
+
+	/**
+	 * @tests java.lang.Math#min(int, int)
+	 */
+	public void test_minII() {
+		// Test for method int java.lang.Math.min(int, int)
+		assertEquals("Incorrect int min value",
+				-19088976, Math.min(-19088976, 19088976));
+		assertEquals("Incorrect int min value", 20, Math.min(20, 19088976));
+		assertEquals("Incorrect int min value",
+				-19088976, Math.min(-20, -19088976));
+
+	}
+
+	/**
+	 * @tests java.lang.Math#min(long, long)
+	 */
+	public void test_minJJ() {
+		// Test for method long java.lang.Math.min(long, long)
+		assertEquals("Incorrect long min value", -19088976000089L, Math.min(-19088976000089L,
+				19088976000089L));
+		assertEquals("Incorrect long min value",
+				20, Math.min(20, 19088976000089L));
+		assertEquals("Incorrect long min value",
+				-19088976000089L, Math.min(-20, -19088976000089L));
+	}
+	
+	/**
+     * start number cases for test_nextAfter_DD in MathTest/StrictMathTest
+     * NEXTAFTER_DD_START_CASES[i][0] is the start number
+     * NEXTAFTER_DD_START_CASES[i][1] is the nextUp of start number
+     * NEXTAFTER_DD_START_CASES[i][2] is the nextDown of start number
+     */
+    static final double NEXTAFTER_DD_START_CASES[][] = new double[][] {
+            { 3.4, 3.4000000000000004, 3.3999999999999995 },
+            { -3.4, -3.3999999999999995, -3.4000000000000004 },
+            { 3.4233E109, 3.4233000000000005E109, 3.4232999999999996E109 },
+            { -3.4233E109, -3.4232999999999996E109, -3.4233000000000005E109 },
+            { +0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+            { 0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+            { -0.0, Double.MIN_VALUE, -Double.MIN_VALUE },
+            { Double.MIN_VALUE, 1.0E-323, +0.0 },
+            { -Double.MIN_VALUE, -0.0, -1.0E-323 },
+            { Double.MIN_NORMAL, 2.225073858507202E-308, 2.225073858507201E-308 },
+            { -Double.MIN_NORMAL, -2.225073858507201E-308,
+                    -2.225073858507202E-308 },
+            { Double.MAX_VALUE, Double.POSITIVE_INFINITY,
+                    1.7976931348623155E308 },
+            { -Double.MAX_VALUE, -1.7976931348623155E308,
+                    Double.NEGATIVE_INFINITY },
+            { Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
+                    Double.MAX_VALUE },
+            { Double.NEGATIVE_INFINITY, -Double.MAX_VALUE,
+                    Double.NEGATIVE_INFINITY } };
+
+    /**
+     * direction number cases for test_nextAfter_DD/test_nextAfter_FD in
+     * MathTest/StrictMathTest
+     */
+    static final double NEXTAFTER_DD_FD_DIRECTION_CASES[] = new double[] {
+            Double.POSITIVE_INFINITY, Double.MAX_VALUE, 8.8, 3.4, 1.4,
+            Double.MIN_NORMAL, Double.MIN_NORMAL / 2, Double.MIN_VALUE, +0.0,
+            0.0, -0.0, -Double.MIN_VALUE, -Double.MIN_NORMAL / 2,
+            -Double.MIN_NORMAL, -1.4, -3.4, -8.8, -Double.MAX_VALUE,
+            Double.NEGATIVE_INFINITY };
+
+    /**
+     * @tests {@link java.lang.Math#nextAfter(double, double)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_nextAfter_DD() {
+        // test for most cases without exception
+        for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+            final double start = NEXTAFTER_DD_START_CASES[i][0];
+            final long nextUpBits = Double
+                    .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+            final long nextDownBits = Double
+                    .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][2]);
+
+            for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+                final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+                final long resultBits = Double.doubleToLongBits(Math.nextAfter(
+                        start, direction));
+                final long directionBits = Double.doubleToLongBits(direction);
+                if (direction > start) {
+                    assertEquals("Result should be next up-number.",
+                            nextUpBits, resultBits);
+                } else if (direction < start) {
+                    assertEquals("Result should be next down-number.",
+                            nextDownBits, resultBits);
+                } else {
+                    assertEquals("Result should be direction.", directionBits,
+                            resultBits);
+                }
+            }
+        }
+
+        // test for cases with NaN
+        for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Double.isNaN(Math
+                    .nextAfter(NEXTAFTER_DD_START_CASES[i][0], Double.NaN)));
+        }
+        for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Double.isNaN(Math
+                    .nextAfter(Double.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+        }
+        assertTrue("The result should be NaN.", Double.isNaN(Math.nextAfter(
+                Double.NaN, Double.NaN)));
+
+        // test for exception
+        try {
+            Math.nextAfter((Double) null, 2.3);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.nextAfter(2.3, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.nextAfter((Double) null, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.Math#max(float, float)
+     * start number cases for test_nextAfter_FD in MathTest/StrictMathTest
+     * NEXTAFTER_FD_START_CASES[i][0] is the start number
+     * NEXTAFTER_FD_START_CASES[i][1] is the nextUp of start number
+     * NEXTAFTER_FD_START_CASES[i][2] is the nextDown of start number
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {float.class, float.class}
-    )
-    public void test_maxFF() {
-        // Test for method float java.lang.Math.max(float, float)
-        assertTrue("Incorrect float max value", Math.max(-1908897.600f,
-                1908897.600f) == 1908897.600f);
-        assertTrue("Incorrect float max value",
-                Math.max(2.0f, 1908897.600f) == 1908897.600f);
-        assertTrue("Incorrect float max value",
-                Math.max(-2.0f, -1908897.600f) == -2.0f);
-        assertEquals("Incorrect returned value", Float.NaN, 
-                Math.max(-1.0f, Float.NaN));
-        assertEquals("Incorrect returned value", Float.NaN, 
-                Math.max(Float.NaN, -1.0f));
-        assertEquals("Incorrect returned value", 0f, Math.max(0f, -0f));         
+    static final float NEXTAFTER_FD_START_CASES[][] = new float[][] {
+            { 3.4f, 3.4000003f, 3.3999999f },
+            { -3.4f, -3.3999999f, -3.4000003f },
+            { 3.4233E19f, 3.4233002E19f, 3.4232998E19f },
+            { -3.4233E19f, -3.4232998E19f, -3.4233002E19f },
+            { +0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+            { 0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+            { -0.0f, Float.MIN_VALUE, -Float.MIN_VALUE },
+            { Float.MIN_VALUE, 2.8E-45f, +0.0f },
+            { -Float.MIN_VALUE, -0.0f, -2.8E-45f },
+            { Float.MIN_NORMAL, 1.1754945E-38f, 1.1754942E-38f },
+            { -Float.MIN_NORMAL, -1.1754942E-38f, -1.1754945E-38f },
+            { Float.MAX_VALUE, Float.POSITIVE_INFINITY, 3.4028233E38f },
+            { -Float.MAX_VALUE, -3.4028233E38f, Float.NEGATIVE_INFINITY },
+            { Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.MAX_VALUE },
+            { Float.NEGATIVE_INFINITY, -Float.MAX_VALUE,
+                    Float.NEGATIVE_INFINITY } };
+
+    /**
+     * @tests {@link java.lang.Math#nextAfter(float, double)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_nextAfter_FD() {
+        // test for most cases without exception
+        for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+            final float start = NEXTAFTER_FD_START_CASES[i][0];
+            final int nextUpBits = Float
+                    .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+            final int nextDownBits = Float
+                    .floatToIntBits(NEXTAFTER_FD_START_CASES[i][2]);
+
+            for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+                final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+                final int resultBits = Float.floatToIntBits(Math.nextAfter(
+                        start, direction));
+                if (direction > start) {
+                    assertEquals("Result should be next up-number.",
+                            nextUpBits, resultBits);
+                } else if (direction < start) {
+                    assertEquals("Result should be next down-number.",
+                            nextDownBits, resultBits);
+                } else {
+                    final int equivalentBits = Float.floatToIntBits(new Float(
+                            direction));
+                    assertEquals(
+                            "Result should be a number equivalent to direction.",
+                            equivalentBits, resultBits);
+                }
+            }
+        }
+
+        // test for cases with NaN
+        for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+                    NEXTAFTER_FD_START_CASES[i][0], Float.NaN)));
+        }
+        for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+                    Float.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+        }
+        assertTrue("The result should be NaN.", Float.isNaN(Math.nextAfter(
+                Float.NaN, Float.NaN)));
+
+        // test for exception
+        try {
+            Math.nextAfter((Float) null, 2.3);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.nextAfter(2.3, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.nextAfter((Float) null, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.Math#max(int, int)
+     * @tests {@link java.lang.Math#nextUp(double)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {int.class, int.class}
-    )    
-    public void test_maxII() {
-        // Test for method int java.lang.Math.max(int, int)
-        assertEquals("Incorrect int max value",
-                19088976, Math.max(-19088976, 19088976));
-        assertEquals("Incorrect int max value",
-                19088976, Math.max(20, 19088976));
-        assertEquals("Incorrect int max value", -20, Math.max(-20, -19088976));
+    @SuppressWarnings("boxing")
+    public void test_nextUp_D() {
+        // This method is semantically equivalent to nextAfter(d,
+        // Double.POSITIVE_INFINITY),
+        // so we use the data of test_nextAfter_DD
+        for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+            final double start = NEXTAFTER_DD_START_CASES[i][0];
+            final long nextUpBits = Double
+                    .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+            final long resultBits = Double.doubleToLongBits(Math.nextUp(start));
+            assertEquals("Result should be next up-number.", nextUpBits,
+                    resultBits);
+        }
+
+        // test for cases with NaN
+        assertTrue("The result should be NaN.", Double.isNaN(Math
+                .nextUp(Double.NaN)));
+
+        // test for exception
+        try {
+            Math.nextUp((Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.Math#max(long, long)
+     * @tests {@link java.lang.Math#nextUp(float)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {long.class, long.class}
-    )        
-    public void test_maxJJ() {
-        // Test for method long java.lang.Math.max(long, long)
-        assertEquals("Incorrect long max value", 19088976000089L, Math.max(-19088976000089L,
-                19088976000089L));
-        assertEquals("Incorrect long max value",
-                19088976000089L, Math.max(20, 19088976000089L));
-        assertEquals("Incorrect long max value",
-                -20, Math.max(-20, -19088976000089L));
+    @SuppressWarnings("boxing")
+    public void test_nextUp_F() {
+        // This method is semantically equivalent to nextAfter(f,
+        // Float.POSITIVE_INFINITY),
+        // so we use the data of test_nextAfter_FD
+        for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+            final float start = NEXTAFTER_FD_START_CASES[i][0];
+            final int nextUpBits = Float
+                    .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+            final int resultBits = Float.floatToIntBits(Math.nextUp(start));
+            assertEquals("Result should be next up-number.", nextUpBits,
+                    resultBits);
+        }
+
+        // test for cases with NaN
+        assertTrue("The result should be NaN.", Float.isNaN(Math
+                .nextUp(Float.NaN)));
+
+        // test for exception
+        try {
+            Math.nextUp((Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
-    /**
-     * @tests java.lang.Math#min(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {double.class, double.class}
-    )
-    public void test_minDD() {
-        // Test for method double java.lang.Math.min(double, double)
-        assertEquals("Incorrect double min value", -1908897.6000089, Math.min(-1908897.6000089,
-                1908897.6000089), 0D);
-        assertEquals("Incorrect double min value",
-                2.0, Math.min(2.0, 1908897.6000089), 0D);
-        assertEquals("Incorrect double min value", -1908897.6000089, Math.min(-2.0,
-                -1908897.6000089), 0D);
-        assertEquals("Incorrect returned value", Double.NaN, 
-                Math.min(-1.0, Double.NaN));
-        assertEquals("Incorrect returned value", Double.NaN, 
-                Math.min(Double.NaN, -1.0));
-        assertEquals("Incorrect returned value", -0.0, Math.min(0.0, -0.0));        
-    }
+	/**
+	 * @tests java.lang.Math#pow(double, double)
+	 */
+	public void test_powDD() {
+		// Test for method double java.lang.Math.pow(double, double)
+        double NZERO = longTodouble(doubleTolong(0.0) ^ 0x8000000000000000L);
+        double p1 = 1.0;
+        double p2 = 2.0;
+        double p3 = 3.0;
+        double p4 = 4.0;
+        double p5 = 5.0;
+        double p6 = 6.0;
+        double p7 = 7.0;
+        double p8 = 8.0;
+        double p9 = 9.0;
+        double p10 = 10.0;
+        double p11 = 11.0;
+        double p12 = 12.0;
+        double p13 = 13.0;
+        double p14 = 14.0;
+        double p15 = 15.0;
+        double p16 = 16.0;
+        double[] values = { p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12,
+                p13, p14, p15, p16 };
 
-    /**
-     * @tests java.lang.Math#min(float, float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {float.class, float.class}
-    )
-    public void test_minFF() {
-        // Test for method float java.lang.Math.min(float, float)
-        assertTrue("Incorrect float min value", Math.min(-1908897.600f,
-                1908897.600f) == -1908897.600f);
-        assertTrue("Incorrect float min value",
-                Math.min(2.0f, 1908897.600f) == 2.0f);
-        assertTrue("Incorrect float min value",
-                Math.min(-2.0f, -1908897.600f) == -1908897.600f);
-        assertEquals("Incorrect returned value", Float.NaN, 
-                Math.min(-1.0f, Float.NaN));
-        assertEquals("Incorrect returned value", Float.NaN, 
-                Math.min(Float.NaN, -1.0f));
-        assertEquals("Incorrect returned value", -0f, Math.min(0f, -0f));        
-    }
+        for (int x = 0; x < values.length; x++) {
+            double dval = values[x];
+            double nagateDval = negateDouble(dval);
+            if (nagateDval == Double.NaN) {
+                continue;
+            }
 
-    /**
-     * @tests java.lang.Math#min(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {int.class, int.class}
-    )
-    public void test_minII() {
-        // Test for method int java.lang.Math.min(int, int)
-        assertEquals("Incorrect int min value",
-                -19088976, Math.min(-19088976, 19088976));
-        assertEquals("Incorrect int min value", 20, Math.min(20, 19088976));
-        assertEquals("Incorrect int min value",
-                -19088976, Math.min(-20, -19088976));
+            // If the second argument is positive or negative zero, then the
+            // result is 1.0.
+            assertEquals("Result should be Math.pow(" + dval
+                    + ",-0.0)=+1.0", 1.0, Math.pow(dval, NZERO));
+            assertEquals("Result should be Math.pow(" + nagateDval
+                    + ",-0.0)=+1.0", 1.0, Math.pow(nagateDval, NZERO));
+            assertEquals("Result should be Math.pow(" + dval
+                    + ",+0.0)=+1.0", 1.0, Math.pow(dval, +0.0));
+            assertEquals("Result should be Math.pow(" + nagateDval
+                    + ",+0.0)=+1.0", 1.0, Math.pow(nagateDval, +0.0));
 
-    }
+            // If the second argument is 1.0, then the result is the same as the
+            // first argument.
+            assertEquals("Result should be Math.pow(" + dval + "," + 1.0 + ")="
+                    + dval, dval, Math.pow(dval, 1.0));
+            assertEquals("Result should be Math.pow(" + nagateDval + "," + 1.0
+                    + ")=" + nagateDval, nagateDval, Math.pow(nagateDval, 1.0));
 
-    /**
-     * @tests java.lang.Math#min(long, long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {long.class, long.class}
-    )
-    public void test_minJJ() {
-        // Test for method long java.lang.Math.min(long, long)
-        assertEquals("Incorrect long min value", -19088976000089L, Math.min(-19088976000089L,
-                19088976000089L));
-        assertEquals("Incorrect long min value",
-                20, Math.min(20, 19088976000089L));
-        assertEquals("Incorrect long min value",
-                -19088976000089L, Math.min(-20, -19088976000089L));
-    }
+            // If the second argument is NaN, then the result is NaN.
+            assertEquals("Result should be Math.pow(" + dval + "," + Double.NaN
+                    + ")=" + Double.NaN,  Double.NaN, Math.pow(dval, Double.NaN));
+            assertEquals("Result should be Math.pow(" + nagateDval + ","
+                    + Double.NaN + ")=" + Double.NaN,  Double.NaN, Math.pow(nagateDval,
+                    Double.NaN));
 
-    /**
-     * @tests java.lang.Math#pow(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pow",
-        args = {double.class, double.class}
-    )
-    public void test_powDD() {
-        // Test for method double java.lang.Math.pow(double, double)
-        assertTrue("pow returned incorrect value",
-                (long) Math.pow(2, 8) == 256l);
-        assertTrue("pow returned incorrect value",
-                Math.pow(2, -8) == 0.00390625d);
-        assertEquals("Incorrect root returned1",
+            if (dval > 1) {
+                // If the first argument is NaN and the second argument is
+                // nonzero,
+                // then the result is NaN.
+                assertEquals("Result should be Math.pow(" + Double.NaN + ","
+                        + dval + ")=" + Double.NaN,  Double.NaN, Math.pow(Double.NaN, dval));
+                assertEquals("Result should be Math.pow(" + Double.NaN + ","
+                        + nagateDval + ")=" + Double.NaN,  Double.NaN, Math.pow(Double.NaN,
+                        nagateDval));
+
+                /*
+                 * If the first argument is positive zero and the second
+                 * argument is greater than zero, or the first argument is
+                 * positive infinity and the second argument is less than zero,
+                 * then the result is positive zero.
+                 */
+                assertEquals("Result should be Math.pow(" + 0.0 + "," + dval
+                        + ")=" + 0.0, +0.0, Math.pow(0.0, dval));
+                assertEquals("Result should be Math.pow("
+                        + Double.POSITIVE_INFINITY + "," + nagateDval + ")="
+                        + 0.0, +0.0, Math.pow(Double.POSITIVE_INFINITY, nagateDval));
+
+                /*
+                 * If the first argument is positive zero and the second
+                 * argument is less than zero, or the first argument is positive
+                 * infinity and the second argument is greater than zero, then
+                 * the result is positive infinity.
+                 */
+                assertEquals("Result should be Math.pow(" + 0.0 + ","
+                        + nagateDval + ")=" + Double.POSITIVE_INFINITY,Double.POSITIVE_INFINITY,
+                        Math.pow(0.0, nagateDval));
+                assertEquals("Result should be Math.pow("
+                        + Double.POSITIVE_INFINITY + "," + dval + ")="
+                        + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(
+                        Double.POSITIVE_INFINITY, dval));
+
+                // Not a finite odd integer
+                if (dval % 2 == 0) {
+                    /*
+                     * If the first argument is negative zero and the second
+                     * argument is greater than zero but not a finite odd
+                     * integer, or the first argument is negative infinity and
+                     * the second argument is less than zero but not a finite
+                     * odd integer, then the result is positive zero.
+                     */
+                    assertEquals("Result should be Math.pow(" + NZERO + ","
+                            + dval + ")=" + 0.0, +0.0, Math.pow(NZERO, dval));
+                    assertEquals("Result should be Math.pow("
+                            + Double.NEGATIVE_INFINITY + "," + nagateDval
+                            + ")=" + 0.0, +0.0, Math.pow(Double.NEGATIVE_INFINITY,
+                            nagateDval));
+
+                    /*
+                     * If the first argument is negative zero and the second
+                     * argument is less than zero but not a finite odd integer,
+                     * or the first argument is negative infinity and the second
+                     * argument is greater than zero but not a finite odd
+                     * integer, then the result is positive infinity.
+                     */
+                    assertEquals("Result should be Math.pow(" + NZERO + ","
+                            + nagateDval + ")=" + Double.POSITIVE_INFINITY,Double.POSITIVE_INFINITY,
+                            Math.pow(NZERO, nagateDval));
+                    assertEquals("Result should be Math.pow("
+                            + Double.NEGATIVE_INFINITY + "," + dval + ")="
+                            + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(
+                            Double.NEGATIVE_INFINITY, dval));
+                }
+
+                // finite odd integer
+                if (dval % 2 != 0) {
+                    /*
+                     * If the first argument is negative zero and the second
+                     * argument is a positive finite odd integer, or the first
+                     * argument is negative infinity and the second argument is
+                     * a negative finite odd integer, then the result is
+                     * negative zero.
+                     */
+                    assertEquals("Result should be Math.pow(" + NZERO + ","
+                            + dval + ")=" + NZERO, NZERO, Math.pow(NZERO, dval));
+                    assertEquals("Result should be Math.pow("
+                            + Double.NEGATIVE_INFINITY + "," + nagateDval
+                            + ")=" + NZERO, NZERO, Math.pow(Double.NEGATIVE_INFINITY,
+                            nagateDval));
+                    /*
+                     * If the first argument is negative zero and the second
+                     * argument is a negative finite odd integer, or the first
+                     * argument is negative infinity and the second argument is
+                     * a positive finite odd integer then the result is negative
+                     * infinity.
+                     */
+                    assertEquals("Result should be Math.pow(" + NZERO + ","
+                            + nagateDval + ")=" + Double.NEGATIVE_INFINITY,Double.NEGATIVE_INFINITY,
+                            Math.pow(NZERO, nagateDval));
+                    assertEquals("Result should be Math.pow("
+                            + Double.NEGATIVE_INFINITY + "," + dval + ")="
+                            + Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Math.pow(
+                            Double.NEGATIVE_INFINITY, dval));
+                }
+
+                /**
+                 * 1. If the first argument is finite and less than zero if the
+                 * second argument is a finite even integer, the result is equal
+                 * to the result of raising the absolute value of the first
+                 * argument to the power of the second argument 
+                 * 
+                 * 2. if the second argument is a finite odd integer, the result is equal to the
+                 * negative of the result of raising the absolute value of the
+                 * first argument to the power of the second argument 
+                 * 
+                 * 3. if the second argument is finite and not an integer, then the result
+                 * is NaN.
+                 */
+                for (int j = 1; j < values.length; j++) {
+                    double jval = values[j];
+                    if (jval % 2.0 == 0.0) {
+                        assertEquals("" + nagateDval + " " + jval, Math.pow(
+                                dval, jval), Math.pow(nagateDval, jval));
+                    } else {
+                        assertEquals("" + nagateDval + " " + jval, -1.0
+                                * Math.pow(dval, jval), Math.pow(nagateDval,
+                                jval));
+                    }
+                    assertEquals(Double.NaN, Math
+                            .pow(nagateDval, jval / 0.5467));
+                    assertEquals(Double.NaN, Math.pow(nagateDval, -1.0 * jval
+                            / 0.5467));
+                }
+            }
+
+            // If the absolute value of the first argument equals 1 and the
+            // second argument is infinite, then the result is NaN.
+            if (dval == 1) {
+                assertEquals("Result should be Math.pow(" + dval + ","
+                        + Double.POSITIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+                        .pow(dval, Double.POSITIVE_INFINITY));
+                assertEquals("Result should be Math.pow(" + dval + ","
+                        + Double.NEGATIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+                        .pow(dval, Double.NEGATIVE_INFINITY));
+
+                assertEquals("Result should be Math.pow(" + nagateDval + ","
+                        + Double.POSITIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+                        .pow(nagateDval, Double.POSITIVE_INFINITY));
+                assertEquals("Result should be Math.pow(" + nagateDval + ","
+                        + Double.NEGATIVE_INFINITY + ")=" + Double.NaN, Double.NaN, Math
+                        .pow(nagateDval, Double.NEGATIVE_INFINITY));
+            }
+
+            if (dval > 1) {
+                /*
+                 * If the absolute value of the first argument is greater than 1
+                 * and the second argument is positive infinity, or the absolute
+                 * value of the first argument is less than 1 and the second
+                 * argument is negative infinity, then the result is positive
+                 * infinity.
+                 */
+                assertEquals("Result should be Math.pow(" + dval + ","
+                        + Double.POSITIVE_INFINITY + ")="
+                        + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(dval,
+                        Double.POSITIVE_INFINITY));
+
+                assertEquals("Result should be Math.pow(" + nagateDval + ","
+                        + Double.NEGATIVE_INFINITY + ")="
+                        + Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Math.pow(-0.13456,
+                        Double.NEGATIVE_INFINITY));
+
+                /*
+                 * If the absolute value of the first argument is greater than 1
+                 * and the second argument is negative infinity, or the absolute
+                 * value of the first argument is less than 1 and the second
+                 * argument is positive infinity, then the result is positive
+                 * zero.
+                 */
+                assertEquals("Result should be Math.pow(" + dval + ","
+                        + Double.NEGATIVE_INFINITY + ")= +0.0", +0.0, Math.pow(dval,
+                        Double.NEGATIVE_INFINITY));
+                assertEquals("Result should be Math.pow(" + nagateDval + ","
+                        + Double.POSITIVE_INFINITY + ")= +0.0", +0.0, Math.pow(
+                        -0.13456, Double.POSITIVE_INFINITY));
+            }
+
+            assertEquals("Result should be Math.pow(" + 0.0 + "," + dval + ")="
+                    + 0.0, 0.0, Math.pow(0.0, dval));
+            assertEquals("Result should be Math.pow(" + Double.NaN + "," + dval
+                    + ")=" + Double.NaN, Double.NaN, Math.pow(Double.NaN, dval));
+        }
+		assertTrue("pow returned incorrect value",
+				(long) Math.pow(2, 8) == 256l);
+		assertTrue("pow returned incorrect value",
+				Math.pow(2, -8) == 0.00390625d);
+		assertEquals("Incorrect root returned1",
                              2, Math.sqrt(Math.pow(Math.sqrt(2), 4)), 0);
-        
-        assertEquals("pow returned incorrect value", 1.0, Math.pow(1, 0));
-        assertEquals("pow returned incorrect value", 2.0, Math.pow(2, 1));
-        assertEquals("pow returned incorrect value", Double.NaN, 
-                                        Math.pow(Double.MAX_VALUE, Double.NaN)); 
-        assertEquals("pow returned incorrect value", Double.NaN, 
-                                        Math.pow(Double.NaN, Double.MAX_VALUE));        
-        assertEquals("pow returned incorrect value", Double.POSITIVE_INFINITY, 
-                                       Math.pow(1.1, Double.POSITIVE_INFINITY));      
-        assertEquals("pow returned incorrect value", Double.POSITIVE_INFINITY, 
-                                       Math.pow(0.9, Double.NEGATIVE_INFINITY));   
-        
-        assertEquals("pow returned incorrect value", 0.0, 
-                                       Math.pow(1.1, Double.NEGATIVE_INFINITY));
-        assertEquals("pow returned incorrect value", 0.0, 
-                                       Math.pow(0.9, Double.POSITIVE_INFINITY));   
-        
-        assertEquals("pow returned incorrect value", Double.NaN, 
-                                       Math.pow(1.0, Double.NEGATIVE_INFINITY));
-        assertEquals("pow returned incorrect value", Double.NaN, 
-                                       Math.pow(1.0, Double.POSITIVE_INFINITY)); 
 
-        assertEquals("pow returned incorrect value", 0.0, Math.pow(0, 1));
-        assertEquals("pow returned incorrect value", 0.0, 
-                                      Math.pow(Double.POSITIVE_INFINITY, -0.1));
+		assertEquals(Double.NEGATIVE_INFINITY, Math.pow(-10.0, 3.093403029238847E15));
+		assertEquals(Double.POSITIVE_INFINITY, Math.pow(10.0, 3.093403029238847E15));
+	}
+
+    private double longTodouble(long longvalue) {
+        return Double.longBitsToDouble(longvalue);
+    }
+
+    private long doubleTolong(double doublevalue) {
+        return Double.doubleToLongBits(doublevalue);
+    }
+
+    private double negateDouble(double doublevalue) {
+        return doublevalue * -1.0;
+    }
+
+	/**
+	 * @tests java.lang.Math#rint(double)
+	 */
+	public void test_rintD() {
+		// Test for method double java.lang.Math.rint(double)
+		assertEquals("Failed to round properly - up to odd",
+				3.0, Math.rint(2.9), 0D);
+		assertTrue("Failed to round properly - NaN", Double.isNaN(Math
+				.rint(Double.NaN)));
+		assertEquals("Failed to round properly down  to even",
+				2.0, Math.rint(2.1), 0D);
+		assertTrue("Failed to round properly " + 2.5 + " to even", Math
+				.rint(2.5) == 2.0);
+                assertTrue("Failed to round properly " + (+0.0d),
+                        Math.rint(+0.0d) == +0.0d);
+                assertTrue("Failed to round properly " + (-0.0d),
+                        Math.rint(-0.0d) == -0.0d);
+	}
+
+	/**
+	 * @tests java.lang.Math#round(double)
+	 */
+	public void test_roundD() {
+		// Test for method long java.lang.Math.round(double)
+		assertEquals("Incorrect rounding of a float", -91, Math.round(-90.89d));
+	}
+
+	/**
+	 * @tests java.lang.Math#round(float)
+	 */
+	public void test_roundF() {
+		// Test for method int java.lang.Math.round(float)
+		assertEquals("Incorrect rounding of a float", -91, Math.round(-90.89f));
+	}
+	
+	/**
+     * @tests {@link java.lang.Math#scalb(double, int)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_scalb_DI() {
+        // result is normal
+        assertEquals(4.1422946304E7, Math.scalb(1.2345, 25));
+        assertEquals(3.679096698760986E-8, Math.scalb(1.2345, -25));
+        assertEquals(1.2345, Math.scalb(1.2345, 0));
+        assertEquals(7868514.304, Math.scalb(0.2345, 25));
+
+        double normal = Math.scalb(0.2345, -25);
+        assertEquals(6.98864459991455E-9, normal);
+        // precision kept
+        assertEquals(0.2345, Math.scalb(normal, 25));
+
+        assertEquals(0.2345, Math.scalb(0.2345, 0));
+        assertEquals(-4.1422946304E7, Math.scalb(-1.2345, 25));
+        assertEquals(-6.98864459991455E-9, Math.scalb(-0.2345, -25));
+        assertEquals(2.0, Math.scalb(Double.MIN_NORMAL / 2, 1024));
+        assertEquals(64.0, Math.scalb(Double.MIN_VALUE, 1080));
+        assertEquals(234, Math.getExponent(Math.scalb(1.0, 234)));
+        assertEquals(3.9999999999999996, Math.scalb(Double.MAX_VALUE,
+                Double.MIN_EXPONENT));
+
+        // result is near infinity
+        double halfMax = Math.scalb(1.0, Double.MAX_EXPONENT);
+        assertEquals(8.98846567431158E307, halfMax);
+        assertEquals(Double.MAX_VALUE, halfMax - Math.ulp(halfMax) + halfMax);
+        assertEquals(Double.POSITIVE_INFINITY, halfMax + halfMax);
+        assertEquals(1.7976931348623155E308, Math.scalb(1.0 - Math.ulp(1.0),
+                Double.MAX_EXPONENT + 1));
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(1.0 - Math.ulp(1.0),
+                Double.MAX_EXPONENT + 2));
+
+        halfMax = Math.scalb(-1.0, Double.MAX_EXPONENT);
+        assertEquals(-8.98846567431158E307, halfMax);
+        assertEquals(-Double.MAX_VALUE, halfMax + Math.ulp(halfMax) + halfMax);
+        assertEquals(Double.NEGATIVE_INFINITY, halfMax + halfMax);
+
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(0.345, 1234));
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(44.345E102, 934));
+        assertEquals(Double.NEGATIVE_INFINITY, Math.scalb(-44.345E102, 934));
+
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(
+                Double.MIN_NORMAL / 2, 4000));
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(Double.MIN_VALUE,
+                8000));
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(Double.MAX_VALUE, 1));
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(
+                Double.POSITIVE_INFINITY, 0));
+        assertEquals(Double.POSITIVE_INFINITY, Math.scalb(
+                Double.POSITIVE_INFINITY, -1));
+        assertEquals(Double.NEGATIVE_INFINITY, Math.scalb(
+                Double.NEGATIVE_INFINITY, -1));
+        assertEquals(Double.NEGATIVE_INFINITY, Math.scalb(
+                Double.NEGATIVE_INFINITY, Double.MIN_EXPONENT));
+
+        // result is subnormal/zero
+        long posZeroBits = Double.doubleToLongBits(+0.0);
+        long negZeroBits = Double.doubleToLongBits(-0.0);
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(+0.0,
+                Integer.MAX_VALUE)));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math
+                .scalb(+0.0, -123)));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(+0.0, 0)));
+        assertEquals(negZeroBits, Double
+                .doubleToLongBits(Math.scalb(-0.0, 123)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(-0.0,
+                Integer.MIN_VALUE)));
+
+        assertEquals(Double.MIN_VALUE, Math.scalb(1.0, -1074));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math
+                .scalb(1.0, -1075)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(-1.0,
+                -1075)));
+
+        // precision lost
+        assertEquals(Math.scalb(21.405, -1078), Math.scalb(21.405, -1079));
+        assertEquals(Double.MIN_VALUE, Math.scalb(21.405, -1079));
+        assertEquals(-Double.MIN_VALUE, Math.scalb(-21.405, -1079));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(21.405,
+                -1080)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(-21.405,
+                -1080)));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+                Double.MIN_VALUE, -1)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+                -Double.MIN_VALUE, -1)));
+        assertEquals(Double.MIN_VALUE, Math.scalb(Double.MIN_NORMAL, -52));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+                Double.MIN_NORMAL, -53)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+                -Double.MIN_NORMAL, -53)));
+        assertEquals(Double.MIN_VALUE, Math.scalb(Double.MAX_VALUE, -2098));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+                Double.MAX_VALUE, -2099)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+                -Double.MAX_VALUE, -2099)));
+        assertEquals(Double.MIN_VALUE, Math.scalb(Double.MIN_NORMAL / 3, -51));
+        assertEquals(posZeroBits, Double.doubleToLongBits(Math.scalb(
+                Double.MIN_NORMAL / 3, -52)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(Math.scalb(
+                -Double.MIN_NORMAL / 3, -52)));
+        double subnormal = Math.scalb(Double.MIN_NORMAL / 3, -25);
+        assertEquals(2.2104123E-316, subnormal);
+        // precision lost
+        assertFalse(Double.MIN_NORMAL / 3 == Math.scalb(subnormal, 25));
+
+        // NaN
+        assertTrue(Double.isNaN(Math.scalb(Double.NaN, 1)));
+        assertTrue(Double.isNaN(Math.scalb(Double.NaN, 0)));
+        assertTrue(Double.isNaN(Math.scalb(Double.NaN, -120)));
+
+        assertEquals(1283457024, Double.doubleToLongBits(Math.scalb(
+                Double.MIN_VALUE * 153, 23)));
+        assertEquals(-9223372035571318784L, Double.doubleToLongBits(Math.scalb(
+                -Double.MIN_VALUE * 153, 23)));
+        assertEquals(36908406321184768L, Double.doubleToLongBits(Math.scalb(
+                Double.MIN_VALUE * 153, 52)));
+        assertEquals(-9186463630533591040L, Double.doubleToLongBits(Math.scalb(
+                -Double.MIN_VALUE * 153, 52)));
+
+        // test for exception
+        try {
+            Math.scalb((Double) null, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.scalb(1.0, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.scalb((Double) null, 1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
         
-        assertEquals("pow returned incorrect value", Double.POSITIVE_INFINITY, 
-                                                               Math.pow(0, -1));
-        assertEquals("pow returned incorrect value", Double.POSITIVE_INFINITY, 
-                                         Math.pow(Double.POSITIVE_INFINITY, 1));
-        
-        assertEquals("pow returned incorrect value", 0.0, 
-                                                           Math.pow(-0.0, 0.9));
-        assertEquals("pow returned incorrect value", 0.0, 
-                                      Math.pow(Double.NEGATIVE_INFINITY, -0.9));
-        
-        assertEquals("pow returned incorrect value", -0.0, 
-                                                             Math.pow(-0.0, 1));
-        assertEquals("pow returned incorrect value", -0.0, 
-                                        Math.pow(Double.NEGATIVE_INFINITY, -1));  
-        
-        assertEquals("pow returned incorrect value", Double.POSITIVE_INFINITY, 
-                                                          Math.pow(-0.0, -0.9));
-        assertEquals("pow returned incorrect value", Double.POSITIVE_INFINITY, 
-                                       Math.pow(Double.NEGATIVE_INFINITY, 0.9));  
-        
-        assertEquals("pow returned incorrect value", Double.NEGATIVE_INFINITY, 
-                                                            Math.pow(-0.0, -1));
-        assertEquals("pow returned incorrect value", Double.NEGATIVE_INFINITY, 
-                                         Math.pow(Double.NEGATIVE_INFINITY, 1));   
-        
-        assertEquals("pow returned incorrect value", 0.81, Math.pow(-0.9, 2));  
-        assertEquals("pow returned incorrect value", -0.9, Math.pow(-0.9, 1)); 
-        assertEquals("pow returned incorrect value", Double.NaN, 
-                                                           Math.pow(-0.9, 0.1));
+        long b1em1022 = 0x0010000000000000L; // bit representation of
+                                                // Double.MIN_NORMAL
+        long b1em1023 = 0x0008000000000000L; // bit representation of half of
+                                                // Double.MIN_NORMAL
+        // assert exact identity
+        assertEquals(b1em1023, Double.doubleToLongBits(Math.scalb(Double
+                .longBitsToDouble(b1em1022), -1)));
     }
 
     /**
-     * @tests java.lang.Math#rint(double)
+     * @tests {@link java.lang.Math#scalb(float, int)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "rint",
-        args = {double.class}
-    )
-    public void test_rintD() {
-        // Test for method double java.lang.Math.rint(double)
-        assertEquals("Failed to round properly - up to odd",
-                3.0, Math.rint(2.9), 0D);
-        assertTrue("Failed to round properly - NaN", Double.isNaN(Math
-                .rint(Double.NaN)));
-        assertEquals("Failed to round properly down  to even",
-                2.0, Math.rint(2.1), 0D);
-        assertTrue("Failed to round properly " + 2.5 + " to even", Math
-                .rint(2.5) == 2.0);
-    }
+    @SuppressWarnings("boxing")
+    public void test_scalb_FI() {
+        // result is normal
+        assertEquals(4.1422946304E7f, Math.scalb(1.2345f, 25));
+        assertEquals(3.679096698760986E-8f, Math.scalb(1.2345f, -25));
+        assertEquals(1.2345f, Math.scalb(1.2345f, 0));
+        assertEquals(7868514.304f, Math.scalb(0.2345f, 25));
 
-    /**
-     * @tests java.lang.Math#round(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "round",
-        args = {double.class}
-    )
-    public void test_roundD() {
-        // Test for method long java.lang.Math.round(double)
-        assertEquals("Incorrect rounding of a float", -91, Math.round(-90.89d));
-        assertEquals("Incorrect rounding of a float", 0, 
-                                                        Math.round(Double.NaN));
-        assertEquals("Incorrect rounding of a float", Long.MIN_VALUE, 
-                                          Math.round(Double.NEGATIVE_INFINITY));
-        assertEquals("Incorrect rounding of a float", Long.MAX_VALUE, 
-                                          Math.round(Double.POSITIVE_INFINITY));        
-    }
+        float normal = Math.scalb(0.2345f, -25);
+        assertEquals(6.98864459991455E-9f, normal);
+        // precision kept
+        assertEquals(0.2345f, Math.scalb(normal, 25));
 
-    /**
-     * @tests java.lang.Math#round(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "round",
-        args = {float.class}
-    )
-    public void test_roundF() {
-        // Test for method int java.lang.Math.round(float)
-        assertEquals("Incorrect rounding of a float", -91, Math.round(-90.89f));
-        assertEquals("Incorrect rounding of a float", 0, 
-                                                        Math.round(Float.NaN));
-        assertEquals("Incorrect rounding of a float", Integer.MIN_VALUE, 
-                                          Math.round(Float.NEGATIVE_INFINITY));
-        assertEquals("Incorrect rounding of a float", Integer.MAX_VALUE, 
-                                          Math.round(Float.POSITIVE_INFINITY));          
+        assertEquals(0.2345f, Math.scalb(0.2345f, 0));
+        assertEquals(-4.1422946304E7f, Math.scalb(-1.2345f, 25));
+        assertEquals(-6.98864459991455E-9f, Math.scalb(-0.2345f, -25));
+        assertEquals(2.0f, Math.scalb(Float.MIN_NORMAL / 2, 128));
+        assertEquals(64.0f, Math.scalb(Float.MIN_VALUE, 155));
+        assertEquals(34, Math.getExponent(Math.scalb(1.0f, 34)));
+        assertEquals(3.9999998f, Math
+                .scalb(Float.MAX_VALUE, Float.MIN_EXPONENT));
+
+        // result is near infinity
+        float halfMax = Math.scalb(1.0f, Float.MAX_EXPONENT);
+        assertEquals(1.7014118E38f, halfMax);
+        assertEquals(Float.MAX_VALUE, halfMax - Math.ulp(halfMax) + halfMax);
+        assertEquals(Float.POSITIVE_INFINITY, halfMax + halfMax);
+        assertEquals(3.4028233E38f, Math.scalb(1.0f - Math.ulp(1.0f),
+                Float.MAX_EXPONENT + 1));
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(1.0f - Math.ulp(1.0f),
+                Float.MAX_EXPONENT + 2));
+
+        halfMax = Math.scalb(-1.0f, Float.MAX_EXPONENT);
+        assertEquals(-1.7014118E38f, halfMax);
+        assertEquals(-Float.MAX_VALUE, halfMax + Math.ulp(halfMax) + halfMax);
+        assertEquals(Float.NEGATIVE_INFINITY, halfMax + halfMax);
+
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(0.345f, 1234));
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(44.345E10f, 934));
+        assertEquals(Float.NEGATIVE_INFINITY, Math.scalb(-44.345E10f, 934));
+
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(Float.MIN_NORMAL / 2,
+                400));
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(Float.MIN_VALUE, 800));
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(Float.MAX_VALUE, 1));
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(
+                Float.POSITIVE_INFINITY, 0));
+        assertEquals(Float.POSITIVE_INFINITY, Math.scalb(
+                Float.POSITIVE_INFINITY, -1));
+        assertEquals(Float.NEGATIVE_INFINITY, Math.scalb(
+                Float.NEGATIVE_INFINITY, -1));
+        assertEquals(Float.NEGATIVE_INFINITY, Math.scalb(
+                Float.NEGATIVE_INFINITY, Float.MIN_EXPONENT));
+
+        // result is subnormal/zero
+        int posZeroBits = Float.floatToIntBits(+0.0f);
+        int negZeroBits = Float.floatToIntBits(-0.0f);
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(+0.0f,
+                Integer.MAX_VALUE)));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(+0.0f, -123)));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(+0.0f, 0)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-0.0f, 123)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-0.0f,
+                Integer.MIN_VALUE)));
+
+        assertEquals(Float.MIN_VALUE, Math.scalb(1.0f, -149));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(1.0f, -150)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-1.0f, -150)));
+
+        // precision lost
+        assertEquals(Math.scalb(21.405f, -154), Math.scalb(21.405f, -153));
+        assertEquals(Float.MIN_VALUE, Math.scalb(21.405f, -154));
+        assertEquals(-Float.MIN_VALUE, Math.scalb(-21.405f, -154));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math
+                .scalb(21.405f, -155)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(-21.405f,
+                -155)));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+                Float.MIN_VALUE, -1)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+                -Float.MIN_VALUE, -1)));
+        assertEquals(Float.MIN_VALUE, Math.scalb(Float.MIN_NORMAL, -23));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+                Float.MIN_NORMAL, -24)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+                -Float.MIN_NORMAL, -24)));
+        assertEquals(Float.MIN_VALUE, Math.scalb(Float.MAX_VALUE, -277));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+                Float.MAX_VALUE, -278)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+                -Float.MAX_VALUE, -278)));
+        assertEquals(Float.MIN_VALUE, Math.scalb(Float.MIN_NORMAL / 3, -22));
+        assertEquals(posZeroBits, Float.floatToIntBits(Math.scalb(
+                Float.MIN_NORMAL / 3, -23)));
+        assertEquals(negZeroBits, Float.floatToIntBits(Math.scalb(
+                -Float.MIN_NORMAL / 3, -23)));
+        float subnormal = Math.scalb(Float.MIN_NORMAL / 3, -11);
+        assertEquals(1.913E-42f, subnormal);
+        // precision lost
+        assertFalse(Float.MIN_NORMAL / 3 == Math.scalb(subnormal, 11));
+
+        assertEquals(68747264, Float.floatToIntBits(Math.scalb(
+                Float.MIN_VALUE * 153, 23)));
+        assertEquals(-2078736384, Float.floatToIntBits(Math.scalb(
+                -Float.MIN_VALUE * 153, 23)));
+
+        assertEquals(4896, Float.floatToIntBits(Math.scalb(
+                Float.MIN_VALUE * 153, 5)));
+        assertEquals(-2147478752, Float.floatToIntBits(Math.scalb(
+                -Float.MIN_VALUE * 153, 5)));
+
+        // NaN
+        assertTrue(Float.isNaN(Math.scalb(Float.NaN, 1)));
+        assertTrue(Float.isNaN(Math.scalb(Float.NaN, 0)));
+        assertTrue(Float.isNaN(Math.scalb(Float.NaN, -120)));
+
+        // test for exception
+        try {
+            Math.scalb((Float) null, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.scalb(1.0f, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            Math.scalb((Float) null, 1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        
+        int b1em126 = 0x00800000; // bit representation of Float.MIN_NORMAL
+        int b1em127 = 0x00400000; // bit representation of half
+                                    // Float.MIN_NORMAL
+        // assert exact identity
+        assertEquals(b1em127, Float.floatToIntBits(Math.scalb(Float
+                .intBitsToFloat(b1em126), -1)));
     }
     
     /**
      * @tests java.lang.Math#signum(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "signum",
-        args = {double.class}
-    )
     public void test_signum_D() {
         assertTrue(Double.isNaN(Math.signum(Double.NaN)));
         assertTrue(Double.isNaN(Math.signum(Double.NaN)));
@@ -955,12 +1668,6 @@
     /**
      * @tests java.lang.Math#signum(float)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "signum",
-        args = {float.class}
-    )
     public void test_signum_F() {
         assertTrue(Float.isNaN(Math.signum(Float.NaN)));
         assertEquals(Float.floatToIntBits(0.0f), Float
@@ -983,40 +1690,18 @@
         assertEquals(-1.0f, Math.signum(Float.NEGATIVE_INFINITY), 0f);
     }
 
-    /**
+	/**
      * @tests java.lang.Math#sin(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sin",
-        args = {double.class}
-    )
-    public void test_sinD() {
-        // Test for method double java.lang.Math.sin(double)
-        assertEquals("Incorrect answer", 0.0, Math.sin(0), 0D);
-        assertEquals("Incorrect answer", 0.8414709848078965, Math.sin(1), 0D);
-        
-        double [] args = {Double.NaN, Double.POSITIVE_INFINITY, 
-                          Double.NEGATIVE_INFINITY};
-        for(int i = 0; i < args.length; i++) {
-            assertEquals("Incorrest returned value.", Double.NaN, 
-                                                             Math.sin(args[i]));
-        }
-        
-        assertEquals("Incorrest returned value.", 0.0, Math.sin(0.0));
-        assertEquals("Incorrest returned value.", -0.0, Math.sin(-0.0));        
-    }
+	public void test_sinD() {
+		// Test for method double java.lang.Math.sin(double)
+		assertEquals("Incorrect answer", 0.0, Math.sin(0), 0D);
+		assertEquals("Incorrect answer", 0.8414709848078965, Math.sin(1), 0D);
+	}
     
     /**
      * @tests java.lang.Math#sinh(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sinh",
-        args = {double.class}
-    )
     public void test_sinh_D() {
         // Test for special situations
         assertTrue("Should return NaN", Double.isNaN(Math.sinh(Double.NaN)));
@@ -1025,11 +1710,11 @@
         assertEquals("Should return NEGATIVE_INFINITY",
                 Double.NEGATIVE_INFINITY, Math.sinh(Double.NEGATIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
-                .sinh(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(Math.sinh(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(Math.sinh(-0.0)));
+				.sinh(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(Math.sinh(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(Math.sinh(-0.0)));
 
         assertEquals("Should return POSITIVE_INFINITY",
                 Double.POSITIVE_INFINITY, Math.sinh(1234.56), 0D);
@@ -1047,62 +1732,27 @@
                 .sinh(Double.MIN_VALUE), 0D);
     }
     
-    /**
-     * @tests java.lang.Math#sqrt(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sqrt",
-        args = {double.class}
-    )
-    public void test_sqrtD() {
-        // Test for method double java.lang.Math.sqrt(double)
-        assertEquals("Incorrect root returned2", 7, Math.sqrt(49), 0);
-        assertEquals("Incorrect value is returned", Double.NaN, 
-                                                         Math.sqrt(Double.NaN));
-        assertEquals("Incorrect value is returned", Double.NaN, 
-                                                                 Math.sqrt(-1)); 
-        assertEquals("Incorrect value is returned", Double.POSITIVE_INFINITY, 
-                                           Math.sqrt(Double.POSITIVE_INFINITY));
-        assertEquals("Incorrect value is returned", 0.0, Math.sqrt(0.0));         
-        assertEquals("Incorrect value is returned", -0.0, Math.sqrt(-0.0));        
-    }
+	/**
+	 * @tests java.lang.Math#sqrt(double)
+	 */
+	public void test_sqrtD() {
+		// Test for method double java.lang.Math.sqrt(double)
+                assertEquals("Incorrect root returned2", 7, Math.sqrt(49), 0);
+	}
 
-    /**
-     * @tests java.lang.Math#tan(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "tan",
-        args = {double.class}
-    )
-    public void test_tanD() {
-        // Test for method double java.lang.Math.tan(double)
-        assertEquals("Incorrect answer", 0.0, Math.tan(0), 0D);
-        assertEquals("Incorrect answer", 1.5574077246549023, Math.tan(1), 0D);
+	/**
+	 * @tests java.lang.Math#tan(double)
+	 */
+	public void test_tanD() {
+		// Test for method double java.lang.Math.tan(double)
+		assertEquals("Incorrect answer", 0.0, Math.tan(0), 0D);
+		assertEquals("Incorrect answer", 1.5574077246549023, Math.tan(1), 0D);
 
-        double [] args = {Double.NaN, Double.POSITIVE_INFINITY, 
-                                                      Double.NEGATIVE_INFINITY};
-        for(int i = 0; i < args.length; i++) {
-            assertEquals("Incorrest returned value.", Double.NaN, 
-                                                   Math.tan(args[i]));
-        }
-        
-        assertEquals("Incorrest returned value.", 0.0, Math.tan(0.0));
-        assertEquals("Incorrest returned value.", -0.0, Math.tan(-0.0));        
-    }
+	}
 
     /**
      * @tests java.lang.Math#tanh(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "tanh",
-        args = {double.class}
-    )
     public void test_tanh_D() {
         // Test for special situations
         assertTrue("Should return NaN", Double.isNaN(Math.tanh(Double.NaN)));
@@ -1111,11 +1761,11 @@
         assertEquals("Should return -1.0", -1.0, Math
                 .tanh(Double.NEGATIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double.doubleToLongBits(Math
-                .tanh(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(Math.tanh(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(Math.tanh(-0.0)));
+				.tanh(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(Math.tanh(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(Math.tanh(-0.0)));
 
         assertEquals("Should return 1.0", 1.0, Math.tanh(1234.56), 0D);
         assertEquals("Should return -1.0", -1.0, Math.tanh(-1234.56), 0D);
@@ -1128,144 +1778,210 @@
                 .tanh(Double.MIN_VALUE), 0D);
     }
     
-    /**
-     * @tests java.lang.Math#random()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "random",
-        args = {}
-    )
-    public void test_random() {
-        // There isn't a place for these tests so just stick them here
-        assertEquals("Wrong value E",
-                4613303445314885481L, Double.doubleToLongBits(Math.E));
-        assertEquals("Wrong value PI",
-                4614256656552045848L, Double.doubleToLongBits(Math.PI));
+	/**
+	 * @tests java.lang.Math#random()
+	 */
+	public void test_random() {
+		// There isn't a place for these tests so just stick them here
+		assertEquals("Wrong value E",
+				4613303445314885481L, Double.doubleToLongBits(Math.E));
+		assertEquals("Wrong value PI",
+				4614256656552045848L, Double.doubleToLongBits(Math.PI));
 
-        for (int i = 500; i >= 0; i--) {
-            double d = Math.random();
-            assertTrue("Generated number is out of range: " + d, d >= 0.0
-                    && d < 1.0);
-        }
-    }
+		for (int i = 500; i >= 0; i--) {
+			double d = Math.random();
+			assertTrue("Generated number is out of range: " + d, d >= 0.0
+					&& d < 1.0);
+		}
+	}
 
-    /**
-     * @tests java.lang.Math#toRadians(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toRadians",
-        args = {double.class}
-    )
-    public void test_toRadiansD() {
-        for (double d = 500; d >= 0; d -= 1.0) {
-            double converted = Math.toDegrees(Math.toRadians(d));
-            assertTrue("Converted number not equal to original. d = " + d,
-                    converted >= d * 0.99999999 && converted <= d * 1.00000001);
-        }
-    }
+	/**
+	 * @tests java.lang.Math#toRadians(double)
+	 */
+	public void test_toRadiansD() {
+		for (double d = 500; d >= 0; d -= 1.0) {
+			double converted = Math.toDegrees(Math.toRadians(d));
+			assertTrue("Converted number not equal to original. d = " + d,
+					converted >= d * 0.99999999 && converted <= d * 1.00000001);
+		}
+	}
 
-    /**
-     * @tests java.lang.Math#toDegrees(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toDegrees",
-        args = {double.class}
-    )
-    public void test_toDegreesD() {
-        for (double d = 500; d >= 0; d -= 1.0) {
-            double converted = Math.toRadians(Math.toDegrees(d));
-            assertTrue("Converted number not equal to original. d = " + d,
-                    converted >= d * 0.99999999 && converted <= d * 1.00000001);
-        }
-    }
-    
-    /**
+	/**
+	 * @tests java.lang.Math#toDegrees(double)
+	 */
+	public void test_toDegreesD() {
+		for (double d = 500; d >= 0; d -= 1.0) {
+			double converted = Math.toRadians(Math.toDegrees(d));
+			assertTrue("Converted number not equal to original. d = " + d,
+					converted >= d * 0.99999999 && converted <= d * 1.00000001);
+		}
+	}
+	
+	/**
      * @tests java.lang.Math#ulp(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ulp",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_ulp_D() {
-        // Test for special cases
-        assertTrue("Should return NaN", Double.isNaN(Math.ulp(Double.NaN)));
-        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, Math
-                .ulp(Double.POSITIVE_INFINITY), 0D);
-        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, Math
-                .ulp(Double.NEGATIVE_INFINITY), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
-                .ulp(0.0), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
-                .ulp(+0.0), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
-                .ulp(-0.0), 0D);
-        assertEquals("Returned incorrect value", Math.pow(2, 971), Math
-                .ulp(Double.MAX_VALUE), 0D);
-        assertEquals("Returned incorrect value", Math.pow(2, 971), Math
-                .ulp(-Double.MAX_VALUE), 0D);
+		// Test for special cases
+		assertTrue("Should return NaN", Double.isNaN(Math.ulp(Double.NaN)));
+		assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, Math
+				.ulp(Double.POSITIVE_INFINITY), 0D);
+		assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY, Math
+				.ulp(Double.NEGATIVE_INFINITY), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+				.ulp(0.0), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+				.ulp(+0.0), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+				.ulp(-0.0), 0D);
+		assertEquals("Returned incorrect value", Math.pow(2, 971), Math
+				.ulp(Double.MAX_VALUE), 0D);
+		assertEquals("Returned incorrect value", Math.pow(2, 971), Math
+				.ulp(-Double.MAX_VALUE), 0D);
 
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
-                .ulp(Double.MIN_VALUE), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
-                .ulp(-Double.MIN_VALUE), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+				.ulp(Double.MIN_VALUE), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, Math
+				.ulp(-Double.MIN_VALUE), 0D);
 
-        assertEquals("Returned incorrect value", 2.220446049250313E-16, Math
-                .ulp(1.0), 0D);
-        assertEquals("Returned incorrect value", 2.220446049250313E-16, Math
-                .ulp(-1.0), 0D);
-        assertEquals("Returned incorrect value", 2.2737367544323206E-13, Math
-                .ulp(1153.0), 0D);
+		assertEquals("Returned incorrect value", 2.220446049250313E-16, Math
+				.ulp(1.0), 0D);
+		assertEquals("Returned incorrect value", 2.220446049250313E-16, Math
+				.ulp(-1.0), 0D);
+		assertEquals("Returned incorrect value", 2.2737367544323206E-13, Math
+				.ulp(1153.0), 0D);
+	}
+
+	/**
+	 * @tests java.lang.Math#ulp(float)
+	 */
+	@SuppressWarnings("boxing")
+	public void test_ulp_f() {
+		// Test for special cases
+		assertTrue("Should return NaN", Float.isNaN(Math.ulp(Float.NaN)));
+		assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, Math
+				.ulp(Float.POSITIVE_INFINITY), 0f);
+		assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, Math
+				.ulp(Float.NEGATIVE_INFINITY), 0f);
+		assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
+				.ulp(0.0f), 0f);
+		assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
+				.ulp(+0.0f), 0f);
+		assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
+				.ulp(-0.0f), 0f);
+		assertEquals("Returned incorrect value", 2.028241E31f, Math
+				.ulp(Float.MAX_VALUE), 0f);
+		assertEquals("Returned incorrect value", 2.028241E31f, Math
+				.ulp(-Float.MAX_VALUE), 0f);
+
+		assertEquals("Returned incorrect value", 1.4E-45f, Math
+				.ulp(Float.MIN_VALUE), 0f);
+		assertEquals("Returned incorrect value", 1.4E-45f, Math
+				.ulp(-Float.MIN_VALUE), 0f);
+
+		assertEquals("Returned incorrect value", 1.1920929E-7f, Math.ulp(1.0f),
+				0f);
+		assertEquals("Returned incorrect value", 1.1920929E-7f,
+				Math.ulp(-1.0f), 0f);
+		assertEquals("Returned incorrect value", 1.2207031E-4f, Math
+				.ulp(1153.0f), 0f);
+		assertEquals("Returned incorrect value", 5.6E-45f, Math
+				.ulp(9.403954E-38f), 0f);
+    }
+	
+	/**
+     * @tests {@link java.lang.Math#shiftIntBits(int, int)}
+     * 
+     * @since 1.6 
+     */
+    public void test_shiftIntBits_II() {
+        class Tuple {
+            public int result;
+
+            public int value;
+
+            public int factor;
+
+            public Tuple(int result, int value, int factor) {
+                this.result = result;
+                this.value = value;
+                this.factor = factor;
+            }
+        }
+        final Tuple[] TUPLES = new Tuple[] {
+        // sub-normal to sub-normal
+                new Tuple(0x00000000, 0x00000001, -1),
+                // round to even
+                new Tuple(0x00000002, 0x00000003, -1),
+                // round to even
+                new Tuple(0x00000001, 0x00000005, -3),
+                // round to infinity
+                new Tuple(0x00000002, 0x0000000d, -3),
+                // round to infinity
+
+                // normal to sub-normal
+                new Tuple(0x00000002, 0x01a00000, -24),
+                // round to even 
+                new Tuple(0x00000004, 0x01e00000, -24),
+                // round to even
+                new Tuple(0x00000003, 0x01c80000, -24),
+                // round to infinity
+                new Tuple(0x00000004, 0x01e80000, -24),
+        // round to infinity
+        };
+        for (int i = 0; i < TUPLES.length; ++i) {
+            Tuple tuple = TUPLES[i];
+            assertEquals(tuple.result, Float.floatToIntBits(Math.scalb(Float
+                    .intBitsToFloat(tuple.value), tuple.factor)));
+            assertEquals(tuple.result, Float.floatToIntBits(-Math.scalb(-Float
+                    .intBitsToFloat(tuple.value), tuple.factor)));
+        }
     }
 
     /**
-     * @tests java.lang.Math#ulp(float)
+     * @tests {@link java.lang.Math#shiftLongBits(long, long)}
+     * 
+     * Round result to nearest value on precision lost.
+     * 
+     * @since 1.6 
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ulp",
-        args = {float.class}
-    )
-    @SuppressWarnings("boxing")
-    public void test_ulp_f() {
-        // Test for special cases
-        assertTrue("Should return NaN", Float.isNaN(Math.ulp(Float.NaN)));
-        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, Math
-                .ulp(Float.POSITIVE_INFINITY), 0f);
-        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY, Math
-                .ulp(Float.NEGATIVE_INFINITY), 0f);
-        assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
-                .ulp(0.0f), 0f);
-        assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
-                .ulp(+0.0f), 0f);
-        assertEquals("Returned incorrect value", Float.MIN_VALUE, Math
-                .ulp(-0.0f), 0f);
-        assertEquals("Returned incorrect value", 2.028241E31f, Math
-                .ulp(Float.MAX_VALUE), 0f);
-        assertEquals("Returned incorrect value", 2.028241E31f, Math
-                .ulp(-Float.MAX_VALUE), 0f);
+    public void test_shiftLongBits_LL() {
+        class Tuple {
+            public long result;
 
-        assertEquals("Returned incorrect value", 1.4E-45f, Math
-                .ulp(Float.MIN_VALUE), 0f);
-        assertEquals("Returned incorrect value", 1.4E-45f, Math
-                .ulp(-Float.MIN_VALUE), 0f);
+            public long value;
 
-        assertEquals("Returned incorrect value", 1.1920929E-7f, Math.ulp(1.0f),
-                0f);
-        assertEquals("Returned incorrect value", 1.1920929E-7f,
-                Math.ulp(-1.0f), 0f);
-        assertEquals("Returned incorrect value", 1.2207031E-4f, Math
-                .ulp(1153.0f), 0f);
-        assertEquals("Returned incorrect value", 5.6E-45f, Math
-                .ulp(9.403954E-38f), 0f);
+            public int factor;
+
+            public Tuple(long result, long value, int factor) {
+                this.result = result;
+                this.value = value;
+                this.factor = factor;
+            }
+        }
+        final Tuple[] TUPLES = new Tuple[] {
+        // sub-normal to sub-normal
+                new Tuple(0x00000000L, 0x00000001L, -1),
+                //round to even
+                new Tuple(0x00000002L, 0x00000003L, -1),
+                //round to even
+                new Tuple(0x00000001L, 0x00000005L, -3),
+                //round to infinity
+                new Tuple(0x00000002L, 0x0000000dL, -3),
+                //round to infinity
+
+                // normal to sub-normal
+                new Tuple(0x0000000000000002L, 0x0034000000000000L, -53), // round to even
+                new Tuple(0x0000000000000004L, 0x003c000000000000L, -53), // round to even
+                new Tuple(0x0000000000000003L, 0x0035000000000000L, -53), // round to infinity
+                new Tuple(0x0000000000000004L, 0x003d000000000000L, -53), // round to infinity
+        };
+        for (int i = 0; i < TUPLES.length; ++i) {
+            Tuple tuple = TUPLES[i];
+            assertEquals(tuple.result, Double.doubleToLongBits(Math.scalb(
+                    Double.longBitsToDouble(tuple.value), tuple.factor)));
+            assertEquals(tuple.result, Double.doubleToLongBits(-Math.scalb(
+                    -Double.longBitsToDouble(tuple.value), tuple.factor)));
+        }
     }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NegativeArraySizeExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NegativeArraySizeExceptionTest.java
index ef1c9a6..93b6dbd 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NegativeArraySizeExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NegativeArraySizeExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NegativeArraySizeException.class) 
 public class NegativeArraySizeExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.NegativeArraySizeException#NegativeArraySizeException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NegativeArraySizeException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NegativeArraySizeException#NegativeArraySizeException()
+	 */
     public void test_Constructor() {
         NegativeArraySizeException e = new NegativeArraySizeException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NegativeArraySizeException#NegativeArraySizeException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NegativeArraySizeException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NegativeArraySizeException e = new NegativeArraySizeException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoClassDefFoundErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoClassDefFoundErrorTest.java
index 9c76a56..db7dced 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoClassDefFoundErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoClassDefFoundErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NoClassDefFoundError.class) 
 public class NoClassDefFoundErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.NoClassDefFoundError#NoClassDefFoundError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoClassDefFoundError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NoClassDefFoundError#NoClassDefFoundError()
+	 */
     public void test_Constructor() {
         NoClassDefFoundError e = new NoClassDefFoundError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NoClassDefFoundError#NoClassDefFoundError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoClassDefFoundError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NoClassDefFoundError e = new NoClassDefFoundError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldErrorTest.java
index 0ca4f41..88889e5 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NoSuchFieldError.class) 
 public class NoSuchFieldErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.NoSuchFieldError#NoSuchFieldError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchFieldError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NoSuchFieldError#NoSuchFieldError()
+	 */
     public void test_Constructor() {
         NoSuchFieldError e = new NoSuchFieldError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NoSuchFieldError#NoSuchFieldError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchFieldError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NoSuchFieldError e = new NoSuchFieldError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldExceptionTest.java
index 135fdb5..5902d86 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchFieldExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NoSuchFieldException.class) 
 public class NoSuchFieldExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.NoSuchFieldException#NoSuchFieldException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchFieldException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NoSuchFieldException#NoSuchFieldException()
+	 */
     public void test_Constructor() {
         NoSuchFieldException e = new NoSuchFieldException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NoSuchFieldException#NoSuchFieldException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchFieldException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NoSuchFieldException e = new NoSuchFieldException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodErrorTest.java
index 5c8a462..b7e711b 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NoSuchMethodError.class) 
 public class NoSuchMethodErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.NoSuchMethodError#NoSuchMethodError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchMethodError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NoSuchMethodError#NoSuchMethodError()
+	 */
     public void test_Constructor() {
         NoSuchMethodError e = new NoSuchMethodError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NoSuchMethodError#NoSuchMethodError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchMethodError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NoSuchMethodError e = new NoSuchMethodError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodExceptionTest.java
index 8e01984..68d46a2 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NoSuchMethodExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NoSuchMethodException.class) 
 public class NoSuchMethodExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.NoSuchMethodException#NoSuchMethodException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchMethodException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NoSuchMethodException#NoSuchMethodException()
+	 */
     public void test_Constructor() {
         NoSuchMethodException e = new NoSuchMethodException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NoSuchMethodException#NoSuchMethodException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NoSuchMethodException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NoSuchMethodException e = new NoSuchMethodException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NullPointerExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NullPointerExceptionTest.java
index f1c870d..a3df668 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NullPointerExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NullPointerExceptionTest.java
@@ -16,25 +16,13 @@
  */
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NullPointerException.class) 
 public class NullPointerExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.NullPointerException#NullPointerException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NullPointerException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NullPointerException#NullPointerException()
+	 */
     public void test_Constructor() {
         NullPointerException e = new NullPointerException();
         assertNull(e.getMessage());
@@ -45,12 +33,6 @@
     /**
      * @tests java.lang.NullPointerException#NullPointerException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NullPointerException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NullPointerException e = new NullPointerException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberFormatExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberFormatExceptionTest.java
index 579b0b9..3cdf445 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberFormatExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberFormatExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(NumberFormatException.class) 
 public class NumberFormatExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.NumberFormatException#NumberFormatException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NumberFormatException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.NumberFormatException#NumberFormatException()
+	 */
     public void test_Constructor() {
         NumberFormatException e = new NumberFormatException();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.NumberFormatException#NumberFormatException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NumberFormatException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         NumberFormatException e = new NumberFormatException("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberTest.java
index d1caf92..5b7d7f7 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/NumberTest.java
@@ -17,108 +17,50 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-@TestTargetClass(Number.class) 
 public class NumberTest extends junit.framework.TestCase {
-    
-    class MockNumber extends Number {
 
-        @Override
-        public double doubleValue() {
-            // TODO Auto-generated method stub
-            return 0;
-        }
+	/**
+	 * @tests java.lang.Number#byteValue()
+	 */
+	public void test_byteValue() {
+		int number = 1231243;
+		assertTrue("Incorrect byte returned for: " + number,
+				((byte) new Integer(number).intValue()) == new Integer(number)
+						.byteValue());
+		number = 0;
+		assertTrue("Incorrect byte returned for: " + number,
+				((byte) new Integer(number).intValue()) == new Integer(number)
+						.byteValue());
+		number = -1;
+		assertTrue("Incorrect byte returned for: " + number,
+				((byte) new Integer(number).intValue()) == new Integer(number)
+						.byteValue());
+		number = -84109328;
+		assertTrue("Incorrect byte returned for: " + number,
+				((byte) new Integer(number).intValue()) == new Integer(number)
+						.byteValue());
+	}
 
-        @Override
-        public float floatValue() {
-            // TODO Auto-generated method stub
-            return 0;
-        }
+	/**
+	 * @tests java.lang.Number#shortValue()
+	 */
+	public void test_shortValue() {
+		int number = 1231243;
+		assertTrue("Incorrect byte returned for: " + number,
+				((short) new Integer(number).intValue()) == new Integer(number)
+						.shortValue());
+		number = 0;
+		assertTrue("Incorrect byte returned for: " + number,
+				((short) new Integer(number).intValue()) == new Integer(number)
+						.shortValue());
+		number = -1;
+		assertTrue("Incorrect byte returned for: " + number,
+				((short) new Integer(number).intValue()) == new Integer(number)
+						.shortValue());
+		number = -84109328;
+		assertTrue("Incorrect byte returned for: " + number,
+				((short) new Integer(number).intValue()) == new Integer(number)
+						.shortValue());
 
-        @Override
-        public int intValue() {
-            // TODO Auto-generated method stub
-            return 0;
-        }
-
-        @Override
-        public long longValue() {
-            // TODO Auto-generated method stub
-            return 0;
-        }
-        
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Number",
-        args = {}
-    )
-    public void test_Number() {
-        MockNumber number = new MockNumber();
-        assertEquals(0, number.longValue());
-        assertEquals(0, number.shortValue());
-    }
-    
-    /**
-     * @tests java.lang.Number#byteValue()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "byteValue",
-        args = {}
-    )
-    public void test_byteValue() {
-        int number = 1231243;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((byte) new Integer(number).intValue()) == new Integer(number)
-                        .byteValue());
-        number = 0;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((byte) new Integer(number).intValue()) == new Integer(number)
-                        .byteValue());
-        number = -1;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((byte) new Integer(number).intValue()) == new Integer(number)
-                        .byteValue());
-        number = -84109328;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((byte) new Integer(number).intValue()) == new Integer(number)
-                        .byteValue());
-    }
-
-    /**
-     * @tests java.lang.Number#shortValue()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "shortValue",
-        args = {}
-    )
-    public void test_shortValue() {
-        int number = 1231243;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((short) new Integer(number).intValue()) == new Integer(number)
-                        .shortValue());
-        number = 0;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((short) new Integer(number).intValue()) == new Integer(number)
-                        .shortValue());
-        number = -1;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((short) new Integer(number).intValue()) == new Integer(number)
-                        .shortValue());
-        number = -84109328;
-        assertTrue("Incorrect byte returned for: " + number,
-                ((short) new Integer(number).intValue()) == new Integer(number)
-                        .shortValue());
-
-    }
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/OutOfMemoryErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/OutOfMemoryErrorTest.java
index 4782f1e..a23789b 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/OutOfMemoryErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/OutOfMemoryErrorTest.java
@@ -17,48 +17,30 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-@TestTargetClass(OutOfMemoryError.class) 
 public class OutOfMemoryErrorTest extends junit.framework.TestCase {
 
-    /**
-     * @tests java.lang.OutOfMemoryError#OutOfMemoryError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "OutOfMemoryError",
-        args = {}
-    )
-    public void test_Constructor() {
-        // Test for method java.lang.OutOfMemoryError()
-        Error e = new OutOfMemoryError();
+	/**
+	 * @tests java.lang.OutOfMemoryError#OutOfMemoryError()
+	 */
+	public void test_Constructor() {
+		// Test for method java.lang.OutOfMemoryError()
+	    Error e = new OutOfMemoryError();
         assertNull(e.getCause());
         assertNull(e.getMessage());
-    }
+	}
 
-    /**
-     * @tests java.lang.OutOfMemoryError#OutOfMemoryError(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "OutOfMemoryError",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
-        // Test for method java.lang.OutOfMemoryError(java.lang.String)
-        Error e = new OutOfMemoryError(null);
+	/**
+	 * @tests java.lang.OutOfMemoryError#OutOfMemoryError(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
+		// Test for method java.lang.OutOfMemoryError(java.lang.String)
+		Error e = new OutOfMemoryError(null);
         assertNull(e.getMessage());
         assertNull(e.getCause());
         
         e= new OutOfMemoryError("msg");
         assertEquals("msg", e.getMessage());
         assertNull(e.getCause());
-    }
+	}
 
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
index 283c1db..61dab9a 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/PackageTest.java
@@ -16,48 +16,27 @@
  */
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.File;
+import java.io.InputStream;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.lang.annotation.Annotation;
 
-import java.lang.annotation.Annotation;
-
-import tests.support.Support_ClassLoader;
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(Package.class) 
 public class PackageTest extends junit.framework.TestCase {
 
     private File resources;
 
     private String resPath;
-    
-    Class clazz;
 
     Package getTestPackage(String resourceJar, String className)
             throws Exception {
-        
-        if ("Dalvik".equals(System.getProperty("java.vm.name"))) {
-            resourceJar = resourceJar.substring(0, resourceJar.indexOf(".")) + 
-                                                                    "_dex.jar";
-        }
         Support_Resources.copyFile(resources, "Package", resourceJar);
         URL resourceURL = new URL("file:/" + resPath + "/Package/"
                 + resourceJar);
 
-        ClassLoader cl = Support_ClassLoader.getInstance(resourceURL,
-                getClass().getClassLoader());
-
-       clazz = cl.loadClass(className);
-       return clazz.getPackage();
+        URLClassLoader ucl = new URLClassLoader(new URL[] { resourceURL }, null);
+        return Class.forName(className, true, ucl).getPackage();
     }
 
     @Override
@@ -82,45 +61,6 @@
      * @tests java.lang.Package#getSpecificationVersion()
      * @tests java.lang.Package#getImplementationTitle()
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getImplementationTitle",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getImplementationVendor",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getImplementationVersion",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getSpecificationTitle",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getSpecificationVendor",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getSpecificationVersion",
-            args = {}
-        )
-    })
-    @KnownFailure("get methods don't work.")
     public void test_helper_Attributes() throws Exception {
 
         Package p = getTestPackage("hyts_all_attributes.jar", "p.C");
@@ -231,13 +171,6 @@
     /**
      * @tests java.lang.Package#getName()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getName",
-        args = {}
-    )
-    @BrokenTest("Different behavior between cts host and run-core-test")
     public void test_getName() throws Exception {
         Package p = getTestPackage("hyts_pq.jar", "p.q.C");
         assertEquals("Package getName returns a wrong string", "p.q", p
@@ -247,34 +180,17 @@
     /**
      * @tests java.lang.Package#getPackage(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPackage",
-        args = {java.lang.String.class}
-    )
-    @KnownFailure("Real package information missing on android.")
-    public void test_getPackageLjava_lang_String() throws Exception {
+    public void test_getPackageLjava_lang_String() {
         assertSame("Package getPackage failed for java.lang", Package
                 .getPackage("java.lang"), Package.getPackage("java.lang"));
 
         assertSame("Package getPackage failed for java.lang", Package
                 .getPackage("java.lang"), Object.class.getPackage());
-        
-        Package p = getTestPackage("hyts_package.jar", "C");
-        assertNull("getPackage should return null.", p);
     }
 
     /**
      * @tests java.lang.Package#getPackages()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPackages",
-        args = {}
-    )
-    @KnownFailure("Package information missing on android")
     public void test_getPackages() throws Exception {
         Package[] pckgs = Package.getPackages();
         boolean found = false;
@@ -290,12 +206,6 @@
     /**
      * @tests java.lang.Package#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         Package p1 = Package.getPackage("java.lang");
         if (p1 != null) {
@@ -306,13 +216,6 @@
     /**
      * @tests java.lang.Package#isCompatibleWith(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isCompatibleWith",
-        args = {java.lang.String.class}
-    )
-    @KnownFailure("Dalvik packages are always version '0.0'.")
     public void test_isCompatibleWithLjava_lang_String() throws Exception {
         Package p = getTestPackage("hyts_c.jar", "p.C");
 
@@ -363,31 +266,14 @@
     /**
      * @tests java.lang.Package#isSealed()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isSealed",
-        args = {}
-    )
-    @KnownFailure("isSealed method returns false for sealed package.")    
     public void test_isSealed() throws Exception {
         Package p = getTestPackage("hyts_pq.jar", "p.q.C");
         assertTrue("Package isSealed returns wrong boolean", p.isSealed());
-        
-        p = String.class.getPackage();
-        assertFalse("Package isSealed returns wrong boolean", p.isSealed());
     }
 
     /**
      * @tests java.lang.Package#isSealed(java.net.URL)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isSealed",
-        args = {java.net.URL.class}
-    )
-    @KnownFailure("isSealed method returns false for sealed package.")
     public void test_isSealedLjava_net_URL() throws Exception {
         Package p = getTestPackage("hyts_c.jar", "p.C");
         assertFalse("Package isSealed returns wrong boolean (1)", p
@@ -399,91 +285,106 @@
     /**
      * @tests java.lang.Package#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
-    @BrokenTest("Different behavior between cts host and run-core-test")
     public void test_toString() throws Exception {
         Package p = getTestPackage("hyts_c.jar", "p.C");
         assertTrue("Package toString returns wrong string", p.toString()
                 .length() > 0);
     }
     
-    @SuppressWarnings("unchecked")
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAnnotation",
-        args = {java.lang.Class.class}
-    )
-    @KnownFailure("Class loader can't retrieve information about annotations.")
-    public void test_getAnnotation() throws Exception {
-        String annotationName = "a.b.PackageAnnotation";
-        Package p = getTestPackage("hyts_package.jar", annotationName);
-        assertEquals(annotationName, 
-                p.getAnnotation(clazz).annotationType().getName());
-        assertNull(String.class.getPackage().getAnnotation(Deprecated.class));
-        assertNull(ExtendTestClass.class.getPackage().
-                getAnnotation(Deprecated.class));        
+    public void test_SealedPackage_forName() throws Exception {
+        Support_Resources.copyFile(resources, "Package", "hyts_c.jar");
+        Support_Resources.copyFile(resources, "Package", "hyts_d.jar");
+        Support_Resources.copyFile(resources, "Package", "hyts_d1.jar");
+        Support_Resources.copyFile(resources, "Package", "hyts_d2.jar");
+
+        URL resourceURL1 = new URL("file:/" + resPath + "/Package/hyts_c.jar");
+        URL resourceURL2 = new URL("file:/" + resPath + "/Package/hyts_d.jar");
+        URL resourceURL3 = new URL("file:/" + resPath + "/Package/hyts_d1.jar");
+        URL resourceURL4 = new URL("file:/" + resPath + "/Package/hyts_d2.jar");
+        URL resourceURL5 = new URL("file:/" + resPath + "/");
+
+        URLClassLoader uclClassLoader;
+        // load from the sealed jar, then an unsealed jar with no manifest
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL2 }, null);
+        Class.forName("p.C", true, uclClassLoader);
+        try {
+            Class.forName("p.D", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
+
+        // setup for next test
+        Support_Resources.copyFile(resources, "p", "");
+        InputStream in = uclClassLoader.getResourceAsStream("p/D.class");
+        Support_Resources.copyLocalFileto(new File(resources.toString(),
+                "p/D.class"), in);
+
+        // load from a sealed jar, then the directory
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL5 }, null);
+        Class.forName("p.C", true, uclClassLoader);
+        try {
+            Class.forName("p.D", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
+
+        // load from a directory, then the sealed jar
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL5 }, null);
+        Class.forName("p.D", true, uclClassLoader);
+        try {
+            Class.forName("p.C", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
+
+        // load from an unsealed jar with no manifest, then the sealed jar
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL2 }, null);
+        Class.forName("p.D", true, uclClassLoader);
+        try {
+            Class.forName("p.C", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
+
+        // load from an unsealed jar with a manifest, then the sealed jar
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL3 }, null);
+        Class.forName("p.C", true, uclClassLoader);
+        try {
+            Class.forName("p.D", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
+
+        // load from an sealed jar, then the unsealed jar with a manifest
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL3 }, null);
+        Class.forName("p.D", true, uclClassLoader);
+        try {
+            Class.forName("p.C", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
+
+        // load from the sealed jar, then another sealed jar
+        uclClassLoader = new java.net.URLClassLoader(new URL[] { resourceURL1,
+                resourceURL4 }, null);
+        Class.forName("p.C", true, uclClassLoader);
+        try {
+            Class.forName("p.D", true, uclClassLoader);
+            fail("should throw SecurityException");
+        } catch (SecurityException e) {
+            // Expected
+        }
     }
-    
-    @SuppressWarnings("unchecked")
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAnnotations",
-        args = {}
-    )
-    @KnownFailure("Class loader can't retrieve information about annotations.")    
-    public void test_getAnnotations() throws Exception {
-        String annotationName = "a.b.PackageAnnotation";
-        Package p = getTestPackage("hyts_package.jar", annotationName);
-
-        Annotation [] annotations = p.getAnnotations();
-        assertEquals(1, annotations.length);
-        
-        p = String.class.getPackage();
-        assertEquals(0, p.getAnnotations().length);
-    }   
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getDeclaredAnnotations",
-        args = {}
-    )
-    @KnownFailure("Class loader can't retrieve information about annotations.")
-    public void test_getDeclaredAnnotations() throws Exception {
-        String annotationName = "a.b.PackageAnnotation";
-        Package p = getTestPackage("hyts_package.jar", annotationName);
-
-        Annotation [] annotations = p.getDeclaredAnnotations();
-        assertEquals(1, annotations.length);
-        
-        p = String.class.getPackage();
-        assertEquals(0, p.getDeclaredAnnotations().length);
-    } 
-    
-    @SuppressWarnings("unchecked")
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isAnnotationPresent",
-        args = {java.lang.Class.class}
-    )
-    @KnownFailure("Class loader can't retrieve information about annotations.")
-    public void test_isAnnotationPresent() throws Exception {
-        String annotationName = "a.b.PackageAnnotation";
-        Package p = getTestPackage("hyts_package.jar", annotationName);
-
-        assertTrue(p.isAnnotationPresent(clazz));
-        assertFalse(p.isAnnotationPresent(Deprecated.class));
-        
-        p = String.class.getPackage();
-        assertFalse(p.isAnnotationPresent(clazz));
-        assertFalse(p.isAnnotationPresent(Deprecated.class));        
-    }          
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimePermissionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimePermissionTest.java
index cc5145e..ebe3a40 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimePermissionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimePermissionTest.java
@@ -17,46 +17,28 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-@TestTargetClass(RuntimePermission.class) 
 public class RuntimePermissionTest extends junit.framework.TestCase {
 
-    /**
-     * @tests java.lang.RuntimePermission#RuntimePermission(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "RuntimePermission",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
-        // Test for method java.lang.RuntimePermission(java.lang.String)
-        RuntimePermission r = new RuntimePermission("createClassLoader");
-        assertEquals("Returned incorrect name", 
-                "createClassLoader", r.getName());
+	/**
+	 * @tests java.lang.RuntimePermission#RuntimePermission(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
+		// Test for method java.lang.RuntimePermission(java.lang.String)
+		RuntimePermission r = new RuntimePermission("createClassLoader");
+		assertEquals("Returned incorrect name", 
+				"createClassLoader", r.getName());
 
-    }
+	}
 
-    /**
-     * @tests java.lang.RuntimePermission#RuntimePermission(java.lang.String,
-     *        java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "RuntimePermission",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_StringLjava_lang_String() {
-        // Test for method java.lang.RuntimePermission(java.lang.String,
-        // java.lang.String)
-        RuntimePermission r = new RuntimePermission("createClassLoader", null);
-        assertEquals("Returned incorrect name", 
-                "createClassLoader", r.getName());
-    }
+	/**
+	 * @tests java.lang.RuntimePermission#RuntimePermission(java.lang.String,
+	 *        java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+		// Test for method java.lang.RuntimePermission(java.lang.String,
+		// java.lang.String)
+		RuntimePermission r = new RuntimePermission("createClassLoader", null);
+		assertEquals("Returned incorrect name", 
+				"createClassLoader", r.getName());
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
index 1b61d6f..791e266 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/RuntimeTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
+import dalvik.annotation.KnownFailure;
 import dalvik.annotation.TestLevel;
 import dalvik.annotation.TestTargetNew;
 import dalvik.annotation.TestTargetClass;
@@ -843,6 +844,7 @@
         method = "traceMethodCalls",
         args = {boolean.class}
     )
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void test_traceMethodCalls() {
         try {
             Runtime.getRuntime().traceMethodCalls(false);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityExceptionTest.java
index 407d6f9..94c7dc2 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityExceptionTest.java
@@ -17,26 +17,15 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(SecurityException.class) 
 public class SecurityExceptionTest extends TestCase {
-    
-    /**
-     * @tests java.lang.SecurityException#SecurityException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "SecurityException",
-        args = {}
-    )
+	
+	/**
+	 * @tests java.lang.SecurityException#SecurityException()
+	 */
     public void test_Constructor() {
         SecurityException e = new SecurityException();
         assertNull(e.getMessage());
@@ -47,12 +36,6 @@
     /**
      * @tests java.lang.SecurityException#SecurityException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "SecurityException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         SecurityException e = new SecurityException("fixture");
         assertEquals("fixture", e.getMessage());
@@ -62,12 +45,6 @@
     /**
      * @tests java.lang.SecurityException#SecurityException(String, Throwable)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "SecurityException",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
     @SuppressWarnings("nls")
     public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
         NullPointerException npe = new NullPointerException();
@@ -79,12 +56,6 @@
     /**
      * @tests java.lang.SecurityException#SecurityException(Throwable)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "SecurityException",
-        args = {java.lang.Throwable.class}
-    )
     @SuppressWarnings("nls")
     public void test_ConstructorLjava_lang_Throwable() {
         NullPointerException npe = new NullPointerException();
@@ -95,12 +66,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationSelf",
-        args = {}
-    )    
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new SecurityException());
@@ -109,12 +74,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new SecurityException());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java
index 0bd0c1f..d8c3751 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/SecurityManagerTest.java
@@ -4,9 +4,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- *
+ * 
  *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,19 +16,10 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import junit.framework.TestCase;
-
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FilePermission;
-import java.io.IOException;
-import java.lang.reflect.Member;
 import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
 import java.net.SocketPermission;
 import java.net.UnknownHostException;
 import java.security.AccessControlContext;
@@ -36,20 +27,13 @@
 import java.security.Permission;
 import java.security.ProtectionDomain;
 import java.security.Security;
-import java.security.SecurityPermission;
+
+import junit.framework.TestCase;
+import tests.support.Support_Exec;
 
 /**
  * Test case for java.lang.SecurityManager
  */
-@TestTargetClass(value = SecurityManager.class, 
-                 untestedMethods = {
-                     @TestTargetNew(
-                         level = TestLevel.NOT_FEASIBLE,
-                         notes = "AWTPermission class is not supported.",
-                         method = "checkSystemClipboardAccess",
-                         args = {}
-                     )
-}) 
 public class SecurityManagerTest extends TestCase {
     MutableSecurityManager mutableSM = null;
 
@@ -57,50 +41,9 @@
 
     SecurityManager originalSM = null;
 
-    String deletedFile = "/";
-    String readedFile  = "/";
-    String writedFile  = "/";
-
-    /**
-     * @tests java.lang.SecurityManager#SecurityManager()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "SecurityManager",
-        args = {}
-    )
-    public void test_Constructor() {
-        SecurityManager localManager = null;
-        try {
-            localManager = new MockSecurityManager();
-        } catch (Exception e) {
-            fail("Unexpected exception " + e.toString());
-        }
-
-        try {
-            assertNotNull("Incorrect SecurityManager", localManager);
-            System.setSecurityManager(localManager);
-            try {
-                new MockSecurityManager();
-                fail("SecurityException was not thrown");
-            } catch (SecurityException se) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
-
     /**
      * @tests java.lang.SecurityManager#checkPackageAccess(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPackageAccess",
-        args = {java.lang.String.class}
-    )
     public void test_checkPackageAccessLjava_lang_String() {
         final String old = Security.getProperty("package.access");
         Security.setProperty("package.access", "a.,bbb, c.d.");
@@ -149,12 +92,6 @@
     /**
      * @tests java.lang.SecurityManager#checkPackageDefinition(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPackageDefinition",
-        args = {java.lang.String.class}
-    )
     public void test_checkPackageDefinitionLjava_lang_String() {
         final String old = Security.getProperty("package.definition");
         Security.setProperty("package.definition", "a.,bbb, c.d.");
@@ -203,17 +140,11 @@
     /**
      * @tests java.lang.SecurityManager#checkMemberAccess(java.lang.Class, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkMemberAccess",
-        args = {java.lang.Class.class, int.class}
-    )
     public void test_checkMemberAccessLjava_lang_ClassI() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        mutableSM.denyPermission(
-                new RuntimePermission("accessDeclaredMembers"));
+        mutableSM
+                .denyPermission(new RuntimePermission("accessDeclaredMembers"));
         System.setSecurityManager(mutableSM);
         try {
             getClass().getDeclaredFields();
@@ -223,80 +154,37 @@
                 fail("This should throw a SecurityException.");
             } catch (SecurityException e) {
             }
-            
-            try {
-                delegateCallToCheckMemberAccess2(Object.class, Member.DECLARED);
-                fail("SecurityException was not thrown.");
-            } catch(SecurityException se) {
-                //expected
-            }
-            
-            try {
-                delegateCallToCheckMemberAccess2(null, Member.PUBLIC);
-                fail("NullPointerException was not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
+
         } finally {
             System.setSecurityManager(null);
         }
     }
 
     /**
-     * Don't call checkMemberAccess directly, since we're checking our caller
-     * (and not ourselves). This is necessary for unit tests, since JUnit's
-     * TestCase is usually in the boot classpath for dalvik. This delegating
-     * method corresponds to Class.getDeclared*();
-     */
-    private void delegateCallToCheckMemberAccess2(Class<Object> cls, int type) {
-        delegateCallToCheckMemberAccess1(cls, type);
-    }
-
-    /**
-     * This delegating method corresponds to Class.checkMemberAccess().
-     */
-    private void delegateCallToCheckMemberAccess1(Class<Object> cls, int type) {
-        mutableSM.checkMemberAccess(cls, type);
-    }
-
-    /**
      * @tests java.lang.SecurityManager#checkPermission(java.security.Permission)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPermission",
-        args = {java.security.Permission.class}
-    )
+    /* BEGIN android-removed: we don't have Support_Exec.execJava.
     public void test_checkPermissionLjava_security_Permission()
             throws Exception {
 
         // tmp user home to avoid presence of ${user.home}/.java.policy
-        //String tmpUserHome = System.getProperty("java.io.tmpdir")
-        //        + File.separatorChar + "tmpUserHomeForSecurityManagerTest";
-        //File dir = new File(tmpUserHome);
-        //if (!dir.exists()) {
-        //    dir.mkdirs();
-        //   dir.deleteOnExit();
-        //}
-        //String javaPolycy = tmpUserHome + File.separatorChar + ".java.policy";
-        //assertFalse("There should be no java policy file: " + javaPolycy,
-        //        new File(javaPolycy).exists());
-        // 
-        //String[] arg = new String[] { "-Duser.home=" + tmpUserHome,
-        //        checkPermissionLjava_security_PermissionTesting.class.getName() };
-        //
-        //Support_Exec.execJava(arg, null, true);
-        
-        checkPermissionLjava_security_PermissionTesting.class.getName();
-        
-       try {
-            mutableSM.checkPermission(null);
-            fail("NullPointerException was not thrown.");
-        } catch(NullPointerException npe) {
-            //expected
+        String tmpUserHome = System.getProperty("java.io.tmpdir")
+                + File.separatorChar + "tmpUserHomeForSecurityManagerTest";
+        File dir = new File(tmpUserHome);
+        if (!dir.exists()) {
+            dir.mkdirs();
+            dir.deleteOnExit();
         }
+        String javaPolycy = tmpUserHome + File.separatorChar + ".java.policy";
+        assertFalse("There should be no java policy file: " + javaPolycy,
+                new File(javaPolycy).exists());
+
+        String[] arg = new String[] { "-Duser.home=" + tmpUserHome,
+                checkPermissionLjava_security_PermissionTesting.class.getName() };
+
+        Support_Exec.execJava(arg, null, true);
     }
+    */
 
     private static class checkPermissionLjava_security_PermissionTesting {
         public static void main(String[] args) {
@@ -310,12 +198,6 @@
                     fail("This should throw a SecurityException");
                 } catch (SecurityException e) {
                 }
-                
-                try {
-                    sm.checkPermission(new SecurityPermission("setSystemScope"));
-                } catch(SecurityException se) {
-                    fail("SecurityException is thrown.");
-                }                
             } finally {
                 System.setSecurityManager(null);
             }
@@ -325,259 +207,39 @@
     /**
      * @tests java.lang.SecurityManager#checkAccess(java.lang.Thread)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkAccess",
-        args = {java.lang.Thread.class}
-    )
     public void test_checkAccessLjava_lang_Thread() throws InterruptedException {
         // Regression for HARMONY-66
         Thread t = new Thread() {
             @Override
             public void run() {
-            }
+            };
         };
         t.start();
         t.join();
         new SecurityManager().checkAccess(t);
-        
-        mutableSM.addPermission(new AllPermission());
-        mutableSM.denyPermission( new RuntimePermission("modifyThread"));  
-        System.setSecurityManager(mutableSM);        
-
-        try {
-            try {
-                mutableSM.checkAccess(t);
-                // should not throw SecurityException for not system thread.
-            } catch(SecurityException se) {
-                fail("SecurityException was thrown.");
-            }
-            
-            try {
-                ThreadGroup initialThreadGroup = Thread.currentThread().getThreadGroup();
-                
-                while (initialThreadGroup.getParent() != null) {
-                    initialThreadGroup = initialThreadGroup.getParent();
-                }                
-                Thread [] systemThread = new Thread[1];
-                initialThreadGroup.enumerate(systemThread);
-                mutableSM.checkAccess(systemThread[0]);
-                fail("SecurityException was not thrown.");
-            } catch(SecurityException se) {
-                // expected
-            }
-            
-          
-        } finally { 
-            System.setSecurityManager(null);  
-        }
-        
-        try {
-            mutableSM.checkAccess((Thread) null);
-            fail("NullPointerException was not thrown.");
-        } catch(NullPointerException npe) {
-            //expected
-        }       
-        
-        try {
-            new SecurityManager().checkAccess((Thread)null);
-            fail("NullPointerException was not thrown.");
-        } catch(NullPointerException npe){
-            //expected
-        }        
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkAccess",
-        args = {java.lang.ThreadGroup.class}
-    )
-    public void test_checkAccessLjava_lang_ThreadGroup() {
-        
-        ThreadGroup tg = new ThreadGroup("name");
-        
-        RuntimePermission rp = new RuntimePermission("modifyThreadGroup");
-        mutableSM.addPermission(new AllPermission());
-        
-        mutableSM.denyPermission(rp);        
-        SecurityManager sm = System.getSecurityManager();
-        System.setSecurityManager(mutableSM);
-
-        try {
-            try {
-                mutableSM.checkAccess(tg);
-         
-            } catch(SecurityException se) {
-                fail("SecurityException was thrown.");   
-            }
-            
-            try {
-                ThreadGroup initialThreadGroup = Thread.currentThread().getThreadGroup();
-                
-                while (initialThreadGroup.getParent() != null) {
-                    initialThreadGroup = initialThreadGroup.getParent();
-                }                
-                mutableSM.checkAccess(initialThreadGroup);
-            } catch(SecurityException se) {
-                
-            }
-        } finally {
-            System.setSecurityManager(sm);  
-        }
-         
-         try {
-             mutableSM.checkAccess((ThreadGroup) null);
-             fail("NullPointerException was not thrown.");
-         } catch(NullPointerException npe) {
-             //expected
-         }
-    }   
     /**
      * @tests {@link java.lang.SecurityManager#checkAccept(String, int)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkAccept",
-        args = {java.lang.String.class, int.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkAcceptLjava_lang_String_int() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        System.setSecurityManager(mutableSM);
-        try {
-            assertFalse(startServerSocket());
-            assertTrue(mutableSM.isCheckAcceptCalled);
-        
-            mutableSM.denyPermission(new SocketPermission("localhost:1024-",
-                                                    "accept, connect, listen")); 
-            assertTrue(startServerSocket());        
-            assertTrue(mutableSM.isCheckAcceptCalled);
-        
-            try {
-                mutableSM.checkAccept(null, 0);
-                fail("NullPointerException is not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
-        } finally {
-            System.setSecurityManager(null);              
-        }
-    }
-
-    boolean startServerSocket() {
-        boolean isSecurityExceptionThrown = false;
-        ServerSocket ss = null;
-        try {
-            ss = new ServerSocket(3132);
-            Thread thr = new Thread() {
-                Socket s = null;
-                
-                public void run() {
-                    try {
-                        s = new Socket(InetAddress.getLocalHost().getHostName(), 3132);
-                        Thread.sleep(1);
-                    } catch(InterruptedException ie) {
-                        fail("InterruptedException was thrown.");
-                    } catch(UnknownHostException uhe) {
-                        fail("UnknownHostException was thrown.");
-                    } catch(IOException ioe) {
-                        fail("IOException was thrown.");
-                    } finally {
-                        try {
-                            s.close();
-                        } catch(Exception e) {}
-                    }
-                }
-            };
-            thr.start();
-            ss.accept();
-            ss.close();
-        } catch(IOException ioe) {
-            fail("IOException was thrown.");
-        } catch(SecurityException se) {
-            isSecurityExceptionThrown = true;
-        } finally {
-            try {
-                if(!ss.isClosed())
-                    ss.close();
-            } catch(Exception e) {              
-            }
-
-        }
-        return isSecurityExceptionThrown;
-    }
-    
-    /**
-     * @tests {@link java.lang.SecurityManager#checkConnect(String, int)}
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkConnect",
-        args = {java.lang.String.class, int.class}
-    )
-    public void test_checkConnectLjava_lang_StringI() {
-        String hostName = "localhost";
-        int port = 1024;
-        
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
         mutableSM.denyPermission(new SocketPermission("localhost:1024-",
                 "accept, connect, listen"));
         System.setSecurityManager(mutableSM);
         try {
-            try {
-                mutableSM.checkConnect(hostName, port);
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            } 
-            
-            assertTrue(createSocketAddress(hostName, port));
-        
-            try {
-                mutableSM.checkConnect(hostName, -1);
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            } 
-            
-            try {
-                mutableSM.checkConnect(null, 1024);
-                fail("NullPointerException was not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
-        } finally {
-              System.setSecurityManager(null);
+            mutableSM.checkAccept("localhost", 1024);
+            fail("This should throw a SecurityException.");
+        } catch (SecurityException e) {
+            // expected
         }
-        
-        assertFalse(createSocketAddress(hostName, port));
     }
-    
-    boolean createSocketAddress(String hostname, int port) {
 
-        try {
-            new InetSocketAddress(hostname, port);
-        } catch(SecurityException se) {
-            return true;
-        }
-        return false;
-    }
-    
     /**
      * @tests {@link java.lang.SecurityManager#checkConnect(String, int, Object)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkConnect",
-        args = {java.lang.String.class, int.class, java.lang.Object.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkConnectLjava_lang_String_int_Ljava_lang_Object() {
         // enable all but one check
@@ -585,133 +247,20 @@
         mutableSM.denyPermission(new SocketPermission("localhost:1024-",
                 "accept, connect, listen"));
         System.setSecurityManager(mutableSM);
+        ProtectionDomain pDomain = this.getClass().getProtectionDomain();
+        ProtectionDomain[] pd = { pDomain };
+        AccessControlContext acc = new AccessControlContext(pd);
         try {
-            ProtectionDomain pDomain = this.getClass().getProtectionDomain();
-            ProtectionDomain[] pd = { pDomain };
-            AccessControlContext acc = new AccessControlContext(pd);
-            try {
-                mutableSM.checkConnect("localhost", 1024, acc);
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            }
-            
-            try {
-                mutableSM.checkConnect("localhost", -1, acc);
-                // The action "resolve" is implicitely in the denied Permission
-                // that was added to the denied permissions at the beginning of
-                // this test. So this throws a security Exception on the RI and
-                // also on android.
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-              // expected
-            }
-            
-            assertTrue(createSocketAddress("localhost", 1024));
-        
-            try {
-                mutableSM.checkConnect(null, 1024, acc);            
-                fail("NullPointerException was not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
-            System.setSecurityManager(null);
-            try {
-                mutableSM.checkConnect("localhost", 1024, null);
-                fail("SecurityException was not thrown.");            
-            } catch(SecurityException se) {
-                //expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        } 
-        assertFalse(createSocketAddress("localhost", 1024));        
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkCreateClassLoader",
-        args = {}
-    )   
-    public void test_checkCreateClassLoader() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        System.setSecurityManager(mutableSM);
-        try {
-            mutableSM.checkCreateClassLoader();
+            mutableSM.checkConnect("localhost", 1024, acc);
+            fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
-            fail("Unexpected SecurityException " + e.toString());
-        }
-
-        SecurityManager localManager = new MockSecurityManager();
-        try {
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkCreateClassLoader();
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkDelete",
-        args = {java.lang.String.class}
-    )
-    public void test_checkDeleteLjava_lang_String() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        mutableSM
-        .denyPermission(new FilePermission("<<ALL FILES>>", "delete")); 
-        try {
-            System.setSecurityManager(mutableSM);
-          
-            try {
-                mutableSM.checkDelete("new.file");
-                fail("SecurityException was not thrown");
-            } catch (SecurityException npe) {
-                // expected
-            }            
-            
-            try {
-                mutableSM.checkDelete(null);
-                fail("NullPointerException was not thrown");
-            } catch (NullPointerException npe) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-
-        SecurityManager localManager = new MockSecurityManager();
-        try {
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkDelete(deletedFile);
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
+            // expected
         }
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkExec(String)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkExec",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkExecLjava_lang_String() {
         // enable all but one check
@@ -724,36 +273,16 @@
             fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
             // expected
-        } finally {
-            System.setSecurityManager(null);           
-        }
-        
-        try {
-            mutableSM.checkExec(null);
-            fail("NullPointerException was not thrown.");
-        } catch(NullPointerException npe) {
-            //expected
         }
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkExit(int)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkExit",
-        args = {int.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkExit_int() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkExit(0);
-        } catch(SecurityException se) {
-            fail("SecurityException was thrown.");
-        }
         mutableSM.denyPermission(new RuntimePermission("exitVM"));
         System.setSecurityManager(mutableSM);
         try {
@@ -761,20 +290,12 @@
             fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
             // expected
-        } finally {
-            System.setSecurityManager(null);
         }
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkLink(String)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkLink",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkLinkLjava_lang_String() {
         // enable all but one check
@@ -782,42 +303,20 @@
         mutableSM.denyPermission(new RuntimePermission("loadLibrary.harmony"));
         System.setSecurityManager(mutableSM);
         try {
-            try {
-                mutableSM.checkLink("harmony");
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            }
-        
-            try {
-                mutableSM.checkLink(null);
-                fail("NullPointerException is not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
-        } finally {
-            System.setSecurityManager(null);
+            mutableSM.checkLink("harmony");
+            fail("This should throw a SecurityException.");
+        } catch (SecurityException e) {
+            // expected
         }
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkListen(int)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkListen",
-        args = {int.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkListen_int() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkListen(80);
-        } catch(SecurityException se) {
-            fail("SecurityException was thrown.");
-        }
         mutableSM
                 .denyPermission(new SocketPermission("localhost:80", "listen"));
         System.setSecurityManager(mutableSM);
@@ -844,22 +343,11 @@
      * @throws UnknownHostException
      * @tests {@link java.lang.SecurityManager#checkMulticast(java.net.InetAddress)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies SecurityException.",
-        method = "checkMulticast",
-        args = {java.net.InetAddress.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkMulticastLjava_net_InetAddress()
             throws UnknownHostException {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkMulticast(InetAddress.getByName("localhost"));
-        } catch(SecurityException se) {
-            fail("SecurityException is thrown.");
-        }            
         mutableSM.denyPermission(new SocketPermission(InetAddress.getByName(
                 "localhost").getHostAddress(), "accept,connect"));
         System.setSecurityManager(mutableSM);
@@ -868,73 +356,35 @@
             fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
             // expected
-        } finally {
-            System.setSecurityManager(null);
         }
-        
-        try {
-            mutableSM.checkMulticast(null);
-            fail("NullPointerException was not thrown.");            
-        } catch(NullPointerException e) {
-            //expected
-        }        
     }
 
     /**
      * @throws UnknownHostException
      * @tests {@link java.lang.SecurityManager#checkMulticast(java.net.InetAddress,byte)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkMulticast",
-        args = {java.net.InetAddress.class, byte.class}
-    )
     @SuppressWarnings( { "nls", "deprecation" })
     public void test_checkMulticastLjava_net_InetAddress_int()
             throws UnknownHostException {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkMulticast(
-                    InetAddress.getByName("localhost"), (byte) 0);
-        } catch(SecurityException se) {
-            fail("SecurityException is thrown.");
-        }            
         mutableSM.denyPermission(new SocketPermission(InetAddress.getByName(
                 "localhost").getHostAddress(), "accept,connect"));
         System.setSecurityManager(mutableSM);
         try {
-            try {
-                // the second parameter is the TTL(time to live)
-                mutableSM.checkMulticast(InetAddress.getByName("localhost"),
-                        (byte) 0);
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            }
-            
-            try {
-                mutableSM.checkMulticast(null, (byte) 0);                
-                fail("NullPointerException is not thrown.");
-            } catch(NullPointerException ne) {
-                //expected
-            }
-        } finally {
-            System.setSecurityManager(null);
+            // the second parameter is the TTL(time to live)
+            mutableSM.checkMulticast(InetAddress.getByName("localhost"),
+                    (byte) 0);
+            fail("This should throw a SecurityException.");
+        } catch (SecurityException e) {
+            // expected
         }
     }
 
     /**
-     *
+     * 
      * @tests {@link java.lang.SecurityManager#checkPermission(Permission, Object)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPermission",
-        args = {java.security.Permission.class, java.lang.Object.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkPermissionLjava_security_PermissionLjava_lang_Object() {
         // enable all but one check
@@ -951,43 +401,16 @@
             fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
             // expected
-        } finally {
-            System.setSecurityManager(null);
         }
-        
-        try {
-            mutableSM.checkPermission(null, acc);
-            fail("NullPointerException was not thrown.");
-        } catch (NullPointerException npe) {
-            // expected
-        } 
-        
-        try {
-            mutableSM.checkPermission(denyp, null);
-            fail("SecurityException was not thrown.");
-        } catch (SecurityException se) {
-            // expected
-        }        
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkPrintJobAccess()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPrintJobAccess",
-        args = {}
-    )
     @SuppressWarnings("nls")
     public void test_checkPrintJobAccess() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkPrintJobAccess();
-        } catch(SecurityException se) {
-            fail("SecurityException is thrown.");
-        }            
         mutableSM.denyPermission(new RuntimePermission("queuePrintJob"));
         System.setSecurityManager(mutableSM);
         try {
@@ -997,99 +420,14 @@
             // expected
         }
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPropertiesAccess",
-        args = {}
-    )
-    public void test_checkPropertiesAccess() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        System.setSecurityManager(mutableSM);
-        try {
-            mutableSM.checkPropertiesAccess();
-        } catch (SecurityException e) {
-            fail("Unexpected SecurityException " + e.toString());
-        } finally {
-            System.setSecurityManager(null);
-        }
-
-        SecurityManager localManager = new MockSecurityManager();
-        try {
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkPropertiesAccess();
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkPropertyAccess",
-        args = {java.lang.String.class}
-    )
-    public void test_checkPropertyAccessLjava_lang_String() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        System.setSecurityManager(mutableSM);
-        try {
-            mutableSM.checkPropertyAccess("key");
-        } catch (SecurityException e) {
-            fail("Unexpected SecurityException " + e.toString());
-        } finally {
-            System.setSecurityManager(null);
-        }
-
-        SecurityManager localManager = new MockSecurityManager();
-        try {
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkPropertyAccess("key");
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-            try {
-                localManager.checkPropertyAccess("");
-                fail("Expected IllegalArgumentException was not thrown");
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            try {
-                localManager.checkPropertyAccess(null);
-                fail("Expected NullPointerException was not thrown");
-            } catch (NullPointerException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkRead(FileDescriptor)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkRead",
-        args = {java.io.FileDescriptor.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkReadLjava_io_FileDescriptor() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkRead(new FileDescriptor());
-        } catch(SecurityException se) {
-            fail("SecurityException is thrown.");
-        }            
         mutableSM.denyPermission(new RuntimePermission("readFileDescriptor"));
         System.setSecurityManager(mutableSM);
         try {
@@ -1099,314 +437,47 @@
             // expected
         }
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkRead",
-        args = {java.lang.String.class}
-    )
-    public void test_checkReadLjava_lang_String() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkRead(readedFile);
-        } catch(SecurityException se) {
-            fail("SecurityException is thrown.");
-        }        
-        mutableSM.denyPermission(new RuntimePermission("readFileDescriptor"));
-        System.setSecurityManager(mutableSM);
-        try {
-            try {
-                mutableSM.checkRead(readedFile);
-            } catch (SecurityException e) {
-                fail("Unexpected SecurityException " + e.toString());
-            }
-
-            SecurityManager localManager = new MockSecurityManager();
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkRead(readedFile);
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-            
-            try {
-                localManager.checkRead((String) null);
-                fail("NullPointerException was not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkRead(String,Object)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies SecurityException.",
-        method = "checkRead",
-        args = {java.lang.String.class, java.lang.Object.class}
-    )
     @SuppressWarnings("nls")
     public void test_checkReadLjava_lang_StringLjava_lang_Object() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
+        mutableSM.denyPermission(new FilePermission("<<ALL FILES>>", "read"));
         ProtectionDomain pDomain = this.getClass().getProtectionDomain();
         ProtectionDomain[] pd = { pDomain };
-        AccessControlContext acc = new AccessControlContext(pd);        
-        mutableSM.denyPermission(new FilePermission("<<ALL FILES>>", "read"));
+        AccessControlContext acc = new AccessControlContext(pd);
         System.setSecurityManager(mutableSM);
         try {
-            try {
-                mutableSM.checkRead("aa", acc);
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            }
-            
-            try {
-                mutableSM.checkRead(null, acc);
-                fail("NullPointerException was not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkSecurityAccess",
-        args = {java.lang.String.class}
-    )
-    public void test_checkSecurityAccessLjava_lang_String() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        System.setSecurityManager(mutableSM);
-        try {
-            mutableSM.checkSecurityAccess("getPolicy");
+            mutableSM.checkRead("aa", acc);
+            fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
-            fail("Unexpected SecurityException " + e.toString());
-        } finally {
-            System.setSecurityManager(null);
-        }
-
-        SecurityManager localManager = new MockSecurityManager();
-        try {
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkSecurityAccess("getPolicy");
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-            try {
-                localManager.checkSecurityAccess("");
-                fail("Expected IllegalArgumentException was not thrown");
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            try {
-                localManager.checkSecurityAccess(null);
-                fail("Expected NullPointerException was not thrown");
-            } catch (NullPointerException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
+            // expected
         }
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#checkSetFactory()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkSetFactory",
-        args = {}
-    )
     @SuppressWarnings("nls")
     public void test_checkSetFactory() {
         // enable all but one check
         mutableSM.addPermission(new AllPermission());
-        assertFalse(setFactory());
         mutableSM.denyPermission(new RuntimePermission("setFactory"));
         System.setSecurityManager(mutableSM);
         try {
-            try {
-                mutableSM.checkSetFactory();
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            }
-            assertTrue(setFactory());
-        } finally {
-            System.setSecurityManager(null);            
-        }
-    }
-    
-    boolean setFactory() {
-        try {
-            ServerSocket.setSocketFactory(null);
-        } catch(IOException ioe) {
-            fail("IOException was thrown.");
-        } catch(SecurityException se) {
-            return true;
-        }
-        return false;
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.NOT_NECESSARY,
-        notes = "Mark this method not feasable: AWTPermission doesn't exist",
-        method = "checkAwtEventQueueAccess",
-        args = {}
-    )
-    public void test_checkAwtEventQueueAccess() {
-        mutableSM.addPermission(new AllPermission());
-        // TODO AWTPermission class is unavailable 
-        //mutableSM.denyPermission(new AWTPermission("accessEventQueue"));
-        //System.setSecurityManager(mutableSM);
-        //try {
-        //    try {
-        //        mutableSM.checkAwtEventQueueAccess();
-        //        fail("This should throw a SecurityException.");
-        //    } catch (SecurityException e) {
-                // expected
-        //    }
-        //} finally {
-        //   System.setSecurityManager(null);            
-        //}
-    }
-
-    @TestTargetNew(
-        level = TestLevel.NOT_NECESSARY,
-        notes = "Mark this method not feasable: AWTPermission doesn't exist",
-        method = "checkTopLevelWindow",
-        args = {java.lang.Object.class}
-    )
-    public void test_checkTopLevelWindowLjava_lang_Object() {
-     //   assertFalse("Calling thread isn't trusted to bring up the top-level window",
-      //          mutableSM.checkTopLevelWindow(this));
-
-        try {
-            SecurityManager localManager = new MockSecurityManager();
-            System.setSecurityManager(localManager);
-            assertTrue("Calling thread is trusted to bring up the top-level window",
-                    localManager.checkTopLevelWindow(this));
-            try {
-                localManager.checkTopLevelWindow(null);
-                fail("Expected NullPointerexception was not thrown");
-            } catch (NullPointerException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-        //TODO AWTPermission class is unavailable
-        //mutableSM.addPermission(new AllPermission());
-        //assertTrue(mutableSM.checkTopLevelWindow(new Object()));
-        //mutableSM.denyPermission(new AWTPermission("showWindowWithoutWarningBanner"));
-        //System.setSecurityManager(mutableSM);
-        //try {
-        //    assertFalse(mutableSM.checkTopLevelWindow(new Object()));
-        //} finally {
-        //    System.setSecurityManager(null);            
-        //}
-                   
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkWrite",
-        args = {java.io.FileDescriptor.class}
-    )
-    public void test_checkWriteLjava_io_FileDescriptor() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkWrite(new FileDescriptor());
-        } catch(SecurityException se) {
-            fail("SecurityException was thrown.");
-        }
-        mutableSM.denyPermission(new RuntimePermission("writeFileDescriptor"));
-        System.setSecurityManager(mutableSM);
-        try {
-            mutableSM.checkWrite(new FileDescriptor());
+            mutableSM.checkSetFactory();
             fail("This should throw a SecurityException.");
         } catch (SecurityException e) {
             // expected
-        } finally {
-            System.setSecurityManager(null);
-        }
-        
-        try {
-            mutableSM.checkWrite((FileDescriptor) null);
-            fail("NullPointerException was not thrown.");            
-        } catch(NullPointerException npe) {
-            //expected
-        }
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkWrite",
-        args = {java.lang.String.class}
-    )
-    public void test_checkWriteLjava_lang_String() {
-        // enable all but one check
-        mutableSM.addPermission(new AllPermission());
-        try {
-            mutableSM.checkWrite(writedFile);
-        } catch(SecurityException se) {
-            fail("SecurityException was thrown.");
-        }
-        mutableSM.denyPermission(new RuntimePermission("writeFileDescriptor"));
-        System.setSecurityManager(mutableSM);
-        try {
-            mutableSM.checkWrite(writedFile);
-        } catch (SecurityException e) {
-            fail("Unexpected SecurityException " + e.toString());
-        } finally {
-            System.setSecurityManager(null);
-        }
-
-        try {
-            SecurityManager localManager = new MockSecurityManager();
-            System.setSecurityManager(localManager);
-            try {
-                localManager.checkWrite(writedFile);
-                fail("Expected SecurityException was not thrown");
-            } catch (SecurityException e) {
-                // expected
-            }
-        } finally {
-            System.setSecurityManager(null);
-        }
-        
-        try {
-            mutableSM.checkWrite((String) null);
-            fail("NullPointerException was not thrown.");
-        } catch(NullPointerException npe) {
-            //expected
         }
     }
 
     /**
      * @tests {@link java.lang.SecurityManager#getInCheck()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInCheck",
-        args = {}
-    )
     public void test_getIncheck() {
         mockSM.setInCheck(false);
         assertFalse(mockSM.getInCheck());
@@ -1417,12 +488,6 @@
     /**
      * @tests {@link java.lang.SecurityManager#getSecurityContext()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getSecurityContext",
-        args = {}
-    )
     @SuppressWarnings("nls")
     public void test_getSecurityContext() {
         // enable all but one check
@@ -1430,61 +495,16 @@
         mutableSM.denyPermission(new FilePermission("<<ALL FILES>>", "read"));
         System.setSecurityManager(mutableSM);
         try {
-            try {
-                mutableSM.getSecurityContext();
-            } catch(Exception e) {
-                fail("Unexpected exception was thrown: " + e.toString());
-            }            
-            
-            try {
-                mutableSM.checkRead("aa", mutableSM.getSecurityContext());
-                fail("This should throw a SecurityException.");
-            } catch (SecurityException e) {
-                // expected
-            }
-    
-        } finally {
-            System.setSecurityManager(null);            
+            mutableSM.checkRead("aa", mutableSM.getSecurityContext());
+            fail("This should throw a SecurityException.");
+        } catch (SecurityException e) {
+            // expected
         }
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getThreadGroup",
-        args = {}
-    )
-    public void test_getThreadGroup() throws InterruptedException {
-        final ThreadGroup tgroup = new ThreadGroup(mutableSM.getThreadGroup(), 
-                "groupName");
-        assertNotNull("Incorrect thread group", tgroup);
-        class MyThread extends Thread{
-            public int newCount;
-            
-            public MyThread() {
-                super(tgroup, "threadName");
-            }
-            
-            @Override
-            public void run() {
-                super.run();
-                newCount = tgroup.activeCount();
-            }
-        }
-        MyThread t = new MyThread();
-        t.start();
-        t.join();
-        assertEquals("Incorrect active count value", 1, t.newCount);
-    }
 
     /**
      * @tests {@link java.lang.SecurityManager#classDepth(String)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = ".",
-        method = "classDepth",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_classDepthLjava_lang_String() {
         assertEquals(-1, mockSM.classDepth("nothing"));
@@ -1493,12 +513,6 @@
     /**
      * @tests {@link java.lang.SecurityManager#classLoaderDepth()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "classLoaderDepth",
-        args = {}
-    )
     public void test_classLoaderDepth() {
         assertEquals(-1, mockSM.classLoaderDepth());
     }
@@ -1506,12 +520,6 @@
     /**
      * @tests {@link java.lang.SecurityManager#currentClassLoader()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "currentClassLoader",
-        args = {}
-    )
     public void test_currentClassLoader() {
         assertNull(mockSM.currentClassLoader());
     }
@@ -1519,12 +527,6 @@
     /**
      * @tests {@link java.lang.SecurityManager#currentLoadedClass()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "currentLoadedClass",
-        args = {}
-    )
     public void test_currentLoadedClass() {
         assertNull(mockSM.currentLoadedClass());
     }
@@ -1532,12 +534,6 @@
     /**
      * @tests {@link java.lang.SecurityManager#inClass(String)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "inClass",
-        args = {java.lang.String.class}
-    )
     @SuppressWarnings("nls")
     public void test_inClassLjava_lang_String() {
         assertFalse(mockSM.inClass("nothing"));
@@ -1547,43 +543,60 @@
     /**
      * @tests {@link java.lang.SecurityManager#inClassLoader()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "inClassLoader",
-        args = {}
-    )
     public void test_inClassLoader() {
         assertFalse(mockSM.inClassLoader());
     }
 
     /**
-     * @tests {@link java.lang.SecurityManager#getClassContext()}
+     * @tests {@link java.lang.SecurityManager#inClassLoader()}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getClassContext",
-        args = {}
-    )
     public void test_getClassContext() {
-        
-        Class [] stack = {MockSecurityManager.class,
-                getClass(), TestCase.class};
-        
-        Class [] returnedStack = mockSM.getClassContext();
-        
-        assertNotNull(returnedStack);
-        assertTrue(returnedStack.length > stack.length);
-        for(int i = 0; i < stack.length; i++) {
-            assertEquals(stack[i].getName() + " class should have " + i +
-                    " position in the classes stack, but there is " +
-                    returnedStack[i].getName(),
-                    stack[i], returnedStack[i]);           
-        }
+        assertEquals("MockSecurityManager should be the first in the classes stack",
+                mockSM.getClassContext()[0], MockSecurityManager.class);
     }
 
     // set some protected method to public for testing
+    class MockSecurityManager extends SecurityManager {
+
+        public void setInCheck(boolean inCheck) {
+            super.inCheck = inCheck;
+        }
+
+        @Override
+        public int classDepth(String name) {
+            return super.classDepth(name);
+        }
+
+        @Override
+        public int classLoaderDepth() {
+            return super.classLoaderDepth();
+        }
+
+        @Override
+        public ClassLoader currentClassLoader() {
+            return super.currentClassLoader();
+        }
+
+        @Override
+        public Class<?> currentLoadedClass() {
+            return super.currentLoadedClass();
+        }
+
+        @Override
+        public Class[] getClassContext() {
+            return super.getClassContext();
+        }
+
+        @Override
+        public boolean inClass(String name) {
+            return super.inClass(name);
+        }
+
+        @Override
+        public boolean inClassLoader() {
+            return super.inClassLoader();
+        }
+    }
 
     @Override
     protected void setUp() throws Exception {
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ShortTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ShortTest.java
index 34f9958..30c9ea7 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ShortTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ShortTest.java
@@ -16,14 +16,8 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(Short.class) 
 public class ShortTest extends TestCase {
     private Short sp = new Short((short) 18000);
     private Short sn = new Short((short) -19000);
@@ -31,12 +25,6 @@
     /**
      * @tests java.lang.Short#byteValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks boundary values.",
-        method = "byteValue",
-        args = {}
-    )
     public void test_byteValue() {
         // Test for method byte java.lang.Short.byteValue()
         assertEquals("Returned incorrect byte value", 0, new Short(Short.MIN_VALUE)
@@ -48,12 +36,6 @@
     /**
      * @tests java.lang.Short#compareTo(java.lang.Short)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.lang.Short.class}
-    )
     public void test_compareToLjava_lang_Short() {
         // Test for method int java.lang.Short.compareTo(java.lang.Short)
         Short s = new Short((short) 1);
@@ -79,12 +61,6 @@
     /**
      * @tests java.lang.Short#decode(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't check that no whitespace characters are permitted in the String. ",
-        method = "decode",
-        args = {java.lang.String.class}
-    )    
     public void test_decodeLjava_lang_String2() {
         // Test for method java.lang.Short
         // java.lang.Short.decode(java.lang.String)
@@ -153,12 +129,6 @@
     /**
      * @tests java.lang.Short#parseShort(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "parseShort",
-        args = {java.lang.String.class}
-    )
     public void test_parseShortLjava_lang_String2() {
         // Test for method short java.lang.Short.parseShort(java.lang.String)
         short sp = Short.parseShort("32746");
@@ -194,12 +164,6 @@
     /**
      * @tests java.lang.Short#parseShort(java.lang.String, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "parseShort",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_parseShortLjava_lang_StringI2() {
         // Test for method short java.lang.Short.parseShort(java.lang.String,
         // int)
@@ -293,12 +257,6 @@
     /**
      * @tests java.lang.Short#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString2() {
         // Test for method java.lang.String java.lang.Short.toString()
         assertTrue("Invalid string returned", sp.toString().equals("18000")
@@ -314,12 +272,6 @@
     /**
      * @tests java.lang.Short#toString(short)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {short.class}
-    )
     public void test_toStringS2() {
         // Test for method java.lang.String java.lang.Short.toString(short)
         assertEquals("Returned incorrect string", "32767", Short.toString((short) 32767)
@@ -333,12 +285,6 @@
     /**
      * @tests java.lang.Short#valueOf(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks boundary values.",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String2() {
         // Test for method java.lang.Short
         // java.lang.Short.valueOf(java.lang.String)
@@ -351,12 +297,6 @@
     /**
      * @tests java.lang.Short#valueOf(java.lang.String, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_valueOfLjava_lang_StringI2() {
         // Test for method java.lang.Short
         // java.lang.Short.valueOf(java.lang.String, int)
@@ -400,37 +340,25 @@
         fail(
                 "Failed to throw exception when passed string larger than 16 bits");
     }
-    /**
-     * @tests java.lang.Short#valueOf(short)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {short.class}
-    )
-    public void test_valueOfS() {
-        assertEquals(new Short(Short.MIN_VALUE), Short.valueOf(Short.MIN_VALUE));
-        assertEquals(new Short(Short.MAX_VALUE), Short.valueOf(Short.MAX_VALUE));
-        assertEquals(new Short((short) 0), Short.valueOf((short) 0));
+	/**
+	 * @tests java.lang.Short#valueOf(byte)
+	 */
+	public void test_valueOfS() {
+		assertEquals(new Short(Short.MIN_VALUE), Short.valueOf(Short.MIN_VALUE));
+		assertEquals(new Short(Short.MAX_VALUE), Short.valueOf(Short.MAX_VALUE));
+		assertEquals(new Short((short) 0), Short.valueOf((short) 0));
 
-        short s = -128;
-        while (s < 128) {
-            assertEquals(new Short(s), Short.valueOf(s));
-            assertSame(Short.valueOf(s), Short.valueOf(s));
-            s++;
-        }
-    }
+		short s = -128;
+		while (s < 128) {
+			assertEquals(new Short(s), Short.valueOf(s));
+			assertSame(Short.valueOf(s), Short.valueOf(s));
+			s++;
+		}
+	}
     
     /**
      * @tests java.lang.Short#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         assertEquals(1, new Short((short)1).hashCode());
         assertEquals(2, new Short((short)2).hashCode());
@@ -441,12 +369,6 @@
     /**
      * @tests java.lang.Short#Short(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Short",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         assertEquals(new Short((short)0), new Short("0"));
         assertEquals(new Short((short)1), new Short("1"));
@@ -476,12 +398,6 @@
     /**
      * @tests java.lang.Short#Short(short)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Short",
-        args = {short.class}
-    )
     public void test_ConstructorS() {
         assertEquals(1, new Short((short)1).shortValue());
         assertEquals(2, new Short((short)2).shortValue());
@@ -492,13 +408,7 @@
     /**
      * @tests java.lang.Short#byteValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check boundary values.",
-        method = "byteValue",
-        args = {}
-    )
-    public void test_byteValue1() {
+    public void test_booleanValue() {
         assertEquals(1, new Short((short)1).byteValue());    
         assertEquals(2, new Short((short)2).byteValue());
         assertEquals(0, new Short((short)0).byteValue());
@@ -508,12 +418,6 @@
     /**
      * @tests java.lang.Short#equals(Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         assertEquals(new Short((short)0), Short.valueOf((short)0));
         assertEquals(new Short((short)1), Short.valueOf((short)1));
@@ -528,12 +432,6 @@
     /**
      * @tests java.lang.Short#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         assertEquals("-1", new Short((short)-1).toString());
         assertEquals("0", new Short((short)0).toString());
@@ -544,12 +442,6 @@
     /**
      * @tests java.lang.Short#toString(short)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {short.class}
-    )
     public void test_toStringS() {
         assertEquals("-1", Short.toString((short)-1));
         assertEquals("0", Short.toString((short)0));
@@ -560,12 +452,6 @@
     /**
      * @tests java.lang.Short#valueOf(String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't check boundary values.",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String() {
         assertEquals(new Short((short)0), Short.valueOf("0"));
         assertEquals(new Short((short)1), Short.valueOf("1"));
@@ -595,12 +481,6 @@
     /**
      * @tests java.lang.Short#valueOf(String,int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_valueOfLjava_lang_StringI() {
         assertEquals(new Short((short)0), Short.valueOf("0", 10));
         assertEquals(new Short((short)1), Short.valueOf("1", 10));
@@ -634,12 +514,6 @@
     /**
      * @tests java.lang.Short#parseShort(String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't check boundary values, unicodes.",
-        method = "parseShort",
-        args = {java.lang.String.class}
-    )
     public void test_parseShortLjava_lang_String() {
         assertEquals(0, Short.parseShort("0"));
         assertEquals(1, Short.parseShort("1"));
@@ -669,12 +543,6 @@
     /**
      * @tests java.lang.Short#parseShort(String,int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't check boundary values.",
-        method = "parseShort",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_parseShortLjava_lang_StringI() {
         assertEquals(0, Short.parseShort("0", 10));
         assertEquals(1, Short.parseShort("1", 10));
@@ -708,12 +576,6 @@
     /**
      * @tests java.lang.Short#decode(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "decode",
-        args = {java.lang.String.class}
-    )
     public void test_decodeLjava_lang_String() {
         assertEquals(new Short((short)0), Short.decode("0"));
         assertEquals(new Short((short)1), Short.decode("1"));
@@ -724,13 +586,6 @@
         assertEquals(new Short((short)07), Short.decode("07"));
         
         try {
-            Short.decode(" 0 ");
-            fail("NumberFormatException is not thrown.");
-        } catch(NumberFormatException nfe) {
-            //expected
-        }
-        
-        try {
             Short.decode("9.2");
             fail("Expected NumberFormatException with floating point string.");
         } catch (NumberFormatException e) {}
@@ -750,12 +605,6 @@
     /**
      * @tests java.lang.Short#doubleValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "doubleValue",
-        args = {}
-    )
     public void test_doubleValue() {
         assertEquals(-1D, new Short((short)-1).doubleValue(), 0D);
         assertEquals(0D, new Short((short)0).doubleValue(), 0D);
@@ -765,12 +614,6 @@
     /**
      * @tests java.lang.Short#floatValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "floatValue",
-        args = {}
-    )
     public void test_floatValue() {
         assertEquals(-1F, new Short((short)-1).floatValue(), 0F);
         assertEquals(0F, new Short((short)0).floatValue(), 0F);
@@ -780,12 +623,6 @@
     /**
      * @tests java.lang.Short#intValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "intValue",
-        args = {}
-    )
     public void test_intValue() {
         assertEquals(-1, new Short((short)-1).intValue());
         assertEquals(0, new Short((short)0).intValue());
@@ -795,12 +632,6 @@
     /**
      * @tests java.lang.Short#longValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "longValue",
-        args = {}
-    )
     public void test_longValue() {
         assertEquals(-1L, new Short((short)-1).longValue());
         assertEquals(0L, new Short((short)0).longValue());
@@ -810,12 +641,6 @@
     /**
      * @tests java.lang.Short#shortValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "shortValue",
-        args = {}
-    )
     public void test_shortValue() {
         assertEquals(-1, new Short((short)-1).shortValue());
         assertEquals(0, new Short((short)0).shortValue());
@@ -825,12 +650,6 @@
     /**
      * @tests java.lang.Short#reverseBytes(short)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reverseBytes",
-        args = {short.class}
-    )
     public void test_reverseBytesS() {
         assertEquals((short)0xABCD, Short.reverseBytes((short)0xCDAB));
         assertEquals((short)0x1234, Short.reverseBytes((short)0x3412));
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StackOverflowErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StackOverflowErrorTest.java
index 009349f..b4e928f 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StackOverflowErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StackOverflowErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(StackOverflowError.class) 
 public class StackOverflowErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.StackOverflowError#StackOverflowError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StackOverflowError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.StackOverflowError#StackOverflowError()
+	 */
     public void test_Constructor() {
         StackOverflowError e = new StackOverflowError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.StackOverflowError#StackOverflowError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StackOverflowError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         StackOverflowError e = new StackOverflowError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StrictMathTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StrictMathTest.java
index 137676c..831dbf8 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StrictMathTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StrictMathTest.java
@@ -17,369 +17,113 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.COPYSIGN_DD_CASES;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.COPYSIGN_FF_CASES;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.GETEXPONENT_D_CASES;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.GETEXPONENT_D_RESULTS;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.GETEXPONENT_F_CASES;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.GETEXPONENT_F_RESULTS;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.NEXTAFTER_DD_START_CASES;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.NEXTAFTER_DD_FD_DIRECTION_CASES;
+import static org.apache.harmony.luni.tests.java.lang.MathTest.NEXTAFTER_FD_START_CASES;
 
-@TestTargetClass(StrictMath.class) 
 public class StrictMathTest extends junit.framework.TestCase {
 
-    double HYP = StrictMath.sqrt(2.0);
+	double HYP = StrictMath.sqrt(2.0);
 
-    double OPP = 1.0;
+	double OPP = 1.0;
 
-    double ADJ = 1.0;
+	double ADJ = 1.0;
 
-    /* Required to make previous preprocessor flags work - do not remove */
-    int unused = 0;
+	/* Required to make previous preprocessor flags work - do not remove */
+	int unused = 0;
 
-    /**
-     * @tests java.lang.StrictMath#pow(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pow",
-        args = {double.class, double.class}
-    )
-    public void test_pow() {
-        // tests changes in fdlibm5.3
-        assertTrue(Double.longBitsToDouble(-4610068591539890326L) == 
-            StrictMath.pow(-1.0000000000000002e+00,4.5035996273704970e+15));
-        assertTrue(Double.longBitsToDouble( 4601023824101950163L) == 
-            StrictMath.pow(-9.9999999999999978e-01,4.035996273704970e+15));
-        
-        assertEquals("Incorrect value was returned.", 1.0, 
-                StrictMath.pow(Double.MAX_VALUE, 0.0));
-        assertEquals("Incorrect value was returned.", 1.0, 
-                StrictMath.pow(Double.MAX_VALUE, -0.0));
-        assertEquals("Incorrect value was returned.", Double.NaN, 
-                StrictMath.pow(Double.MAX_VALUE, Double.NaN)); 
-        assertEquals("Incorrect value was returned.", Double.NaN, 
-                StrictMath.pow(Double.NaN, 1.0));
-        assertEquals("Incorrect value was returned.", Double.POSITIVE_INFINITY, 
-                StrictMath.pow(1.1, Double.POSITIVE_INFINITY));    
-        assertEquals("Incorrect value was returned.", Double.POSITIVE_INFINITY, 
-                StrictMath.pow(0.9, Double.NEGATIVE_INFINITY));   
-        
-        assertEquals("Incorrect value was returned.", 0.0, 
-                StrictMath.pow(1.1, Double.NEGATIVE_INFINITY));   
-        assertEquals("Incorrect value was returned.", 0.0, 
-                StrictMath.pow(0.9, Double.POSITIVE_INFINITY));    
-        
-        assertEquals("Incorrect value was returned.", Double.NaN, 
-                StrictMath.pow(-1.0, Double.POSITIVE_INFINITY));   
-        assertEquals("Incorrect value was returned.", Double.NaN, 
-                StrictMath.pow(1.0, Double.NEGATIVE_INFINITY));
-        
-        assertEquals("Incorrect value was returned.", 0.0, 
-                StrictMath.pow(0.0, 1.1));   
-        assertEquals("Incorrect value was returned.", 0.0, 
-                StrictMath.pow(Double.POSITIVE_INFINITY, -1.0));   
-        
-        assertEquals("Incorrect value was returned.", 0.0, 
-                StrictMath.pow(-0.0, 1.1));   
-        assertEquals("Incorrect value was returned.", 0.0, 
-                StrictMath.pow(Double.POSITIVE_INFINITY, -1.0)); 
-        
-        assertEquals("Incorrect value was returned.", Double.POSITIVE_INFINITY,
-                StrictMath.pow(0.0, -1.0));
-        assertEquals("Incorrect value was returned.", Double.POSITIVE_INFINITY,
-                StrictMath.pow(Double.POSITIVE_INFINITY, 1.0));        
-        
-        assertEquals("Incorrect value was returned.", 0.0,
-                StrictMath.pow(-0.0, 2.0));
-        assertEquals("Incorrect value was returned.", 0.0,
-                StrictMath.pow(Double.NEGATIVE_INFINITY, -2.0));  
-        
-        assertEquals("Incorrect value was returned.", -0.0,
-                StrictMath.pow(-0.0, 1.0));
-        assertEquals("Incorrect value was returned.", -0.0,
-                StrictMath.pow(Double.NEGATIVE_INFINITY, -1.0));  
-        
-        assertEquals("Incorrect value was returned.", Double.POSITIVE_INFINITY,
-                StrictMath.pow(-0.0, -2.0));
-        assertEquals("Incorrect value was returned.", Double.POSITIVE_INFINITY,
-                StrictMath.pow(Double.NEGATIVE_INFINITY, 2.0)); 
-        
-        assertEquals("Incorrect value was returned.", Double.NEGATIVE_INFINITY,
-                StrictMath.pow(-0.0, -1.0));
-        assertEquals("Incorrect value was returned.", Double.NEGATIVE_INFINITY,
-                StrictMath.pow(Double.NEGATIVE_INFINITY, 1.0));   
-        
-        assertEquals("Incorrect value was returned.", -0.999,
-                StrictMath.pow(-0.999, 1.0));   
-        
-        assertEquals("Incorrect value was returned.", Double.NaN,
-                StrictMath.pow(-0.999, 1.1));
-    }
+	/**
+	 * @tests java.lang.StrictMath#abs(double)
+	 */
+	public void test_absD() {
+		// Test for method double java.lang.StrictMath.abs(double)
 
-    /**
-     * @tests java.lang.StrictMath#tan(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "tan",
-        args = {double.class}
-    )
-    public void test_tan(){
-        // tests changes in fdlibm5.3
-        assertTrue(Double.longBitsToDouble( 4850236541654588678L) == StrictMath.tan( 1.7765241907548024E+269));
-        assertEquals("Incorrect value of tan was returned.",
-                Double.NaN, StrictMath.tan(Double.NaN));
-        assertEquals("Incorrect value of tan was returned.",
-                Double.NaN, StrictMath.tan(Double.POSITIVE_INFINITY));     
-        assertEquals("Incorrect value of tan was returned.",
-                Double.NaN, StrictMath.tan(Double.NEGATIVE_INFINITY));
-        assertEquals("Incorrect value of tan was returned.",
-                0.0, StrictMath.tan(0.0));    
-        assertEquals("Incorrect value of tan was returned.",
-                -0.0, StrictMath.tan(-0.0));            
-    }
+		assertTrue("Incorrect double abs value",
+				(StrictMath.abs(-1908.8976) == 1908.8976));
+		assertTrue("Incorrect double abs value",
+				(StrictMath.abs(1908.8976) == 1908.8976));
+	}
 
-    /**
-     * @tests java.lang.StrictMath#asin(double)
-     * @tests java.lang.StrictMath#exp(double)
-     * @tests java.lang.StrictMath#sinh(double)
-     * @tests java.lang.StrictMath#expm1(double)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Checks one value.",
-            method = "asin",
-            args = {double.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Checks one value.",
-            method = "exp",
-            args = {double.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Checks one value.",
-            method = "sinh",
-            args = {double.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Checks one value.",
-            method = "expm1",
-            args = {double.class}
-        )
-    })
-    public void test_inexact(){
-        assertTrue( 4485585228743840298L == Double.doubleToRawLongBits(StrictMath.asin(7.4505805E-9)));
-        assertTrue( 4607182418816794624L == Double.doubleToRawLongBits(StrictMath.exp(3.7252902E-9)));
-        assertTrue( 4481081628995577220L == Double.doubleToRawLongBits(StrictMath.sinh(3.7252902E-9)));
-        assertTrue(-4616189618054758400L == Double.doubleToRawLongBits(StrictMath.expm1(-40)));
-    }
-    
-    /**
-     * @tests java.lang.StrictMath#abs(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {double.class}
-    )
-    public void test_absD() {
-        // Test for method double java.lang.StrictMath.abs(double)
+	/**
+	 * @tests java.lang.StrictMath#abs(float)
+	 */
+	public void test_absF() {
+		// Test for method float java.lang.StrictMath.abs(float)
+		assertTrue("Incorrect float abs value",
+				(StrictMath.abs(-1908.8976f) == 1908.8976f));
+		assertTrue("Incorrect float abs value",
+				(StrictMath.abs(1908.8976f) == 1908.8976f));
+	}
 
-        assertTrue("Incorrect double abs value",
-                (StrictMath.abs(-1908.8976) == 1908.8976));
-        assertTrue("Incorrect double abs value",
-                (StrictMath.abs(1908.8976) == 1908.8976));
-        
-        assertEquals(0.0, StrictMath.abs(0.0));
-        assertEquals(0.0, StrictMath.abs(-0.0));
-        assertEquals(Double.POSITIVE_INFINITY, StrictMath.abs(Double.POSITIVE_INFINITY));    
-        assertEquals(Double.POSITIVE_INFINITY, StrictMath.abs(Double.NEGATIVE_INFINITY));      
-        assertEquals(Double.NaN, StrictMath.abs(Double.NaN));      
-    }
+	/**
+	 * @tests java.lang.StrictMath#abs(int)
+	 */
+	public void test_absI() {
+		// Test for method int java.lang.StrictMath.abs(int)
+		assertTrue("Incorrect int abs value",
+				(StrictMath.abs(-1908897) == 1908897));
+		assertTrue("Incorrect int abs value",
+				(StrictMath.abs(1908897) == 1908897));
+	}
 
-    /**
-     * @tests java.lang.StrictMath#abs(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {float.class}
-    )
-    public void test_absF() {
-        // Test for method float java.lang.StrictMath.abs(float)
-        assertTrue("Incorrect float abs value",
-                (StrictMath.abs(-1908.8976f) == 1908.8976f));
-        assertTrue("Incorrect float abs value",
-                (StrictMath.abs(1908.8976f) == 1908.8976f));
-        
-        assertEquals(0f, StrictMath.abs(0f));
-        assertEquals(0f, StrictMath.abs(-0f));
-        assertEquals(Float.POSITIVE_INFINITY, StrictMath.abs(Float.POSITIVE_INFINITY));    
-        assertEquals(Float.POSITIVE_INFINITY, StrictMath.abs(Float.NEGATIVE_INFINITY));      
-        assertEquals(Float.NaN, StrictMath.abs(Float.NaN));        
-    }
+	/**
+	 * @tests java.lang.StrictMath#abs(long)
+	 */
+	public void test_absJ() {
+		// Test for method long java.lang.StrictMath.abs(long)
+		assertTrue("Incorrect long abs value", (StrictMath
+				.abs(-19088976000089L) == 19088976000089L));
+		assertTrue("Incorrect long abs value",
+				(StrictMath.abs(19088976000089L) == 19088976000089L));
+	}
 
-    /**
-     * @tests java.lang.StrictMath#abs(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {int.class}
-    )
-    public void test_absI() {
-        // Test for method int java.lang.StrictMath.abs(int)
-        assertTrue("Incorrect int abs value",
-                (StrictMath.abs(-1908897) == 1908897));
-        assertTrue("Incorrect int abs value",
-                (StrictMath.abs(1908897) == 1908897));
-        
-        assertEquals(Integer.MIN_VALUE, StrictMath.abs(Integer.MIN_VALUE));
-    }
+	/**
+	 * @tests java.lang.StrictMath#acos(double)
+	 */
+	public void test_acosD() {
+		// Test for method double java.lang.StrictMath.acos(double)
+		assertTrue("Returned incorrect arc cosine", StrictMath.cos(StrictMath
+				.acos(ADJ / HYP)) == ADJ / HYP);
+	}
 
-    /**
-     * @tests java.lang.StrictMath#abs(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {long.class}
-    )
-    public void test_absJ() {
-        // Test for method long java.lang.StrictMath.abs(long)
-        assertTrue("Incorrect long abs value", (StrictMath
-                .abs(-19088976000089L) == 19088976000089L));
-        assertTrue("Incorrect long abs value",
-                (StrictMath.abs(19088976000089L) == 19088976000089L));
-        
-        assertEquals(Long.MIN_VALUE, StrictMath.abs(Long.MIN_VALUE));        
-    }
+	/**
+	 * @tests java.lang.StrictMath#asin(double)
+	 */
+	public void test_asinD() {
+		// Test for method double java.lang.StrictMath.asin(double)
+		assertTrue("Returned incorrect arc sine", StrictMath.sin(StrictMath
+				.asin(OPP / HYP)) == OPP / HYP);
+	}
 
-    /**
-     * @tests java.lang.StrictMath#acos(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "acos",
-        args = {double.class}
-    )
-    public void test_acosD() {
-        // Test for method double java.lang.StrictMath.acos(double)
-        assertTrue("Returned incorrect arc cosine", StrictMath.cos(StrictMath
-                .acos(ADJ / HYP)) == ADJ / HYP);
-        
-        assertEquals(Double.NaN, StrictMath.acos(Double.NaN));
-        assertEquals(Double.NaN, StrictMath.acos(1.1));        
-    }
+	/**
+	 * @tests java.lang.StrictMath#atan(double)
+	 */
+	public void test_atanD() {
+		// Test for method double java.lang.StrictMath.atan(double)
+		double answer = StrictMath.tan(StrictMath.atan(1.0));
+		assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+				&& answer >= 9.9999999999999983E-1);
+	}
 
-    /**
-     * @tests java.lang.StrictMath#asin(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "asin",
-        args = {double.class}
-    )
-    public void test_asinD() {
-        // Test for method double java.lang.StrictMath.asin(double)
-        assertTrue("Returned incorrect arc sine", StrictMath.sin(StrictMath
-                .asin(OPP / HYP)) == OPP / HYP);
-        
-        assertEquals(Double.NaN, StrictMath.asin(Double.NaN));
-        assertEquals(Double.NaN, StrictMath.asin(1.1));        
-        assertEquals(0.0, StrictMath.asin(0.0));  
-        assertEquals(-0.0, StrictMath.asin(-0.0));          
-    }
-
-    /**
-     * @tests java.lang.StrictMath#atan(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Doesn't check boundary values.",
-        method = "atan",
-        args = {double.class}
-    )
-    public void test_atanD() {
-        // Test for method double java.lang.StrictMath.atan(double)
-        double answer = StrictMath.tan(StrictMath.atan(1.0));
-        assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
-                && answer >= 9.9999999999999983E-1);
-    }
-
-    /**
-     * @tests java.lang.StrictMath#atan2(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "atan2",
-        args = {double.class, double.class}
-    )
-    public void test_atan2DD() {
-        // Test for method double java.lang.StrictMath.atan2(double, double)
-        double answer = StrictMath.atan(StrictMath.tan(1.0));
-        assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
-                && answer >= 9.9999999999999983E-1);
-        
-        assertEquals(Double.NaN, StrictMath.atan2(Double.NaN, 1.0));
-        assertEquals(Double.NaN, StrictMath.atan2(Double.NaN, 1.0));
-        
-        assertEquals(0.0, StrictMath.atan2(0.0, 1.0));
-        assertEquals(0.0, StrictMath.atan2(1.0, Double.POSITIVE_INFINITY));   
-        
-        assertEquals(-0.0, StrictMath.atan2(-0.0, 1.0));      
-        assertEquals(-0.0, StrictMath.atan2(-1.0, Double.POSITIVE_INFINITY)); 
-        
-        assertEquals(StrictMath.PI, StrictMath.atan2(0.0, -1.0));      
-        assertEquals(StrictMath.PI, StrictMath.atan2(1.0, 
-                                                     Double.NEGATIVE_INFINITY));     
-        
-        assertEquals(-StrictMath.PI, StrictMath.atan2(-0.0, -1.0));   
-        assertEquals(-StrictMath.PI, StrictMath.atan2(-1.0, 
-                                                     Double.NEGATIVE_INFINITY));     
-        
-        assertEquals(StrictMath.PI/2, StrictMath.atan2(1.0, 0.0));   
-        assertEquals(StrictMath.PI/2, StrictMath.atan2(1.0, -0.0));        
-        assertEquals(StrictMath.PI/2, StrictMath.atan2(Double.POSITIVE_INFINITY, 0.0)); 
-        
-        assertEquals(-StrictMath.PI/2, StrictMath.atan2(-1.0, 0.0));   
-        assertEquals(-StrictMath.PI/2, StrictMath.atan2(-1.0, -0.0));        
-        assertEquals(-StrictMath.PI/2, StrictMath.atan2(Double.NEGATIVE_INFINITY, 1.0));  
-        
-        assertEquals(StrictMath.PI/4, StrictMath.atan2(Double.POSITIVE_INFINITY, 
-                                                     Double.POSITIVE_INFINITY)); 
-        assertEquals(3*StrictMath.PI/4, 
-                                      StrictMath.atan2(Double.POSITIVE_INFINITY, 
-                                                     Double.NEGATIVE_INFINITY));     
-        
-        assertEquals(-StrictMath.PI/4, 
-                StrictMath.atan2(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));  
-        
-        assertEquals(-3*StrictMath.PI/4, 
-                                      StrictMath.atan2(Double.NEGATIVE_INFINITY, 
-                                                     Double.NEGATIVE_INFINITY));        
-    }
+	/**
+	 * @tests java.lang.StrictMath#atan2(double, double)
+	 */
+	public void test_atan2DD() {
+		// Test for method double java.lang.StrictMath.atan2(double, double)
+		double answer = StrictMath.atan(StrictMath.tan(1.0));
+		assertTrue("Returned incorrect arc tangent: " + answer, answer <= 1.0
+				&& answer >= 9.9999999999999983E-1);
+	}
     
     /**
      * @tests java.lang.StrictMath#cbrt(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "cbrt",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_cbrt_D() {
         // Test for special situations
@@ -392,11 +136,11 @@
                 Double.NEGATIVE_INFINITY, StrictMath
                         .cbrt(Double.NEGATIVE_INFINITY));
         assertEquals(Double.doubleToLongBits(0.0), Double
-                .doubleToLongBits(StrictMath.cbrt(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(StrictMath.cbrt(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(StrictMath.cbrt(-0.0)));
+				.doubleToLongBits(StrictMath.cbrt(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(StrictMath.cbrt(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(StrictMath.cbrt(-0.0)));
 
         assertEquals("Should return 3.0", 3.0, StrictMath.cbrt(27.0));
         assertEquals("Should return 23.111993172558684", 23.111993172558684,
@@ -420,67 +164,159 @@
         }
     }
 
-    /**
-     * @tests java.lang.StrictMath#ceil(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ceil",
-        args = {double.class}
-    )
-    public void test_ceilD() {
-        // Test for method double java.lang.StrictMath.ceil(double)
+	/**
+	 * @tests java.lang.StrictMath#ceil(double)
+	 */
+	public void test_ceilD() {
+		// Test for method double java.lang.StrictMath.ceil(double)
                 assertEquals("Incorrect ceiling for double",
                              79, StrictMath.ceil(78.89), 0.0);
-        assertEquals("Incorrect ceiling for double",
+		assertEquals("Incorrect ceiling for double",
                              -78, StrictMath.ceil(-78.89), 0.0);
+	}
+	
+	/**
+     * @tests {@link java.lang.StrictMath#copySign(double, double)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_copySign_DD() {
+        for (int i = 0; i < COPYSIGN_DD_CASES.length; i++) {
+            final double magnitude = COPYSIGN_DD_CASES[i];
+            final long absMagnitudeBits = Double.doubleToLongBits(StrictMath
+                    .abs(magnitude));
+            final long negMagnitudeBits = Double.doubleToLongBits(-StrictMath
+                    .abs(magnitude));
+
+            // cases for NaN
+            assertEquals("If the sign is NaN, the result should be positive.",
+                    absMagnitudeBits, Double.doubleToLongBits(StrictMath
+                            .copySign(magnitude, Double.NaN)));
+            assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+                    .copySign(Double.NaN, magnitude)));
+
+            for (int j = 0; j < COPYSIGN_DD_CASES.length; j++) {
+                final double sign = COPYSIGN_DD_CASES[j];
+                final long resultBits = Double.doubleToLongBits(StrictMath
+                        .copySign(magnitude, sign));
+
+                if (sign > 0 || Double.valueOf(+0.0).equals(sign)
+                        || Double.valueOf(0.0).equals(sign)) {
+                    assertEquals(
+                            "If the sign is positive, the result should be positive.",
+                            absMagnitudeBits, resultBits);
+                }
+                if (sign < 0 || Double.valueOf(-0.0).equals(sign)) {
+                    assertEquals(
+                            "If the sign is negative, the result should be negative.",
+                            negMagnitudeBits, resultBits);
+                }
+            }
+        }
+
+        assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+                .copySign(Double.NaN, Double.NaN)));
+
+        try {
+            StrictMath.copySign((Double) null, 2.3);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.copySign(2.3, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.copySign((Double) null, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
         
-        assertEquals("Incorrect ceiling for mathematical integer",
-                             -78, StrictMath.ceil(-78), 0.0);  
-        assertEquals("Incorrect ceiling for NaN",
-                                       Double.NaN, StrictMath.ceil(Double.NaN));
-        assertEquals("Incorrect ceiling for positive infinity", 
-                Double.POSITIVE_INFINITY, 
-                StrictMath.ceil(Double.POSITIVE_INFINITY));        
-        assertEquals("Incorrect ceiling for negative infinity", 
-                Double.NEGATIVE_INFINITY, 
-                StrictMath.ceil(Double.NEGATIVE_INFINITY));  
-        assertEquals("Incorrect ceiling for positive zero.", 
-                0.0, StrictMath.ceil(0.0));
-        assertEquals("Incorrect ceiling for negative zero.", 
-                -0.0, StrictMath.ceil(-0.0)); 
-        assertEquals("Incorrect ceiling for negative zero.", 
-                -0.0, StrictMath.ceil(-0.5));         
+		double d = Double.longBitsToDouble(0xfff8000000000000L);
+		assertEquals(1.0, StrictMath.copySign(1.0, d), 0d);
     }
 
     /**
-     * @tests java.lang.StrictMath#cos(double)
+     * @tests {@link java.lang.StrictMath#copySign(float, float)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "cos",
-        args = {double.class}
-    )
-    public void test_cosD() {
-        // Test for method double java.lang.StrictMath.cos(double)
+    @SuppressWarnings("boxing")
+    public void test_copySign_FF() {
+        for (int i = 0; i < COPYSIGN_FF_CASES.length; i++) {
+            final float magnitude = COPYSIGN_FF_CASES[i];
+            final int absMagnitudeBits = Float.floatToIntBits(StrictMath
+                    .abs(magnitude));
+            final int negMagnitudeBits = Float.floatToIntBits(-StrictMath
+                    .abs(magnitude));
 
-        assertTrue("Returned incorrect cosine", StrictMath.cos(StrictMath
-                .acos(ADJ / HYP)) == ADJ / HYP);
-        assertEquals("Returned incorrect cosine", StrictMath.cos(Double.NaN), 
-                                                                 Double.NaN);        
+            // cases for NaN
+            assertEquals("If the sign is NaN, the result should be positive.",
+                    absMagnitudeBits, Float.floatToIntBits(StrictMath.copySign(
+                            magnitude, Float.NaN)));
+            assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+                    .copySign(Float.NaN, magnitude)));
+
+            for (int j = 0; j < COPYSIGN_FF_CASES.length; j++) {
+                final float sign = COPYSIGN_FF_CASES[j];
+                final int resultBits = Float.floatToIntBits(StrictMath
+                        .copySign(magnitude, sign));
+                if (sign > 0 || Float.valueOf(+0.0f).equals(sign)
+                        || Float.valueOf(0.0f).equals(sign)) {
+                    assertEquals(
+                            "If the sign is positive, the result should be positive.",
+                            absMagnitudeBits, resultBits);
+                }
+                if (sign < 0 || Float.valueOf(-0.0f).equals(sign)) {
+                    assertEquals(
+                            "If the sign is negative, the result should be negative.",
+                            negMagnitudeBits, resultBits);
+                }
+            }
+        }
+
+        assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+                .copySign(Float.NaN, Float.NaN)));
+
+        try {
+            StrictMath.copySign((Float) null, 2.3f);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.copySign(2.3f, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.copySign((Float) null, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        
+		float f = Float.intBitsToFloat(0xffc00000);
+		assertEquals(1.0f, StrictMath.copySign(1.0f, f), 0f);
     }
+
+	/**
+	 * @tests java.lang.StrictMath#cos(double)
+	 */
+	public void test_cosD() {
+		// Test for method double java.lang.StrictMath.cos(double)
+
+		assertTrue("Returned incorrect cosine", StrictMath.cos(StrictMath
+				.acos(ADJ / HYP)) == ADJ / HYP);
+	}
     
     /**
      * @tests java.lang.StrictMath#cosh(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "cosh",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_cosh_D() {
         // Test for special situations        
@@ -512,39 +348,21 @@
                 .cosh(Double.MIN_VALUE));
     }
 
-    /**
-     * @tests java.lang.StrictMath#exp(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "exp",
-        args = {double.class}
-    )
-    public void test_expD() {
-        // Test for method double java.lang.StrictMath.exp(double)
-        assertTrue("Incorrect answer returned for simple power", StrictMath
-                .abs(StrictMath.exp(4D) - StrictMath.E * StrictMath.E
-                        * StrictMath.E * StrictMath.E) < 0.1D);
-        assertTrue("Incorrect answer returned for larger power", StrictMath
-                .log(StrictMath.abs(StrictMath.exp(5.5D)) - 5.5D) < 10.0D);
-        assertEquals("Returned incorrect value for NaN argument", Double.NaN, 
-                                                    StrictMath.exp(Double.NaN));
-        assertEquals("Returned incorrect value for positive infinity.", 
-            Double.POSITIVE_INFINITY, StrictMath.exp(Double.POSITIVE_INFINITY));    
-        assertEquals("Returned incorrect value for negative infinity.", 
-                                 0.0, StrictMath.exp(Double.NEGATIVE_INFINITY));  
-    }
+	/**
+	 * @tests java.lang.StrictMath#exp(double)
+	 */
+	public void test_expD() {
+		// Test for method double java.lang.StrictMath.exp(double)
+		assertTrue("Incorrect answer returned for simple power", StrictMath
+				.abs(StrictMath.exp(4D) - StrictMath.E * StrictMath.E
+						* StrictMath.E * StrictMath.E) < 0.1D);
+		assertTrue("Incorrect answer returned for larger power", StrictMath
+				.log(StrictMath.abs(StrictMath.exp(5.5D)) - 5.5D) < 10.0D);
+	}
     
     /**
      * @tests java.lang.StrictMath#expm1(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "expm1",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_expm1_D() {
         //Test for special cases        
@@ -554,11 +372,11 @@
         assertEquals("Should return -1.0", -1.0, StrictMath
                 .expm1(Double.NEGATIVE_INFINITY));
         assertEquals(Double.doubleToLongBits(0.0), Double
-                .doubleToLongBits(StrictMath.expm1(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(StrictMath.expm1(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(StrictMath.expm1(-0.0)));
+				.doubleToLongBits(StrictMath.expm1(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(StrictMath.expm1(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(StrictMath.expm1(-0.0)));
 
         assertEquals("Should return -9.999950000166666E-6",
                 -9.999950000166666E-6, StrictMath.expm1(-0.00001));
@@ -574,44 +392,61 @@
        
     }    
 
-    /**
-     * @tests java.lang.StrictMath#floor(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "floor",
-        args = {double.class}
-    )
-    public void test_floorD() {
-        // Test for method double java.lang.StrictMath.floor(double)
+	/**
+	 * @tests java.lang.StrictMath#floor(double)
+	 */
+	public void test_floorD() {
+		// Test for method double java.lang.StrictMath.floor(double)
                 assertEquals("Incorrect floor for double",
                              78, StrictMath.floor(78.89), 0.0);
-        assertEquals("Incorrect floor for double",
+		assertEquals("Incorrect floor for double",
                              -79, StrictMath.floor(-78.89), 0.0);
-        assertEquals("Incorrect floor for mathematical integer",
-                             -79, StrictMath.floor(-79), 0.0);
-        assertEquals("Incorrect floor for NaN",
-                        Double.NaN, StrictMath.floor(Double.NaN));    
-        assertEquals("Incorrect floor for positive infinity.",
-          Double.POSITIVE_INFINITY, StrictMath.floor(Double.POSITIVE_INFINITY));    
-        assertEquals("Incorrect floor for negative infinity.",
-          Double.NEGATIVE_INFINITY, StrictMath.floor(Double.NEGATIVE_INFINITY));  
-        assertEquals("Incorrect floor for positive zero.",
-                                                    0.0, StrictMath.floor(0.0)); 
-        assertEquals("Incorrect floor for negative zero.",
-                                                  -0.0, StrictMath.floor(-0.0));        
+	}
+	
+	/**
+     * @tests {@link java.lang.StrictMath#getExponent(double)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_getExponent_D() {
+        for (int i = 0; i < GETEXPONENT_D_CASES.length; i++) {
+            final double number = GETEXPONENT_D_CASES[i];
+            final int result = GETEXPONENT_D_RESULTS[i];
+            assertEquals("Wrong result of getExponent(double).", result,
+                    StrictMath.getExponent(number));
+        }
+
+        try {
+            StrictMath.getExponent((Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests {@link java.lang.StrictMath#getExponent(float)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_getExponent_F() {
+        for (int i = 0; i < GETEXPONENT_F_CASES.length; i++) {
+            final float number = GETEXPONENT_F_CASES[i];
+            final int result = GETEXPONENT_F_RESULTS[i];
+            assertEquals("Wrong result of getExponent(float).", result,
+                    StrictMath.getExponent(number));
+        }
+        try {
+            StrictMath.getExponent((Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
     
     /**
      * @tests java.lang.StrictMath#hypot(double, double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hypot",
-        args = {double.class, double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_hypot_DD() {
         // Test for special cases
@@ -649,77 +484,37 @@
 
     }
 
-    /**
-     * @tests java.lang.StrictMath#IEEEremainder(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IEEEremainder",
-        args = {double.class, double.class}
-    )
-    public void test_IEEEremainderDD() {
-        // Test for method double java.lang.StrictMath.IEEEremainder(double,
-        // double)
-        assertEquals("Incorrect remainder returned", 0.0, StrictMath.IEEEremainder(
-                1.0, 1.0), 0.0);
-        assertTrue(
-                "Incorrect remainder returned",
-                StrictMath.IEEEremainder(1.32, 89.765) >= 1.4705063220631647E-2
-                        || StrictMath.IEEEremainder(1.32, 89.765) >= 1.4705063220631649E-2);
-        
-        assertEquals(Double.NaN, StrictMath.IEEEremainder(Double.NaN, 0.0));
-        assertEquals(Double.NaN, StrictMath.IEEEremainder(0.0, Double.NaN));
-        assertEquals(Double.NaN, StrictMath.IEEEremainder(Double.POSITIVE_INFINITY, 0.0));
-        assertEquals(Double.NaN, StrictMath.IEEEremainder(Double.NEGATIVE_INFINITY, 0.0));
-        assertEquals(Double.NaN, StrictMath.IEEEremainder(0.0, 0.0));
-        assertEquals(Double.NaN, StrictMath.IEEEremainder(-0.0, 0.0));
-        
-        assertEquals(1.0, StrictMath.IEEEremainder(1.0, Double.POSITIVE_INFINITY));
-        assertEquals(1.0, StrictMath.IEEEremainder(1.0, Double.NEGATIVE_INFINITY));        
-        
-    }
+	/**
+	 * @tests java.lang.StrictMath#IEEEremainder(double, double)
+	 */
+	public void test_IEEEremainderDD() {
+		// Test for method double java.lang.StrictMath.IEEEremainder(double,
+		// double)
+		assertEquals("Incorrect remainder returned", 0.0, StrictMath.IEEEremainder(
+				1.0, 1.0), 0.0);
+		assertTrue(
+				"Incorrect remainder returned",
+				StrictMath.IEEEremainder(1.32, 89.765) >= 1.4705063220631647E-2
+						|| StrictMath.IEEEremainder(1.32, 89.765) >= 1.4705063220631649E-2);
+	}
 
-    /**
-     * @tests java.lang.StrictMath#log(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log",
-        args = {double.class}
-    )
-    public void test_logD() {
-        // Test for method double java.lang.StrictMath.log(double)
-        for (double d = 10; d >= -10; d -= 0.5) {
-            double answer = StrictMath.log(StrictMath.exp(d));
-            assertTrue("Answer does not equal expected answer for d = " + d
-                    + " answer = " + answer,
-                    StrictMath.abs(answer - d) <= StrictMath
-                            .abs(d * 0.00000001));
-        }
-        
-        assertEquals("Returned incorrect value for NaN.", 
-                                        Double.NaN, StrictMath.log(Double.NaN));
-        assertEquals("Returned incorrect value for positive infinity.", 
-            Double.POSITIVE_INFINITY, StrictMath.log(Double.POSITIVE_INFINITY));     
-        assertEquals("Returned incorrect value for negative infinity.", 
-                          Double.NaN, StrictMath.log(Double.NEGATIVE_INFINITY));  
-        assertEquals("Returned incorrect value for positive zero.", 
-                                 Double.NEGATIVE_INFINITY, StrictMath.log(0.0));  
-        assertEquals("Returned incorrect value for negative zero.", 
-                                Double.NEGATIVE_INFINITY, StrictMath.log(-0.0));        
-    }
+	/**
+	 * @tests java.lang.StrictMath#log(double)
+	 */
+	public void test_logD() {
+		// Test for method double java.lang.StrictMath.log(double)
+		for (double d = 10; d >= -10; d -= 0.5) {
+			double answer = StrictMath.log(StrictMath.exp(d));
+			assertTrue("Answer does not equal expected answer for d = " + d
+					+ " answer = " + answer,
+					StrictMath.abs(answer - d) <= StrictMath
+							.abs(d * 0.00000001));
+		}
+	}
     
     /**
      * @tests java.lang.StrictMath#log10(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log10",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_log10_D() {
         // Test for special cases        
@@ -754,12 +549,6 @@
     /**
      * @tests java.lang.StrictMath#log1p(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "log1p",
-        args = {double.class}
-    )
     @SuppressWarnings("boxing")
     public void test_log1p_D() {
         // Test for special cases
@@ -771,11 +560,11 @@
                 Double.POSITIVE_INFINITY, StrictMath
                         .log1p(Double.POSITIVE_INFINITY));
         assertEquals(Double.doubleToLongBits(0.0), Double
-                .doubleToLongBits(StrictMath.log1p(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(StrictMath.log1p(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(StrictMath.log1p(-0.0)));
+				.doubleToLongBits(StrictMath.log1p(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(StrictMath.log1p(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(StrictMath.log1p(-0.0)));
 
         assertEquals("Should return -0.2941782295312541", -0.2941782295312541,
                 StrictMath.log1p(-0.254856327));
@@ -792,330 +581,659 @@
     /**
      * @tests java.lang.StrictMath#max(double, double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {double.class, double.class}
-    )
-    public void test_maxDD() {
-        // Test for method double java.lang.StrictMath.max(double, double)
-        assertEquals("Incorrect double max value", 1908897.6000089, StrictMath.max(
-                -1908897.6000089, 1908897.6000089), 0D);
-        assertEquals("Incorrect double max value", 1908897.6000089, StrictMath.max(2.0,
-                1908897.6000089), 0D);
-        assertEquals("Incorrect double max value", -2.0, StrictMath.max(-2.0,
-                -1908897.6000089), 0D);
+	public void test_maxDD() {
+		// Test for method double java.lang.StrictMath.max(double, double)
+		assertEquals("Incorrect double max value", 1908897.6000089, StrictMath.max(
+				-1908897.6000089, 1908897.6000089), 0D);
+		assertEquals("Incorrect double max value", 1908897.6000089, StrictMath.max(2.0,
+				1908897.6000089), 0D);
+		assertEquals("Incorrect double max value", -2.0, StrictMath.max(-2.0,
+				-1908897.6000089), 0D);
 
-        assertEquals("Incorrect double max value", Double.NaN, 
-                                               StrictMath.max(Double.NaN, 1.0));
-        assertEquals("Incorrect double max value", 0.0, 
-                                                     StrictMath.max(0.0, -0.0));        
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#max(float, float)
+	 */
+	public void test_maxFF() {
+		// Test for method float java.lang.StrictMath.max(float, float)
+		assertTrue("Incorrect float max value", StrictMath.max(-1908897.600f,
+				1908897.600f) == 1908897.600f);
+		assertTrue("Incorrect float max value", StrictMath.max(2.0f,
+				1908897.600f) == 1908897.600f);
+		assertTrue("Incorrect float max value", StrictMath.max(-2.0f,
+				-1908897.600f) == -2.0f);
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#max(int, int)
+	 */
+	public void test_maxII() {
+		// Test for method int java.lang.StrictMath.max(int, int)
+		assertEquals("Incorrect int max value", 19088976, StrictMath.max(-19088976,
+				19088976));
+		assertEquals("Incorrect int max value",
+				19088976, StrictMath.max(20, 19088976));
+		assertEquals("Incorrect int max value",
+				-20, StrictMath.max(-20, -19088976));
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#max(long, long)
+	 */
+	public void test_maxJJ() {
+		// Test for method long java.lang.StrictMath.max(long, long)
+		assertEquals("Incorrect long max value", 19088976000089L, StrictMath.max(-19088976000089L,
+				19088976000089L));
+		assertEquals("Incorrect long max value", 19088976000089L, StrictMath.max(20,
+				19088976000089L));
+		assertEquals("Incorrect long max value", -20, StrictMath.max(-20,
+				-19088976000089L));
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#min(double, double)
+	 */
+	public void test_minDD() {
+		// Test for method double java.lang.StrictMath.min(double, double)
+		assertEquals("Incorrect double min value", -1908897.6000089, StrictMath.min(
+				-1908897.6000089, 1908897.6000089), 0D);
+		assertEquals("Incorrect double min value", 2.0, StrictMath.min(2.0,
+				1908897.6000089), 0D);
+		assertEquals("Incorrect double min value", -1908897.6000089, StrictMath.min(-2.0,
+				-1908897.6000089), 0D);
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#min(float, float)
+	 */
+	public void test_minFF() {
+		// Test for method float java.lang.StrictMath.min(float, float)
+		assertTrue("Incorrect float min value", StrictMath.min(-1908897.600f,
+				1908897.600f) == -1908897.600f);
+		assertTrue("Incorrect float min value", StrictMath.min(2.0f,
+				1908897.600f) == 2.0f);
+		assertTrue("Incorrect float min value", StrictMath.min(-2.0f,
+				-1908897.600f) == -1908897.600f);
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#min(int, int)
+	 */
+	public void test_minII() {
+		// Test for method int java.lang.StrictMath.min(int, int)
+		assertEquals("Incorrect int min value", -19088976, StrictMath.min(-19088976,
+				19088976));
+		assertEquals("Incorrect int min value",
+				20, StrictMath.min(20, 19088976));
+		assertEquals("Incorrect int min value",
+				-19088976, StrictMath.min(-20, -19088976));
+
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#min(long, long)
+	 */
+	public void test_minJJ() {
+		// Test for method long java.lang.StrictMath.min(long, long)
+		assertEquals("Incorrect long min value", -19088976000089L, StrictMath.min(-19088976000089L,
+				19088976000089L));
+		assertEquals("Incorrect long min value", 20, StrictMath.min(20,
+				19088976000089L));
+		assertEquals("Incorrect long min value", -19088976000089L, StrictMath.min(-20,
+				-19088976000089L));
+	}
+	
+	 /**
+     * @tests {@link java.lang.StrictMath#nextAfter(double, double)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_nextAfter_DD() {
+        // test for most cases without exception
+        for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+            final double start = NEXTAFTER_DD_START_CASES[i][0];
+            final long nextUpBits = Double
+                    .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+            final long nextDownBits = Double
+                    .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][2]);
+
+            for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+                final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+                final long resultBits = Double.doubleToLongBits(StrictMath
+                        .nextAfter(start, direction));
+                final long directionBits = Double.doubleToLongBits(direction);
+                if (direction > start) {
+                    assertEquals("Result should be next up-number.",
+                            nextUpBits, resultBits);
+                } else if (direction < start) {
+                    assertEquals("Result should be next down-number.",
+                            nextDownBits, resultBits);
+                } else {
+                    assertEquals("Result should be direction.", directionBits,
+                            resultBits);
+                }
+            }
+        }
+
+        // test for cases with NaN
+        for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+                    .nextAfter(NEXTAFTER_DD_START_CASES[i][0], Double.NaN)));
+        }
+        for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+                    .nextAfter(Double.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+        }
+        assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+                .nextAfter(Double.NaN, Double.NaN)));
+
+        // test for exception
+        try {
+            StrictMath.nextAfter((Double) null, 2.3);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.nextAfter(2.3, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.nextAfter((Double) null, (Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.StrictMath#max(float, float)
+     * @tests {@link java.lang.StrictMath#nextAfter(float, double)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {float.class, float.class}
-    )
-    public void test_maxFF() {
-        // Test for method float java.lang.StrictMath.max(float, float)
-        assertTrue("Incorrect float max value", StrictMath.max(-1908897.600f,
-                1908897.600f) == 1908897.600f);
-        assertTrue("Incorrect float max value", StrictMath.max(2.0f,
-                1908897.600f) == 1908897.600f);
-        assertTrue("Incorrect float max value", StrictMath.max(-2.0f,
-                -1908897.600f) == -2.0f);
-        assertEquals("Incorrect float max value", Float.NaN, 
-                                                 StrictMath.max(Float.NaN, 1f));
-        assertEquals("Incorrect float max value", 0f, 
-                                                       StrictMath.max(0f, -0f));           
+    @SuppressWarnings("boxing")
+    public void test_nextAfter_FD() {
+        // test for most cases without exception
+        for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+            final float start = NEXTAFTER_FD_START_CASES[i][0];
+            final int nextUpBits = Float
+                    .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+            final int nextDownBits = Float
+                    .floatToIntBits(NEXTAFTER_FD_START_CASES[i][2]);
+
+            for (int j = 0; j < NEXTAFTER_DD_FD_DIRECTION_CASES.length; j++) {
+                final double direction = NEXTAFTER_DD_FD_DIRECTION_CASES[j];
+                final int resultBits = Float.floatToIntBits(StrictMath
+                        .nextAfter(start, direction));
+                if (direction > start) {
+                    assertEquals("Result should be next up-number.",
+                            nextUpBits, resultBits);
+                } else if (direction < start) {
+                    assertEquals("Result should be next down-number.",
+                            nextDownBits, resultBits);
+                } else {
+                    final int equivalentBits = Float.floatToIntBits(new Float(
+                            direction));
+                    assertEquals(
+                            "Result should be a number equivalent to direction.",
+                            equivalentBits, resultBits);
+                }
+            }
+        }
+
+        // test for cases with NaN
+        for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+                    .nextAfter(NEXTAFTER_FD_START_CASES[i][0], Float.NaN)));
+        }
+        for (int i = 0; i < NEXTAFTER_DD_FD_DIRECTION_CASES.length; i++) {
+            assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+                    .nextAfter(Float.NaN, NEXTAFTER_DD_FD_DIRECTION_CASES[i])));
+        }
+        assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+                .nextAfter(Float.NaN, Float.NaN)));
+
+        // test for exception
+        try {
+            StrictMath.nextAfter((Float) null, 2.3);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.nextAfter(2.3, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.nextAfter((Float) null, (Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.StrictMath#max(int, int)
+     * @tests {@link java.lang.StrictMath#nextUp(double)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {int.class, int.class}
-    )
-    public void test_maxII() {
-        // Test for method int java.lang.StrictMath.max(int, int)
-        assertEquals("Incorrect int max value", 19088976, StrictMath.max(-19088976,
-                19088976));
-        assertEquals("Incorrect int max value",
-                19088976, StrictMath.max(20, 19088976));
-        assertEquals("Incorrect int max value",
-                -20, StrictMath.max(-20, -19088976));
-        assertEquals("Returned incorrect value.", Integer.MAX_VALUE, 
-                      StrictMath.max(Integer.MAX_VALUE, 1));  
-        assertEquals("Returned incorrect value.", Integer.MIN_VALUE, 
-                StrictMath.max(Integer.MIN_VALUE, Integer.MIN_VALUE));         
+    @SuppressWarnings("boxing")
+    public void test_nextUp_D() {
+        // This method is semantically equivalent to nextAfter(d,
+        // Double.POSITIVE_INFINITY),
+        // so we use the data of test_nextAfter_DD
+        for (int i = 0; i < NEXTAFTER_DD_START_CASES.length; i++) {
+            final double start = NEXTAFTER_DD_START_CASES[i][0];
+            final long nextUpBits = Double
+                    .doubleToLongBits(NEXTAFTER_DD_START_CASES[i][1]);
+            final long resultBits = Double.doubleToLongBits(StrictMath
+                    .nextUp(start));
+            assertEquals("Result should be next up-number.", nextUpBits,
+                    resultBits);
+        }
+
+        // test for cases with NaN
+        assertTrue("The result should be NaN.", Double.isNaN(StrictMath
+                .nextUp(Double.NaN)));
+
+        // test for exception
+        try {
+            StrictMath.nextUp((Double) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.StrictMath#max(long, long)
+     * @tests {@link java.lang.StrictMath#nextUp(float)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {long.class, long.class}
-    )
-    public void test_maxJJ() {
-        // Test for method long java.lang.StrictMath.max(long, long)
-        assertEquals("Incorrect long max value", 19088976000089L, StrictMath.max(-19088976000089L,
-                19088976000089L));
-        assertEquals("Incorrect long max value", 19088976000089L, StrictMath.max(20,
-                19088976000089L));
-        assertEquals("Incorrect long max value", -20, StrictMath.max(-20,
-                -19088976000089L));
-        
-        assertEquals("Returned incorrect value.", Long.MAX_VALUE, 
-                StrictMath.max(Long.MAX_VALUE, 1));  
-        assertEquals("Returned incorrect value.", Long.MIN_VALUE, 
-          StrictMath.max(Long.MIN_VALUE, Long.MIN_VALUE));         
+    @SuppressWarnings("boxing")
+    public void test_nextUp_F() {
+        // This method is semantically equivalent to nextAfter(f,
+        // Float.POSITIVE_INFINITY),
+        // so we use the data of test_nextAfter_FD
+        for (int i = 0; i < NEXTAFTER_FD_START_CASES.length; i++) {
+            final float start = NEXTAFTER_FD_START_CASES[i][0];
+            final int nextUpBits = Float
+                    .floatToIntBits(NEXTAFTER_FD_START_CASES[i][1]);
+            final int resultBits = Float.floatToIntBits(StrictMath
+                    .nextUp(start));
+            assertEquals("Result should be next up-number.", nextUpBits,
+                    resultBits);
+        }
+
+        // test for cases with NaN
+        assertTrue("The result should be NaN.", Float.isNaN(StrictMath
+                .nextUp(Float.NaN)));
+
+        // test for exception
+        try {
+            StrictMath.nextUp((Float) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+	/**
+	 * @tests java.lang.StrictMath#pow(double, double)
+	 */
+	public void test_powDD() {
+		// Test for method double java.lang.StrictMath.pow(double, double)
+		assertTrue("pow returned incorrect value",
+				(long) StrictMath.pow(2, 8) == 256l);
+		assertTrue("pow returned incorrect value",
+				StrictMath.pow(2, -8) == 0.00390625d);
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#rint(double)
+	 */
+	public void test_rintD() {
+		// Test for method double java.lang.StrictMath.rint(double)
+		assertEquals("Failed to round properly - up to odd",
+				3.0, StrictMath.rint(2.9), 0D);
+		assertTrue("Failed to round properly - NaN", Double.isNaN(StrictMath
+				.rint(Double.NaN)));
+		assertEquals("Failed to round properly down  to even", 2.0, StrictMath
+				.rint(2.1), 0D);
+		assertTrue("Failed to round properly " + 2.5 + " to even", StrictMath
+				.rint(2.5) == 2.0);
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#round(double)
+	 */
+	public void test_roundD() {
+		// Test for method long java.lang.StrictMath.round(double)
+		assertEquals("Incorrect rounding of a float",
+				-91, StrictMath.round(-90.89d));
+	}
+
+	/**
+	 * @tests java.lang.StrictMath#round(float)
+	 */
+	public void test_roundF() {
+		// Test for method int java.lang.StrictMath.round(float)
+		assertEquals("Incorrect rounding of a float",
+				-91, StrictMath.round(-90.89f));
+	}
+    
+	/**
+     * @tests {@link java.lang.StrictMath#scalb(double, int)}
+     * @since 1.6
+     */
+    @SuppressWarnings("boxing")
+    public void test_scalb_DI() {
+        // result is normal
+        assertEquals(4.1422946304E7, StrictMath.scalb(1.2345, 25));
+        assertEquals(3.679096698760986E-8, StrictMath.scalb(1.2345, -25));
+        assertEquals(1.2345, StrictMath.scalb(1.2345, 0));
+        assertEquals(7868514.304, StrictMath.scalb(0.2345, 25));
+
+        double normal = StrictMath.scalb(0.2345, -25);
+        assertEquals(6.98864459991455E-9, normal);
+        // precision kept
+        assertEquals(0.2345, StrictMath.scalb(normal, 25));
+
+        assertEquals(0.2345, StrictMath.scalb(0.2345, 0));
+        assertEquals(-4.1422946304E7, StrictMath.scalb(-1.2345, 25));
+        assertEquals(-6.98864459991455E-9, StrictMath.scalb(-0.2345, -25));
+        assertEquals(2.0, StrictMath.scalb(Double.MIN_NORMAL / 2, 1024));
+        assertEquals(64.0, StrictMath.scalb(Double.MIN_VALUE, 1080));
+        assertEquals(234, StrictMath.getExponent(StrictMath.scalb(1.0, 234)));
+        assertEquals(3.9999999999999996, StrictMath.scalb(Double.MAX_VALUE,
+                Double.MIN_EXPONENT));
+
+        // result is near infinity
+        double halfMax = StrictMath.scalb(1.0, Double.MAX_EXPONENT);
+        assertEquals(8.98846567431158E307, halfMax);
+        assertEquals(Double.MAX_VALUE, halfMax - StrictMath.ulp(halfMax)
+                + halfMax);
+        assertEquals(Double.POSITIVE_INFINITY, halfMax + halfMax);
+        assertEquals(1.7976931348623155E308, StrictMath.scalb(1.0 - StrictMath
+                .ulp(1.0), Double.MAX_EXPONENT + 1));
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+                1.0 - StrictMath.ulp(1.0), Double.MAX_EXPONENT + 2));
+
+        halfMax = StrictMath.scalb(-1.0, Double.MAX_EXPONENT);
+        assertEquals(-8.98846567431158E307, halfMax);
+        assertEquals(-Double.MAX_VALUE, halfMax + StrictMath.ulp(halfMax)
+                + halfMax);
+        assertEquals(Double.NEGATIVE_INFINITY, halfMax + halfMax);
+
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(0.345, 1234));
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath
+                .scalb(44.345E102, 934));
+        assertEquals(Double.NEGATIVE_INFINITY, StrictMath.scalb(-44.345E102,
+                934));
+
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+                Double.MIN_NORMAL / 2, 4000));
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+                Double.MIN_VALUE, 8000));
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+                Double.MAX_VALUE, 1));
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+                Double.POSITIVE_INFINITY, 0));
+        assertEquals(Double.POSITIVE_INFINITY, StrictMath.scalb(
+                Double.POSITIVE_INFINITY, -1));
+        assertEquals(Double.NEGATIVE_INFINITY, StrictMath.scalb(
+                Double.NEGATIVE_INFINITY, -1));
+        assertEquals(Double.NEGATIVE_INFINITY, StrictMath.scalb(
+                Double.NEGATIVE_INFINITY, Double.MIN_EXPONENT));
+
+        // result is subnormal/zero
+        long posZeroBits = Double.doubleToLongBits(+0.0);
+        long negZeroBits = Double.doubleToLongBits(-0.0);
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                +0.0, Integer.MAX_VALUE)));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                +0.0, -123)));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                +0.0, 0)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -0.0, 123)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -0.0, Integer.MIN_VALUE)));
+
+        assertEquals(Double.MIN_VALUE, StrictMath.scalb(1.0, -1074));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(1.0,
+                -1075)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -1.0, -1075)));
+
+        // precision lost
+        assertEquals(StrictMath.scalb(21.405, -1078), StrictMath.scalb(21.405,
+                -1079));
+        assertEquals(Double.MIN_VALUE, StrictMath.scalb(21.405, -1079));
+        assertEquals(-Double.MIN_VALUE, StrictMath.scalb(-21.405, -1079));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                21.405, -1080)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -21.405, -1080)));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                Double.MIN_VALUE, -1)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -Double.MIN_VALUE, -1)));
+        assertEquals(Double.MIN_VALUE, StrictMath.scalb(Double.MIN_NORMAL, -52));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                Double.MIN_NORMAL, -53)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -Double.MIN_NORMAL, -53)));
+        assertEquals(Double.MIN_VALUE, StrictMath
+                .scalb(Double.MAX_VALUE, -2098));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                Double.MAX_VALUE, -2099)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -Double.MAX_VALUE, -2099)));
+        assertEquals(Double.MIN_VALUE, StrictMath.scalb(Double.MIN_NORMAL / 3,
+                -51));
+        assertEquals(posZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                Double.MIN_NORMAL / 3, -52)));
+        assertEquals(negZeroBits, Double.doubleToLongBits(StrictMath.scalb(
+                -Double.MIN_NORMAL / 3, -52)));
+        double subnormal = StrictMath.scalb(Double.MIN_NORMAL / 3, -25);
+        assertEquals(2.2104123E-316, subnormal);
+        // precision lost
+        assertFalse(Double.MIN_NORMAL / 3 == StrictMath.scalb(subnormal, 25));
+
+        // NaN
+        assertTrue(Double.isNaN(StrictMath.scalb(Double.NaN, 1)));
+        assertTrue(Double.isNaN(StrictMath.scalb(Double.NaN, 0)));
+        assertTrue(Double.isNaN(StrictMath.scalb(Double.NaN, -120)));
+
+        assertEquals(1283457024, Double.doubleToLongBits(StrictMath.scalb(
+                Double.MIN_VALUE * 153, 23)));
+        assertEquals(-9223372035571318784L, Double.doubleToLongBits(StrictMath
+                .scalb(-Double.MIN_VALUE * 153, 23)));
+        assertEquals(36908406321184768L, Double.doubleToLongBits(StrictMath
+                .scalb(Double.MIN_VALUE * 153, 52)));
+        assertEquals(-9186463630533591040L, Double.doubleToLongBits(StrictMath
+                .scalb(-Double.MIN_VALUE * 153, 52)));
+
+        // test for exception
+        try {
+            StrictMath.scalb((Double) null, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.scalb(1.0, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.scalb((Double) null, 1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     /**
-     * @tests java.lang.StrictMath#min(double, double)
+     * @tests {@link java.lang.StrictMath#scalb(float, int)}
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {double.class, double.class}
-    )
-    public void test_minDD() {
-        // Test for method double java.lang.StrictMath.min(double, double)
-        assertEquals("Incorrect double min value", -1908897.6000089, StrictMath.min(
-                -1908897.6000089, 1908897.6000089), 0D);
-        assertEquals("Incorrect double min value", 2.0, StrictMath.min(2.0,
-                1908897.6000089), 0D);
-        assertEquals("Incorrect double min value", -1908897.6000089, StrictMath.min(-2.0,
-                -1908897.6000089), 0D);
-        assertEquals("Returned incorrect value.", Double.NaN, 
-                                               StrictMath.min(Double.NaN, 1.0));
-        assertEquals("Returned incorrect value.", Double.NaN, 
-                                               StrictMath.min(1.0, Double.NaN));      
-        assertEquals("Returned incorrect value.", -0.0, StrictMath.min(0.0, -0.0));  
-    }
+    @SuppressWarnings("boxing")
+    public void test_scalb_FI() {
+        // result is normal
+        assertEquals(4.1422946304E7f, StrictMath.scalb(1.2345f, 25));
+        assertEquals(3.679096698760986E-8f, StrictMath.scalb(1.2345f, -25));
+        assertEquals(1.2345f, StrictMath.scalb(1.2345f, 0));
+        assertEquals(7868514.304f, StrictMath.scalb(0.2345f, 25));
 
-    /**
-     * @tests java.lang.StrictMath#min(float, float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {float.class, float.class}
-    )
-    public void test_minFF() {
-        // Test for method float java.lang.StrictMath.min(float, float)
-        assertTrue("Incorrect float min value", StrictMath.min(-1908897.600f,
-                1908897.600f) == -1908897.600f);
-        assertTrue("Incorrect float min value", StrictMath.min(2.0f,
-                1908897.600f) == 2.0f);
-        assertTrue("Incorrect float min value", StrictMath.min(-2.0f,
-                -1908897.600f) == -1908897.600f);
-        
-        assertEquals("Returned incorrect value.", Float.NaN, 
-                StrictMath.min(Float.NaN, 1f));
-        assertEquals("Returned incorrect value.", Float.NaN, 
-                StrictMath.min(1f, Float.NaN));      
-        assertEquals("Returned incorrect value.", -0f, StrictMath.min(0f, -0f));  
-    }
+        float normal = StrictMath.scalb(0.2345f, -25);
+        assertEquals(6.98864459991455E-9f, normal);
+        // precision kept
+        assertEquals(0.2345f, StrictMath.scalb(normal, 25));
 
-    /**
-     * @tests java.lang.StrictMath#min(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {int.class, int.class}
-    )
-    public void test_minII() {
-        // Test for method int java.lang.StrictMath.min(int, int)
-        assertEquals("Incorrect int min value", -19088976, StrictMath.min(-19088976,
-                19088976));
-        assertEquals("Incorrect int min value",
-                20, StrictMath.min(20, 19088976));
-        assertEquals("Incorrect int min value",
-                -19088976, StrictMath.min(-20, -19088976));
+        assertEquals(0.2345f, StrictMath.scalb(0.2345f, 0));
+        assertEquals(-4.1422946304E7f, StrictMath.scalb(-1.2345f, 25));
+        assertEquals(-6.98864459991455E-9f, StrictMath.scalb(-0.2345f, -25));
+        assertEquals(2.0f, StrictMath.scalb(Float.MIN_NORMAL / 2, 128));
+        assertEquals(64.0f, StrictMath.scalb(Float.MIN_VALUE, 155));
+        assertEquals(34, StrictMath.getExponent(StrictMath.scalb(1.0f, 34)));
+        assertEquals(3.9999998f, StrictMath.scalb(Float.MAX_VALUE,
+                Float.MIN_EXPONENT));
 
-        assertEquals("Incorrect value was returned.", Double.MIN_VALUE, 
-                StrictMath.min(Double.MIN_VALUE, Double.MIN_VALUE));
-    }
+        // result is near infinity
+        float halfMax = StrictMath.scalb(1.0f, Float.MAX_EXPONENT);
+        assertEquals(1.7014118E38f, halfMax);
+        assertEquals(Float.MAX_VALUE, halfMax - StrictMath.ulp(halfMax)
+                + halfMax);
+        assertEquals(Float.POSITIVE_INFINITY, halfMax + halfMax);
+        assertEquals(3.4028233E38f, StrictMath.scalb(1.0f - StrictMath
+                .ulp(1.0f), Float.MAX_EXPONENT + 1));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+                1.0f - StrictMath.ulp(1.0f), Float.MAX_EXPONENT + 2));
 
-    /**
-     * @tests java.lang.StrictMath#min(long, long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {long.class, long.class}
-    )
-    public void test_minJJ() {
-        // Test for method long java.lang.StrictMath.min(long, long)
-        assertEquals("Incorrect long min value", -19088976000089L, StrictMath.min(-19088976000089L,
-                19088976000089L));
-        assertEquals("Incorrect long min value", 20, StrictMath.min(20,
-                19088976000089L));
-        assertEquals("Incorrect long min value", -19088976000089L, StrictMath.min(-20,
-                -19088976000089L));
-        assertEquals("Incorrect value was returned.", Long.MIN_VALUE, 
-                StrictMath.min(Long.MIN_VALUE, Long.MIN_VALUE));        
-    }
+        halfMax = StrictMath.scalb(-1.0f, Float.MAX_EXPONENT);
+        assertEquals(-1.7014118E38f, halfMax);
+        assertEquals(-Float.MAX_VALUE, halfMax + StrictMath.ulp(halfMax)
+                + halfMax);
+        assertEquals(Float.NEGATIVE_INFINITY, halfMax + halfMax);
 
-    /**
-     * @tests java.lang.StrictMath#pow(double, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pow",
-        args = {double.class, double.class}
-    )
-    public void test_powDD() {
-        // Test for method double java.lang.StrictMath.pow(double, double)
-        assertTrue("pow returned incorrect value",
-                (long) StrictMath.pow(2, 8) == 256l);
-        assertTrue("pow returned incorrect value",
-                StrictMath.pow(2, -8) == 0.00390625d);
-        
-        assertEquals(1.0, StrictMath.pow(1.0, 0.0));
-        assertEquals(1.0, StrictMath.pow(1.0, -0.0));
-        
-        assertEquals(Double.NaN, StrictMath.pow(1.0, Double.NaN));
-        assertEquals(Double.NaN, StrictMath.pow(Double.NaN, 1.0));  
-        
-        assertEquals(Double.POSITIVE_INFINITY, 
-                StrictMath.pow(1.1, Double.POSITIVE_INFINITY));
-        assertEquals(Double.POSITIVE_INFINITY, 
-                StrictMath.pow(0.1, Double.NEGATIVE_INFINITY));  
-        
-        assertEquals(0.0, StrictMath.pow(1.1, Double.NEGATIVE_INFINITY));
-        assertEquals(0.0, StrictMath.pow(0.1, Double.POSITIVE_INFINITY));
-        
-        assertEquals(Double.NaN, StrictMath.pow(1.0, Double.NEGATIVE_INFINITY));
-        assertEquals(Double.NaN, StrictMath.pow(1.0, Double.POSITIVE_INFINITY));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(0.345f, 1234));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(44.345E10f, 934));
+        assertEquals(Float.NEGATIVE_INFINITY, StrictMath
+                .scalb(-44.345E10f, 934));
 
-        assertEquals(0.0, StrictMath.pow(0.0, 1.0));
-        assertEquals(0.0, StrictMath.pow(Double.POSITIVE_INFINITY, -1.0));
-        
-        assertEquals(Double.POSITIVE_INFINITY, StrictMath.pow(0.0, -1.0));
-        assertEquals(Double.POSITIVE_INFINITY, 
-                StrictMath.pow(Double.POSITIVE_INFINITY, 1.0));
-        
-        assertEquals(0.0, StrictMath.pow(-0.0, 2.0));
-        assertEquals(0.0, StrictMath.pow(Double.NEGATIVE_INFINITY, -2.0));
-        
-        assertEquals(Double.POSITIVE_INFINITY, StrictMath.pow(-0.0, -2.0));
-        assertEquals(Double.POSITIVE_INFINITY, StrictMath.pow(
-                Double.NEGATIVE_INFINITY, 2.0)); 
-        
-        assertEquals(Double.NEGATIVE_INFINITY, StrictMath.pow(-0.0, -1.0));
-        assertEquals(Double.NEGATIVE_INFINITY, StrictMath.pow(
-                Double.NEGATIVE_INFINITY, 1.0));         
-        
-        assertEquals(Double.NaN, StrictMath.pow(-1.0, 1.1));       
-    }
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+                Float.MIN_NORMAL / 2, 400));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(Float.MIN_VALUE,
+                800));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(Float.MAX_VALUE,
+                1));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+                Float.POSITIVE_INFINITY, 0));
+        assertEquals(Float.POSITIVE_INFINITY, StrictMath.scalb(
+                Float.POSITIVE_INFINITY, -1));
+        assertEquals(Float.NEGATIVE_INFINITY, StrictMath.scalb(
+                Float.NEGATIVE_INFINITY, -1));
+        assertEquals(Float.NEGATIVE_INFINITY, StrictMath.scalb(
+                Float.NEGATIVE_INFINITY, Float.MIN_EXPONENT));
 
-    /**
-     * @tests java.lang.StrictMath#rint(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "rint",
-        args = {double.class}
-    )
-    public void test_rintD() {
-        // Test for method double java.lang.StrictMath.rint(double)
-        assertEquals("Failed to round properly - up to odd",
-                3.0, StrictMath.rint(2.9), 0D);
-        assertTrue("Failed to round properly - NaN", Double.isNaN(StrictMath
-                .rint(Double.NaN)));
-        assertEquals("Failed to round properly down  to even", 2.0, StrictMath
-                .rint(2.1), 0D);
-        assertTrue("Failed to round properly " + 2.5 + " to even", StrictMath
-                .rint(2.5) == 2.0);
-    }
+        // result is subnormal/zero
+        int posZeroBits = Float.floatToIntBits(+0.0f);
+        int negZeroBits = Float.floatToIntBits(-0.0f);
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(+0.0f,
+                Integer.MAX_VALUE)));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(+0.0f,
+                -123)));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(+0.0f,
+                0)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(-0.0f,
+                123)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(-0.0f,
+                Integer.MIN_VALUE)));
 
-    /**
-     * @tests java.lang.StrictMath#round(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "round",
-        args = {double.class}
-    )
-    public void test_roundD() {
-        // Test for method long java.lang.StrictMath.round(double)
-        assertEquals("Incorrect rounding of a float",
-                -91, StrictMath.round(-90.89d));
-        
-        assertEquals("Incorrect rounding of NaN", 0l, 
-                                                  StrictMath.round(Double.NaN));
-        assertEquals("Incorrect rounding of NEGATIVE_INFINITY", Long.MIN_VALUE, 
-                                    StrictMath.round(Double.NEGATIVE_INFINITY));
-        assertEquals("Incorrect rounding of value less than Long.MIN_VALUE", 
-            Long.MIN_VALUE, StrictMath.round(new Double(Long.MIN_VALUE - 0.1)));   
-        assertEquals("Incorrect rounding of Long.MIN_VALUE", 
-                Long.MIN_VALUE, StrictMath.round(new Double(Long.MIN_VALUE))); 
-        assertEquals("Incorrect rounding of Long.MAX_VALUE", 
-                Long.MAX_VALUE, StrictMath.round(Double.POSITIVE_INFINITY));  
-        assertEquals("Incorrect rounding of value greater than Long.MAX_VALUE", 
-            Long.MAX_VALUE, StrictMath.round(new Double(Long.MAX_VALUE + 0.1)));        
-        
-    }
+        assertEquals(Float.MIN_VALUE, StrictMath.scalb(1.0f, -149));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(1.0f,
+                -150)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(-1.0f,
+                -150)));
 
-    /**
-     * @tests java.lang.StrictMath#round(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "round",
-        args = {float.class}
-    )
-    public void test_roundF() {
-        // Test for method int java.lang.StrictMath.round(float)
-        assertEquals("Incorrect rounding of a float",
-                -91, StrictMath.round(-90.89f));
-        
-        assertEquals("Incorrect rounding of NaN", 0l, 
-                        StrictMath.round(Float.NaN));
-        assertEquals("Incorrect rounding of NEGATIVE_INFINITY", 
-                  Integer.MIN_VALUE, StrictMath.round(Float.NEGATIVE_INFINITY));
-        assertEquals("Incorrect rounding of value less than Integer.MIN_VALUE", 
-        Integer.MIN_VALUE, StrictMath.round(new Float(Integer.MIN_VALUE - 0.1)));   
-        assertEquals("Incorrect rounding of Integer.MIN_VALUE", 
-        Integer.MIN_VALUE, StrictMath.round(new Float(Integer.MIN_VALUE))); 
-        assertEquals("Incorrect rounding of Integer.MAX_VALUE", 
-        Integer.MAX_VALUE, StrictMath.round(Float.POSITIVE_INFINITY));  
-        assertEquals("Incorrect rounding of value greater than Integer.MAX_VALUE", 
-        Integer.MAX_VALUE, StrictMath.round(new Float(Integer.MAX_VALUE + 0.1)));
+        // precision lost
+        assertEquals(StrictMath.scalb(21.405f, -154), StrictMath.scalb(21.405f,
+                -153));
+        assertEquals(Float.MIN_VALUE, StrictMath.scalb(21.405f, -154));
+        assertEquals(-Float.MIN_VALUE, StrictMath.scalb(-21.405f, -154));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                21.405f, -155)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                -21.405f, -155)));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                Float.MIN_VALUE, -1)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                -Float.MIN_VALUE, -1)));
+        assertEquals(Float.MIN_VALUE, StrictMath.scalb(Float.MIN_NORMAL, -23));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                Float.MIN_NORMAL, -24)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                -Float.MIN_NORMAL, -24)));
+        assertEquals(Float.MIN_VALUE, StrictMath.scalb(Float.MAX_VALUE, -277));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                Float.MAX_VALUE, -278)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                -Float.MAX_VALUE, -278)));
+        assertEquals(Float.MIN_VALUE, StrictMath.scalb(Float.MIN_NORMAL / 3,
+                -22));
+        assertEquals(posZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                Float.MIN_NORMAL / 3, -23)));
+        assertEquals(negZeroBits, Float.floatToIntBits(StrictMath.scalb(
+                -Float.MIN_NORMAL / 3, -23)));
+        float subnormal = StrictMath.scalb(Float.MIN_NORMAL / 3, -11);
+        assertEquals(1.913E-42f, subnormal);
+        // precision lost
+        assertFalse(Float.MIN_NORMAL / 3 == StrictMath.scalb(subnormal, 11));
+
+        assertEquals(68747264, Float.floatToIntBits(StrictMath.scalb(
+                Float.MIN_VALUE * 153, 23)));
+        assertEquals(-2078736384, Float.floatToIntBits(StrictMath.scalb(
+                -Float.MIN_VALUE * 153, 23)));
+
+        assertEquals(4896, Float.floatToIntBits(StrictMath.scalb(
+                Float.MIN_VALUE * 153, 5)));
+        assertEquals(-2147478752, Float.floatToIntBits(StrictMath.scalb(
+                -Float.MIN_VALUE * 153, 5)));
+
+        // NaN
+        assertTrue(Float.isNaN(StrictMath.scalb(Float.NaN, 1)));
+        assertTrue(Float.isNaN(StrictMath.scalb(Float.NaN, 0)));
+        assertTrue(Float.isNaN(StrictMath.scalb(Float.NaN, -120)));
+
+        // test for exception
+        try {
+            StrictMath.scalb((Float) null, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.scalb(1.0f, (Integer) null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            StrictMath.scalb((Float) null, 1);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
     
     /**
      * @tests java.lang.StrictMath#signum(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "signum",
-        args = {double.class}
-    )
     public void test_signum_D() {
         assertTrue(Double.isNaN(StrictMath.signum(Double.NaN)));
         assertEquals(Double.doubleToLongBits(0.0), Double
@@ -1142,12 +1260,6 @@
     /**
      * @tests java.lang.StrictMath#signum(float)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "signum",
-        args = {float.class}
-    )
     public void test_signum_F() {
         assertTrue(Float.isNaN(StrictMath.signum(Float.NaN)));
         assertEquals(Float.floatToIntBits(0.0f), Float
@@ -1170,44 +1282,18 @@
         assertEquals(-1.0f, StrictMath.signum(Float.NEGATIVE_INFINITY), 0f);
     }
 
-    /**
+	/**
      * @tests java.lang.StrictMath#sin(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sin",
-        args = {double.class}
-    )
-    public void test_sinD() {
-        // Test for method double java.lang.StrictMath.sin(double)
-        assertTrue("Returned incorrect sine", StrictMath.sin(StrictMath
-                .asin(OPP / HYP)) == OPP / HYP);
-        
-        assertEquals("Returned incorrect sin value.", 
-                Double.NaN, StrictMath.sin(Double.NaN));
-        
-        assertEquals("Returned incorrect sin value.", 
-                Double.NaN, StrictMath.sin(Double.POSITIVE_INFINITY));
-        
-        assertEquals("Returned incorrect sin value.", 
-                Double.NaN, StrictMath.sin(Double.NEGATIVE_INFINITY));   
-        
-        assertEquals("Returned incorrect sin value.", 
-                0.0, StrictMath.sin(0.0));   
-        assertEquals("Returned incorrect sin value.", 
-                -0.0, StrictMath.sin(-0.0));        
-    }
+	public void test_sinD() {
+		// Test for method double java.lang.StrictMath.sin(double)
+		assertTrue("Returned incorrect sine", StrictMath.sin(StrictMath
+				.asin(OPP / HYP)) == OPP / HYP);
+	}
 
     /**
      * @tests java.lang.StrictMath#sinh(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sinh",
-        args = {double.class}
-    )
     public void test_sinh_D() {
         // Test for special situations
         assertTrue(Double.isNaN(StrictMath.sinh(Double.NaN)));
@@ -1218,11 +1304,11 @@
                 Double.NEGATIVE_INFINITY, StrictMath
                         .sinh(Double.NEGATIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double
-                .doubleToLongBits(StrictMath.sinh(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(StrictMath.sinh(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(StrictMath.sinh(-0.0)));
+				.doubleToLongBits(StrictMath.sinh(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(StrictMath.sinh(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(StrictMath.sinh(-0.0)));
 
         assertEquals("Should return POSITIVE_INFINITY",
                 Double.POSITIVE_INFINITY, StrictMath.sinh(1234.56), 0D);
@@ -1240,58 +1326,30 @@
                 .sinh(Double.MIN_VALUE), 0D);
     }
     
-    /**
-     * @tests java.lang.StrictMath#sqrt(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sqrt",
-        args = {double.class}
-    )
-    public void test_sqrtD() {
-        // Test for method double java.lang.StrictMath.sqrt(double)
-        assertEquals("Incorrect root returned1",
+	/**
+	 * @tests java.lang.StrictMath#sqrt(double)
+	 */
+	public void test_sqrtD() {
+		// Test for method double java.lang.StrictMath.sqrt(double)
+		assertEquals("Incorrect root returned1",
                              2, StrictMath.sqrt(StrictMath.pow(StrictMath.sqrt(2), 4)), 0.0);
-        assertEquals("Incorrect root returned2", 7, StrictMath.sqrt(49), 0.0);
-        
-        assertEquals("Incorrect root was returned.", Double.NaN, 
-                StrictMath.sqrt(Double.NaN));
-        assertEquals("Incorrect root was returned.", Double.NaN, 
-                StrictMath.sqrt(-0.1));        
-        assertEquals("Incorrect root was returned.", Double.POSITIVE_INFINITY, 
-                StrictMath.sqrt(Double.POSITIVE_INFINITY)); 
-        
-        assertEquals("Incorrect root was returned.", 0.0, StrictMath.sqrt(0.0));     
-        assertEquals("Incorrect root was returned.", -0.0, StrictMath.sqrt(-0.0));       
-    }
+		assertEquals("Incorrect root returned2", 7, StrictMath.sqrt(49), 0.0);
+	}
 
-    /**
-     * @tests java.lang.StrictMath#tan(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't check boundary values.",
-        method = "tan",
-        args = {double.class}
-    )
-    public void test_tanD() {
-        // Test for method double java.lang.StrictMath.tan(double)
-        assertTrue(
-                "Returned incorrect tangent: ",
-                StrictMath.tan(StrictMath.atan(1.0)) <= 1.0
-                        || StrictMath.tan(StrictMath.atan(1.0)) >= 9.9999999999999983E-1);
-    }
+	/**
+	 * @tests java.lang.StrictMath#tan(double)
+	 */
+	public void test_tanD() {
+		// Test for method double java.lang.StrictMath.tan(double)
+		assertTrue(
+				"Returned incorrect tangent: ",
+				StrictMath.tan(StrictMath.atan(1.0)) <= 1.0
+						|| StrictMath.tan(StrictMath.atan(1.0)) >= 9.9999999999999983E-1);
+	}
 
     /**
      * @tests java.lang.StrictMath#tanh(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "tanh",
-        args = {double.class}
-    )
     public void test_tanh_D() {
         // Test for special situations
         assertTrue(Double.isNaN(StrictMath.tanh(Double.NaN)));
@@ -1300,11 +1358,11 @@
         assertEquals("Should return -1.0", -1.0, StrictMath
                 .tanh(Double.NEGATIVE_INFINITY), 0D);
         assertEquals(Double.doubleToLongBits(0.0), Double
-                .doubleToLongBits(StrictMath.tanh(0.0)));
-        assertEquals(Double.doubleToLongBits(+0.0), Double
-                .doubleToLongBits(StrictMath.tanh(+0.0)));
-        assertEquals(Double.doubleToLongBits(-0.0), Double
-                .doubleToLongBits(StrictMath.tanh(-0.0)));
+				.doubleToLongBits(StrictMath.tanh(0.0)));
+		assertEquals(Double.doubleToLongBits(+0.0), Double
+				.doubleToLongBits(StrictMath.tanh(+0.0)));
+		assertEquals(Double.doubleToLongBits(-0.0), Double
+				.doubleToLongBits(StrictMath.tanh(-0.0)));
 
         assertEquals("Should return 1.0", 1.0, StrictMath.tanh(1234.56), 0D);
         assertEquals("Should return -1.0", -1.0, StrictMath.tanh(-1234.56), 0D);
@@ -1318,172 +1376,115 @@
                 .tanh(Double.MIN_VALUE), 0D);
     }
     
-    /**
-     * @tests java.lang.StrictMath#random()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "random",
-        args = {}
-    )
-    public void test_random() {
-        // There isn't a place for these tests so just stick them here
-        assertEquals("Wrong value E",
-                4613303445314885481L, Double.doubleToLongBits(StrictMath.E));
-        assertEquals("Wrong value PI",
-                4614256656552045848L, Double.doubleToLongBits(StrictMath.PI));
+	/**
+	 * @tests java.lang.StrictMath#random()
+	 */
+	public void test_random() {
+		// There isn't a place for these tests so just stick them here
+		assertEquals("Wrong value E",
+				4613303445314885481L, Double.doubleToLongBits(StrictMath.E));
+		assertEquals("Wrong value PI",
+				4614256656552045848L, Double.doubleToLongBits(StrictMath.PI));
 
-        for (int i = 500; i >= 0; i--) {
-            double d = StrictMath.random();
-            assertTrue("Generated number is out of range: " + d, d >= 0.0
-                    && d < 1.0);
-        }
-    }
+		for (int i = 500; i >= 0; i--) {
+			double d = StrictMath.random();
+			assertTrue("Generated number is out of range: " + d, d >= 0.0
+					&& d < 1.0);
+		}
+	}
 
-    /**
-     * @tests java.lang.StrictMath#toRadians(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toRadians",
-        args = {double.class}
-    )
-    public void test_toRadiansD() {
-        for (double d = 500; d >= 0; d -= 1.0) {
-            double converted = StrictMath.toDegrees(StrictMath.toRadians(d));
-            assertTrue("Converted number not equal to original. d = " + d,
-                    converted >= d * 0.99999999 && converted <= d * 1.00000001);
-        }
-    }
+	/**
+	 * @tests java.lang.StrictMath#toRadians(double)
+	 */
+	public void test_toRadiansD() {
+		for (double d = 500; d >= 0; d -= 1.0) {
+			double converted = StrictMath.toDegrees(StrictMath.toRadians(d));
+			assertTrue("Converted number not equal to original. d = " + d,
+					converted >= d * 0.99999999 && converted <= d * 1.00000001);
+		}
+	}
 
-    /**
-     * @tests java.lang.StrictMath#toDegrees(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toDegrees",
-        args = {double.class}
-    )
-    public void test_toDegreesD() {
-        for (double d = 500; d >= 0; d -= 1.0) {
-            double converted = StrictMath.toRadians(StrictMath.toDegrees(d));
-            assertTrue("Converted number not equal to original. d = " + d,
-                    converted >= d * 0.99999999 && converted <= d * 1.00000001);
-        }
-    }
-    
-    /**
+	/**
+	 * @tests java.lang.StrictMath#toDegrees(double)
+	 */
+	public void test_toDegreesD() {
+		for (double d = 500; d >= 0; d -= 1.0) {
+			double converted = StrictMath.toRadians(StrictMath.toDegrees(d));
+			assertTrue("Converted number not equal to original. d = " + d,
+					converted >= d * 0.99999999 && converted <= d * 1.00000001);
+		}
+	}
+	
+	/**
      * @tests java.lang.StrictMath#ulp(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ulp",
-        args = {double.class}
-    )
      @SuppressWarnings("boxing")
     public void test_ulp_D() {
         // Test for special cases
-        assertTrue("Should return NaN", Double
-                .isNaN(StrictMath.ulp(Double.NaN)));
-        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY,
-                StrictMath.ulp(Double.POSITIVE_INFINITY), 0D);
-        assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY,
-                StrictMath.ulp(Double.NEGATIVE_INFINITY), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
-                .ulp(0.0), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
-                .ulp(+0.0), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
-                .ulp(-0.0), 0D);
-        assertEquals("Returned incorrect value", StrictMath.pow(2, 971),
-                StrictMath.ulp(Double.MAX_VALUE), 0D);
-        assertEquals("Returned incorrect value", StrictMath.pow(2, 971),
-                StrictMath.ulp(-Double.MAX_VALUE), 0D);
+		assertTrue("Should return NaN", Double
+				.isNaN(StrictMath.ulp(Double.NaN)));
+		assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY,
+				StrictMath.ulp(Double.POSITIVE_INFINITY), 0D);
+		assertEquals("Returned incorrect value", Double.POSITIVE_INFINITY,
+				StrictMath.ulp(Double.NEGATIVE_INFINITY), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+				.ulp(0.0), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+				.ulp(+0.0), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+				.ulp(-0.0), 0D);
+		assertEquals("Returned incorrect value", StrictMath.pow(2, 971),
+				StrictMath.ulp(Double.MAX_VALUE), 0D);
+		assertEquals("Returned incorrect value", StrictMath.pow(2, 971),
+				StrictMath.ulp(-Double.MAX_VALUE), 0D);
 
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
-                .ulp(Double.MIN_VALUE), 0D);
-        assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
-                .ulp(-Double.MIN_VALUE), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+				.ulp(Double.MIN_VALUE), 0D);
+		assertEquals("Returned incorrect value", Double.MIN_VALUE, StrictMath
+				.ulp(-Double.MIN_VALUE), 0D);
 
-        assertEquals("Returned incorrect value", 2.220446049250313E-16,
-                StrictMath.ulp(1.0), 0D);
-        assertEquals("Returned incorrect value", 2.220446049250313E-16,
-                StrictMath.ulp(-1.0), 0D);
-        assertEquals("Returned incorrect value", 2.2737367544323206E-13,
-                StrictMath.ulp(1153.0), 0D);
+		assertEquals("Returned incorrect value", 2.220446049250313E-16,
+				StrictMath.ulp(1.0), 0D);
+		assertEquals("Returned incorrect value", 2.220446049250313E-16,
+				StrictMath.ulp(-1.0), 0D);
+		assertEquals("Returned incorrect value", 2.2737367544323206E-13,
+				StrictMath.ulp(1153.0), 0D);
     }
 
     /**
-     * @tests java.lang.StrictMath#ulp(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ulp",
-        args = {float.class}
-    )
+	 * @tests java.lang.StrictMath#ulp(float)
+	 */
     @SuppressWarnings("boxing")
     public void test_ulp_f() {
         // Test for special cases
-        assertTrue("Should return NaN", Float.isNaN(StrictMath.ulp(Float.NaN)));
-        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY,
-                StrictMath.ulp(Float.POSITIVE_INFINITY), 0f);
-        assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY,
-                StrictMath.ulp(Float.NEGATIVE_INFINITY), 0f);
-        assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
-                .ulp(0.0f), 0f);
-        assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
-                .ulp(+0.0f), 0f);
-        assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
-                .ulp(-0.0f), 0f);
-        assertEquals("Returned incorrect value", 2.028241E31f, StrictMath
-                .ulp(Float.MAX_VALUE), 0f);
-        assertEquals("Returned incorrect value", 2.028241E31f, StrictMath
-                .ulp(-Float.MAX_VALUE), 0f);
+    	assertTrue("Should return NaN", Float.isNaN(StrictMath.ulp(Float.NaN)));
+		assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY,
+				StrictMath.ulp(Float.POSITIVE_INFINITY), 0f);
+		assertEquals("Returned incorrect value", Float.POSITIVE_INFINITY,
+				StrictMath.ulp(Float.NEGATIVE_INFINITY), 0f);
+		assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
+				.ulp(0.0f), 0f);
+		assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
+				.ulp(+0.0f), 0f);
+		assertEquals("Returned incorrect value", Float.MIN_VALUE, StrictMath
+				.ulp(-0.0f), 0f);
+		assertEquals("Returned incorrect value", 2.028241E31f, StrictMath
+				.ulp(Float.MAX_VALUE), 0f);
+		assertEquals("Returned incorrect value", 2.028241E31f, StrictMath
+				.ulp(-Float.MAX_VALUE), 0f);
 
-        assertEquals("Returned incorrect value", 1.4E-45f, StrictMath
-                .ulp(Float.MIN_VALUE), 0f);
-        assertEquals("Returned incorrect value", 1.4E-45f, StrictMath
-                .ulp(-Float.MIN_VALUE), 0f);
+		assertEquals("Returned incorrect value", 1.4E-45f, StrictMath
+				.ulp(Float.MIN_VALUE), 0f);
+		assertEquals("Returned incorrect value", 1.4E-45f, StrictMath
+				.ulp(-Float.MIN_VALUE), 0f);
 
-        assertEquals("Returned incorrect value", 1.1920929E-7f, StrictMath
-                .ulp(1.0f), 0f);
-        assertEquals("Returned incorrect value", 1.1920929E-7f, StrictMath
-                .ulp(-1.0f), 0f);
-        assertEquals("Returned incorrect value", 1.2207031E-4f, StrictMath
-                .ulp(1153.0f), 0f);
-        assertEquals("Returned incorrect value", 5.6E-45f, Math
-                .ulp(9.403954E-38f), 0f);
+		assertEquals("Returned incorrect value", 1.1920929E-7f, StrictMath
+				.ulp(1.0f), 0f);
+		assertEquals("Returned incorrect value", 1.1920929E-7f, StrictMath
+				.ulp(-1.0f), 0f);
+		assertEquals("Returned incorrect value", 1.2207031E-4f, StrictMath
+				.ulp(1153.0f), 0f);
+		assertEquals("Returned incorrect value", 5.6E-45f, Math
+				.ulp(9.403954E-38f), 0f);
     }
-    
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Stress test.",
-        method = "pow",
-        args = {double.class, double.class}
-    )
-    public void test_pow_stress() {
-        assertTrue(Double.longBitsToDouble(-4610068591539890326L) ==
-                StrictMath.pow(-1.0000000000000002e+00,
-                        4.5035996273704970e+15));
-        assertTrue(Double.longBitsToDouble(4601023824101950163L) == 
-                StrictMath.pow(-9.9999999999999978e-01,
-                        4.035996273704970e+15));
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Stress test.",
-        method = "tan",
-        args = {double.class}
-    )
-    public void test_tan_stress(){
-        assertTrue(Double.longBitsToDouble(4850236541654588678L) == 
-            StrictMath.tan(1.7765241907548024E+269));
-    }
-    
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java
index 79b87fc..1f5de93 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBufferTest.java
@@ -16,30 +16,18 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.io.Serializable;
 
 import junit.framework.TestCase;
 
-import java.io.Serializable;
-
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(StringBuffer.class) 
 public class StringBufferTest extends TestCase {
 
     /**
      * @tests java.lang.StringBuffer#setLength(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IndexOutOfBoundsException.",
-        method = "setLength",
-        args = {int.class}
-    )
     public void test_setLengthI() {
         // Regression for HARMONY-90
         StringBuffer buffer = new StringBuffer("abcde");
@@ -49,22 +37,81 @@
         } catch (IndexOutOfBoundsException e) {
             // expected
         }
+
+        assertEquals("abcde", buffer.toString());
+        buffer.setLength(1);
+        buffer.append('f');
+        assertEquals("af", buffer.toString());
+
+        buffer = new StringBuffer("abcde");
+        assertEquals("cde", buffer.substring(2));
+        buffer.setLength(3);
+        buffer.append('f');
+        assertEquals("abcf", buffer.toString());
+
+        buffer = new StringBuffer("abcde");
+        buffer.setLength(2);
+        try {
+            buffer.charAt(3);
+            fail("should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+        }
+
+        buffer = new StringBuffer();
+        buffer.append("abcdefg");
+        buffer.setLength(2);
+        buffer.setLength(5);
+        for (int i = 2; i < 5; i++) {
+            assertEquals(0, buffer.charAt(i));
+        }
+
+        buffer = new StringBuffer();
+        buffer.append("abcdefg");
+        buffer.delete(2, 4);
+        buffer.setLength(7);
+        assertEquals('a', buffer.charAt(0));
+        assertEquals('b', buffer.charAt(1));
+        assertEquals('e', buffer.charAt(2));
+        assertEquals('f', buffer.charAt(3));
+        assertEquals('g', buffer.charAt(4));
+        for (int i = 5; i < 7; i++) {
+            assertEquals(0, buffer.charAt(i));
+        }
+
+        buffer = new StringBuffer();
+        buffer.append("abcdefg");
+        buffer.replace(2, 5, "z");
+        buffer.setLength(7);
+        for (int i = 5; i < 7; i++) {
+            assertEquals(0, buffer.charAt(i));
+        }
     }
-    
+
+    /**
+     * @tests java.lang.StringBuffer#toString()
+     */
+    public void test_toString() throws Exception {
+        StringBuffer buffer = new StringBuffer();
+        assertEquals("", buffer.toString());
+
+        buffer.append("abcde");
+        assertEquals("abcde", buffer.toString());
+        buffer.setLength(1000);
+        byte[] bytes = buffer.toString().getBytes("GB18030");
+        for (int i = 5; i < bytes.length; i++) {
+            assertEquals(0, bytes[i]);
+        }
+
+        buffer.setLength(5);
+        buffer.append("fghij");
+        assertEquals("abcdefghij", buffer.toString());
+    }
+
     /**
      * @tests StringBuffer.StringBuffer(CharSequence);
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringBuffer",
-        args = {java.lang.CharSequence.class}
-    )
     public void test_constructorLjava_lang_CharSequence() {
-        String str = "Test string";
-        StringBuffer sb = new StringBuffer((CharSequence) str);
-        assertEquals(str.length(), sb.length());
-        
         try {
             new StringBuffer((CharSequence) null);
             fail("Assert 0: NPE must be thrown.");
@@ -72,12 +119,7 @@
         
         assertEquals("Assert 1: must equal 'abc'.", "abc", new StringBuffer((CharSequence)"abc").toString());
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "trimToSize",
-        args = {}
-    )
+    
     public void test_trimToSize() {
         StringBuffer buffer = new StringBuffer(25);
         buffer.append("abc");
@@ -92,12 +134,6 @@
     /**
      * @tests java.lang.StringBuffer.append(CharSequence)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class}
-    )
     public void test_appendLjava_lang_CharSequence() {
         StringBuffer sb = new StringBuffer();
         assertSame(sb, sb.append((CharSequence) "ab"));
@@ -109,35 +145,10 @@
         assertSame(sb, sb.append((CharSequence) null));
         assertEquals("null", sb.toString());
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.StringBuffer.class}
-    )
-    public void test_appendLStringBuffer() {
-        StringBuffer originalSB = new StringBuffer();
-        StringBuffer sb1 = new StringBuffer("append1");
-        StringBuffer sb2 = new StringBuffer("append2");
-        originalSB.append(sb1);
-        assertEquals(sb1.toString(), originalSB.toString());
-        originalSB.append(sb2);
-        assertEquals(sb1.toString() + sb2.toString(), originalSB.toString()); 
-        originalSB.append((StringBuffer) null);
-        assertEquals(sb1.toString() + sb2.toString() + "null", 
-                                                         originalSB.toString());
-    }
 
     /**
      * @tests java.lang.StringBuffer.append(CharSequence, int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class, int.class, int.class}
-    )
     @SuppressWarnings("cast")
     public void test_appendLjava_lang_CharSequenceII() {
         StringBuffer sb = new StringBuffer();
@@ -155,24 +166,11 @@
         sb.setLength(0);
         assertSame(sb, sb.append((CharSequence) null, 0, 2));
         assertEquals("nu", sb.toString());
-        
-        try {
-            sb.append((CharSequence) "abcd", -1, 2);
-            fail("IndexOutOfBoundsException was thrown.");
-        } catch(IndexOutOfBoundsException e) {
-            //expected
-        }
     }
     
     /**
      * @tests java.lang.StringBuffer.append(char[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies ArrayIndexOutOfBoundsException.",
-        method = "append",
-        args = {char[].class, int.class, int.class}
-    )
     public void test_append$CII_2() {
         StringBuffer obj = new StringBuffer();
         try {
@@ -186,12 +184,6 @@
     /**
      * @tests java.lang.StringBuffer.append(char[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies NullPointerException.",
-        method = "append",
-        args = {char[].class, int.class, int.class}
-    )
     public void test_append$CII_3() throws Exception {
         StringBuffer obj = new StringBuffer();
         try {
@@ -205,12 +197,6 @@
     /**
      * @tests java.lang.StringBuffer.insert(int, CharSequence)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, java.lang.CharSequence.class}
-    )
     public void test_insertILjava_lang_CharSequence() {
         final String fixture = "0000";
         StringBuffer sb = new StringBuffer(fixture);
@@ -253,12 +239,6 @@
     /**
      * @tests java.lang.StringBuffer.insert(int, CharSequence, int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, java.lang.CharSequence.class, int.class, int.class}
-    )
     @SuppressWarnings("cast")
     public void test_insertILjava_lang_CharSequenceII() {
         final String fixture = "0000";
@@ -341,12 +321,6 @@
     /**
      * @tests java.lang.StringBuffer.insert(int, char)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies ArrayIndexOutOfBoundsException.",
-        method = "insert",
-        args = {int.class, char.class}
-    )
     public void test_insertIC() {
         StringBuffer obj = new StringBuffer();
         try {
@@ -360,12 +334,6 @@
     /**
      * @tests java.lang.StringBuffer.appendCodePoint(int)'
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "appendCodePoint",
-        args = {int.class}
-    )
     public void test_appendCodePointI() {
         StringBuffer sb = new StringBuffer();
         sb.appendCodePoint(0x10000);
@@ -379,12 +347,6 @@
     /**
      * @tests java.lang.StringBuffer.codePointAt(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointAt",
-        args = {int.class}
-    )
     public void test_codePointAtI() {
         StringBuffer sb = new StringBuffer("abc");
         assertEquals('a', sb.codePointAt(0));
@@ -420,12 +382,6 @@
     /**
      * @tests java.lang.StringBuffer.codePointBefore(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointBefore",
-        args = {int.class}
-    )
     public void test_codePointBeforeI() {
         StringBuffer sb = new StringBuffer("abc");
         assertEquals('a', sb.codePointBefore(1));
@@ -461,12 +417,6 @@
     /**
      * @tests java.lang.StringBuffer.codePointCount(int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointCount",
-        args = {int.class, int.class}
-    )
     public void test_codePointCountII() {
         assertEquals(1, new StringBuffer("\uD800\uDC00").codePointCount(0, 2));
         assertEquals(1, new StringBuffer("\uD800\uDC01").codePointCount(0, 2));
@@ -502,41 +452,19 @@
     /**
      * @tests java.lang.StringBuffer.getChars(int, int, char[], int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IndexOutOfBoundsException, NullPointerException.",
-        method = "getChars",
-        args = {int.class, int.class, char[].class, int.class}
-    )
     public void test_getCharsII$CI() {
         StringBuffer obj = new StringBuffer();
         try {
             obj.getChars(0, 0,  new char[0], -1);
-// TODO(Fixed) According to spec this should be IndexOutOfBoundsException. 
-//            fail("ArrayIndexOutOfBoundsException expected");
-//          } catch (ArrayIndexOutOfBoundsException e) {
-            fail("IndexOutOfBoundsException expected");
-        } catch (IndexOutOfBoundsException e) {
+            fail("ArrayIndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException e) {
             // expected
         }
-        
-        try {
-            obj.getChars(0, 0,  null, -1);
-            fail("NullPointerException is not thrown.");
-        } catch(NullPointerException npe) {
-            //expected
-        }
     }
 
     /**
      * @tests java.lang.StringBuffer.offsetByCodePoints(int, int)'
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "offsetByCodePoints",
-        args = {int.class, int.class}
-    )
     public void test_offsetByCodePointsII() {
         int result = new StringBuffer("a\uD800\uDC00b").offsetByCodePoints(0, 2);
         assertEquals(3, result);
@@ -602,12 +530,6 @@
     /**
      * @tests {@link java.lang.StringBuffer#indexOf(String, int)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "indexOf",
-        args = {java.lang.String.class, int.class}
-    )
     @SuppressWarnings("nls")
     public void test_IndexOfStringInt() {
         final String fixture = "0123456789";
@@ -638,12 +560,6 @@
     /**
      * @tests {@link java.lang.StringBuffer#lastIndexOf(String, int)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "lastIndexOf",
-        args = {java.lang.String.class, int.class}
-    )
     @SuppressWarnings("nls")
     public void test_lastIndexOfLjava_lang_StringI() {
         final String fixture = "0123456789";
@@ -689,12 +605,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new StringBuffer("0123456789"),
@@ -704,12 +614,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new StringBuffer("0123456789"),
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java
index 0243fdb..596453d 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringBuilderTest.java
@@ -17,565 +17,412 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.Arrays;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(StringBuilder.class) 
 public class StringBuilderTest extends TestCase {
 
-    /**
-     * @tests java.lang.StringBuilder.StringBuilder()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringBuilder",
-        args = {}
-    )
-    public void test_Constructor() {
-        StringBuilder sb = new StringBuilder();
-        assertNotNull(sb);
-        assertEquals(16, sb.capacity());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.StringBuilder()
+	 */
+	public void test_Constructor() {
+		StringBuilder sb = new StringBuilder();
+		assertNotNull(sb);
+		assertEquals(16, sb.capacity());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.StringBuilder(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringBuilder",
-        args = {int.class}
-    )
-    public void test_ConstructorI() {
-        StringBuilder sb = new StringBuilder(24);
-        assertNotNull(sb);
-        assertEquals(24, sb.capacity());
+	/**
+	 * @tests java.lang.StringBuilder.StringBuilder(int)
+	 */
+	public void test_ConstructorI() {
+		StringBuilder sb = new StringBuilder(24);
+		assertNotNull(sb);
+		assertEquals(24, sb.capacity());
 
-        try {
-            new StringBuilder(-1);
-            fail("no exception");
-        } catch (NegativeArraySizeException e) {
-            // Expected
-        }
+		try {
+			new StringBuilder(-1);
+			fail("no exception");
+		} catch (NegativeArraySizeException e) {
+			// Expected
+		}
 
-        assertNotNull(new StringBuilder(0));
-    }
+		assertNotNull(new StringBuilder(0));
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.StringBuilder(CharSequence)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringBuilder",
-        args = {java.lang.CharSequence.class}
-    )
-    @SuppressWarnings("cast")
+	/**
+	 * @tests java.lang.StringBuilder.StringBuilder(CharSequence)
+	 */
+	@SuppressWarnings("cast")
     public void test_ConstructorLjava_lang_CharSequence() {
-        StringBuilder sb = new StringBuilder((CharSequence) "fixture");
-        assertEquals("fixture", sb.toString());
-        assertEquals("fixture".length() + 16, sb.capacity());
+		StringBuilder sb = new StringBuilder((CharSequence) "fixture");
+		assertEquals("fixture", sb.toString());
+		assertEquals("fixture".length() + 16, sb.capacity());
 
-        sb = new StringBuilder((CharSequence) new StringBuffer("fixture"));
-        assertEquals("fixture", sb.toString());
-        assertEquals("fixture".length() + 16, sb.capacity());
+		sb = new StringBuilder((CharSequence) new StringBuffer("fixture"));
+		assertEquals("fixture", sb.toString());
+		assertEquals("fixture".length() + 16, sb.capacity());
 
-        try {
-            new StringBuilder((CharSequence) null);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-    }
+		try {
+			new StringBuilder((CharSequence) null);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.StringBuilder(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringBuilder",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_String() {
-        StringBuilder sb = new StringBuilder("fixture");
-        assertEquals("fixture", sb.toString());
-        assertEquals("fixture".length() + 16, sb.capacity());
+	/**
+	 * @tests java.lang.StringBuilder.StringBuilder(String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
+		StringBuilder sb = new StringBuilder("fixture");
+		assertEquals("fixture", sb.toString());
+		assertEquals("fixture".length() + 16, sb.capacity());
 
-        try {
-            new StringBuilder((String) null);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-        }
-    }
+		try {
+			new StringBuilder((String) null);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {boolean.class}
-    )
-    public void test_appendZ() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(true));
-        assertEquals("true", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(false));
-        assertEquals("false", sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(boolean)
+	 */
+	public void test_appendZ() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(true));
+		assertEquals("true", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(false));
+		assertEquals("false", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(char)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {char.class}
-    )
-    public void test_appendC() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append('a'));
-        assertEquals("a", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append('b'));
-        assertEquals("b", sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(char)
+	 */
+	public void test_appendC() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append('a'));
+		assertEquals("a", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append('b'));
+		assertEquals("b", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(char[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {char[].class}
-    )
-    public void test_append$C() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(new char[] { 'a', 'b' }));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(new char[] { 'c', 'd' }));
-        assertEquals("cd", sb.toString());
-        try {
-            sb.append((char[]) null);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(char[])
+	 */
+	public void test_append$C() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(new char[] { 'a', 'b' }));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(new char[] { 'c', 'd' }));
+		assertEquals("cd", sb.toString());
+		try {
+			sb.append((char[]) null);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(char[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {char[].class, int.class, int.class}
-    )
-    public void test_append$CII() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(new char[] { 'a', 'b' }, 0, 2));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(new char[] { 'c', 'd' }, 0, 2));
-        assertEquals("cd", sb.toString());
+	/**
+	 * @tests java.lang.StringBuilder.append(char[], int, int)
+	 */
+	public void test_append$CII() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(new char[] { 'a', 'b' }, 0, 2));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(new char[] { 'c', 'd' }, 0, 2));
+		assertEquals("cd", sb.toString());
 
-        sb.setLength(0);
-        assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 0, 2));
-        assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 0, 2));
+		assertEquals("ab", sb.toString());
 
-        sb.setLength(0);
-        assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 2));
-        assertEquals("cd", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 2));
+		assertEquals("cd", sb.toString());
 
-        sb.setLength(0);
-        assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 0));
-        assertEquals("", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 0));
+		assertEquals("", sb.toString());
 
-        try {
-            sb.append((char[]) null, 0, 2);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
+		try {
+			sb.append((char[]) null, 0, 2);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
 
-        try {
-            sb.append(new char[] { 'a', 'b', 'c', 'd' }, -1, 2);
-            fail("no IOOBE, negative offset");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.append(new char[] { 'a', 'b', 'c', 'd' }, -1, 2);
+			fail("no IOOBE, negative offset");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.append(new char[] { 'a', 'b', 'c', 'd' }, 0, -1);
-            fail("no IOOBE, negative length");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.append(new char[] { 'a', 'b', 'c', 'd' }, 0, -1);
+			fail("no IOOBE, negative length");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 3);
-            fail("no IOOBE, offset and length overflow");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb.append(new char[] { 'a', 'b', 'c', 'd' }, 2, 3);
+			fail("no IOOBE, offset and length overflow");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(CharSequence)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class}
-    )
-    public void test_appendLjava_lang_CharSequence() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append((CharSequence) "ab"));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((CharSequence) "cd"));
-        assertEquals("cd", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((CharSequence) null));
-        assertEquals("null", sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(CharSequence)
+	 */
+	public void test_appendLjava_lang_CharSequence() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append((CharSequence) "ab"));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((CharSequence) "cd"));
+		assertEquals("cd", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((CharSequence) null));
+		assertEquals("null", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(CharSequence, int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class, int.class, int.class}
-    )
-    @SuppressWarnings("cast")
+	/**
+	 * @tests java.lang.StringBuilder.append(CharSequence, int, int)
+	 */
+	@SuppressWarnings("cast")
     public void test_appendLjava_lang_CharSequenceII() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append((CharSequence) "ab", 0, 2));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((CharSequence) "cd", 0, 2));
-        assertEquals("cd", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((CharSequence) "abcd", 0, 2));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((CharSequence) "abcd", 2, 4));
-        assertEquals("cd", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((CharSequence) null, 0, 2));
-        assertEquals("nu", sb.toString());
-        
-        try {
-            sb.append((CharSequence) "abcd", -1, 2);
-            fail("IndexOutOfBoundsException was thrown.");
-        } catch(IndexOutOfBoundsException e) {
-            //expected
-        }
-        
-        try {
-            sb.append((CharSequence) "abcd", 0, 5);
-            fail("IndexOutOfBoundsException was thrown.");
-        } catch(IndexOutOfBoundsException e) {
-            //expected
-        }
-        
-        try {
-            sb.append((CharSequence) "abcd", 2, 1);
-            fail("IndexOutOfBoundsException was thrown.");
-        } catch(IndexOutOfBoundsException e) {
-            //expected
-        }        
-    }
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append((CharSequence) "ab", 0, 2));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((CharSequence) "cd", 0, 2));
+		assertEquals("cd", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((CharSequence) "abcd", 0, 2));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((CharSequence) "abcd", 2, 4));
+		assertEquals("cd", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((CharSequence) null, 0, 2));
+		assertEquals("nu", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {double.class}
-    )
-    public void test_appendD() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(1D));
-        assertEquals(String.valueOf(1D), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(0D));
-        assertEquals(String.valueOf(0D), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(-1D));
-        assertEquals(String.valueOf(-1D), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Double.NaN));
-        assertEquals(String.valueOf(Double.NaN), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Double.NEGATIVE_INFINITY));
-        assertEquals(String.valueOf(Double.NEGATIVE_INFINITY), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Double.POSITIVE_INFINITY));
-        assertEquals(String.valueOf(Double.POSITIVE_INFINITY), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Double.MIN_VALUE));
-        assertEquals(String.valueOf(Double.MIN_VALUE), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Double.MAX_VALUE));
-        assertEquals(String.valueOf(Double.MAX_VALUE), sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(double)
+	 */
+	public void test_appendD() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(1D));
+		assertEquals(String.valueOf(1D), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(0D));
+		assertEquals(String.valueOf(0D), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(-1D));
+		assertEquals(String.valueOf(-1D), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Double.NaN));
+		assertEquals(String.valueOf(Double.NaN), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Double.NEGATIVE_INFINITY));
+		assertEquals(String.valueOf(Double.NEGATIVE_INFINITY), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Double.POSITIVE_INFINITY));
+		assertEquals(String.valueOf(Double.POSITIVE_INFINITY), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Double.MIN_VALUE));
+		assertEquals(String.valueOf(Double.MIN_VALUE), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Double.MAX_VALUE));
+		assertEquals(String.valueOf(Double.MAX_VALUE), sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {float.class}
-    )
-    public void test_appendF() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(1F));
-        assertEquals(String.valueOf(1F), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(0F));
-        assertEquals(String.valueOf(0F), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(-1F));
-        assertEquals(String.valueOf(-1F), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Float.NaN));
-        assertEquals(String.valueOf(Float.NaN), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Float.NEGATIVE_INFINITY));
-        assertEquals(String.valueOf(Float.NEGATIVE_INFINITY), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Float.POSITIVE_INFINITY));
-        assertEquals(String.valueOf(Float.POSITIVE_INFINITY), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Float.MIN_VALUE));
-        assertEquals(String.valueOf(Float.MIN_VALUE), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Float.MAX_VALUE));
-        assertEquals(String.valueOf(Float.MAX_VALUE), sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(float)
+	 */
+	public void test_appendF() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(1F));
+		assertEquals(String.valueOf(1F), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(0F));
+		assertEquals(String.valueOf(0F), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(-1F));
+		assertEquals(String.valueOf(-1F), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Float.NaN));
+		assertEquals(String.valueOf(Float.NaN), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Float.NEGATIVE_INFINITY));
+		assertEquals(String.valueOf(Float.NEGATIVE_INFINITY), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Float.POSITIVE_INFINITY));
+		assertEquals(String.valueOf(Float.POSITIVE_INFINITY), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Float.MIN_VALUE));
+		assertEquals(String.valueOf(Float.MIN_VALUE), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Float.MAX_VALUE));
+		assertEquals(String.valueOf(Float.MAX_VALUE), sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {int.class}
-    )
-    public void test_appendI() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(1));
-        assertEquals(String.valueOf(1), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(0));
-        assertEquals(String.valueOf(0), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(-1));
-        assertEquals(String.valueOf(-1), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Integer.MIN_VALUE));
-        assertEquals(String.valueOf(Integer.MIN_VALUE), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Integer.MAX_VALUE));
-        assertEquals(String.valueOf(Integer.MAX_VALUE), sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(int)
+	 */
+	public void test_appendI() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(1));
+		assertEquals(String.valueOf(1), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(0));
+		assertEquals(String.valueOf(0), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(-1));
+		assertEquals(String.valueOf(-1), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Integer.MIN_VALUE));
+		assertEquals(String.valueOf(Integer.MIN_VALUE), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Integer.MAX_VALUE));
+		assertEquals(String.valueOf(Integer.MAX_VALUE), sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {long.class}
-    )
-    public void test_appendL() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(1L));
-        assertEquals(String.valueOf(1L), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(0L));
-        assertEquals(String.valueOf(0L), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(-1L));
-        assertEquals(String.valueOf(-1L), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Integer.MIN_VALUE));
-        assertEquals(String.valueOf(Integer.MIN_VALUE), sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(Integer.MAX_VALUE));
-        assertEquals(String.valueOf(Integer.MAX_VALUE), sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(long)
+	 */
+	public void test_appendL() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(1L));
+		assertEquals(String.valueOf(1L), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(0L));
+		assertEquals(String.valueOf(0L), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(-1L));
+		assertEquals(String.valueOf(-1L), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Integer.MIN_VALUE));
+		assertEquals(String.valueOf(Integer.MIN_VALUE), sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(Integer.MAX_VALUE));
+		assertEquals(String.valueOf(Integer.MAX_VALUE), sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(Object)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.Object.class}
-    )
-    public void test_appendLjava_lang_Object() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(Fixture.INSTANCE));
-        assertEquals(Fixture.INSTANCE.toString(), sb.toString());
+	/**
+	 * @tests java.lang.StringBuilder.append(Object)'
+	 */
+	public void test_appendLjava_lang_Object() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(Fixture.INSTANCE));
+		assertEquals(Fixture.INSTANCE.toString(), sb.toString());
 
-        sb.setLength(0);
-        assertSame(sb, sb.append((Object) null));
-        assertEquals("null", sb.toString());
-    }
+		sb.setLength(0);
+		assertSame(sb, sb.append((Object) null));
+		assertEquals("null", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.String.class}
-    )
-    public void test_appendLjava_lang_String() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append("ab"));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append("cd"));
-        assertEquals("cd", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((String) null));
-        assertEquals("null", sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(String)
+	 */
+	public void test_appendLjava_lang_String() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append("ab"));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append("cd"));
+		assertEquals("cd", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((String) null));
+		assertEquals("null", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.append(StringBuffer)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.StringBuffer.class}
-    )
-    public void test_appendLjava_lang_StringBuffer() {
-        StringBuilder sb = new StringBuilder();
-        assertSame(sb, sb.append(new StringBuffer("ab")));
-        assertEquals("ab", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append(new StringBuffer("cd")));
-        assertEquals("cd", sb.toString());
-        sb.setLength(0);
-        assertSame(sb, sb.append((StringBuffer) null));
-        assertEquals("null", sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.append(StringBuffer)
+	 */
+	public void test_appendLjava_lang_StringBuffer() {
+		StringBuilder sb = new StringBuilder();
+		assertSame(sb, sb.append(new StringBuffer("ab")));
+		assertEquals("ab", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append(new StringBuffer("cd")));
+		assertEquals("cd", sb.toString());
+		sb.setLength(0);
+		assertSame(sb, sb.append((StringBuffer) null));
+		assertEquals("null", sb.toString());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.appendCodePoint(int)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "appendCodePoint",
-        args = {int.class}
-    )
-    public void test_appendCodePointI() {
-        StringBuilder sb = new StringBuilder();
+	/**
+	 * @tests java.lang.StringBuilder.appendCodePoint(int)'
+	 */
+	public void test_appendCodePointI() {
+		StringBuilder sb = new StringBuilder();
         sb.appendCodePoint(0x10000);
         assertEquals("\uD800\uDC00", sb.toString());
         sb.append("fixture");
         assertEquals("\uD800\uDC00fixture", sb.toString());
         sb.appendCodePoint(0x00010FFFF);
         assertEquals("\uD800\uDC00fixture\uDBFF\uDFFF", sb.toString());
-    }
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.capacity()'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "capacity",
-        args = {}
-    )
-    public void test_capacity() {
-        StringBuilder sb = new StringBuilder();
-        assertEquals(16, sb.capacity());
-        sb.append("0123456789ABCDEF0123456789ABCDEF");
-        assertTrue(sb.capacity() > 16);
-    }
+	/**
+	 * @tests java.lang.StringBuilder.capacity()'
+	 */
+	public void test_capacity() {
+		StringBuilder sb = new StringBuilder();
+		assertEquals(16, sb.capacity());
+		sb.append("0123456789ABCDEF0123456789ABCDEF");
+		assertTrue(sb.capacity() > 16);
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.charAt(int)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "charAt",
-        args = {int.class}
-    )
-    public void test_charAtI() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        for (int i = 0; i < fixture.length(); i++) {
-            assertEquals((char) ('0' + i), sb.charAt(i));
-        }
+	/**
+	 * @tests java.lang.StringBuilder.charAt(int)'
+	 */
+	public void test_charAtI() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		for (int i = 0; i < fixture.length(); i++) {
+			assertEquals((char) ('0' + i), sb.charAt(i));
+		}
 
-        try {
-            sb.charAt(-1);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.charAt(-1);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.charAt(fixture.length());
-            fail("no IOOBE, equal to length");
-        } catch (IndexOutOfBoundsException e) {
-        }
+		try {
+			sb.charAt(fixture.length());
+			fail("no IOOBE, equal to length");
+		} catch (IndexOutOfBoundsException e) {
+		}
 
-        try {
-            sb.charAt(fixture.length() + 1);
-            fail("no IOOBE, greater than length");
-        } catch (IndexOutOfBoundsException e) {
-        }
-    }
+		try {
+			sb.charAt(fixture.length() + 1);
+			fail("no IOOBE, greater than length");
+		} catch (IndexOutOfBoundsException e) {
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.codePointAt(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointAt",
-        args = {int.class}
-    )
-    public void test_codePointAtI() {
+	/**
+	 * @tests java.lang.StringBuilder.codePointAt(int)
+	 */
+	public void test_codePointAtI() {
         StringBuilder sb = new StringBuilder("abc");
         assertEquals('a', sb.codePointAt(0));
         assertEquals('b', sb.codePointAt(1));
@@ -607,18 +454,12 @@
         } catch (IndexOutOfBoundsException e) {
             
         }
-    }
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.codePointBefore(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointBefore",
-        args = {int.class}
-    )
-    public void test_codePointBeforeI() {
+	/**
+	 * @tests java.lang.StringBuilder.codePointBefore(int)
+	 */
+	public void test_codePointBeforeI() {
         StringBuilder sb = new StringBuilder("abc");
         assertEquals('a', sb.codePointBefore(1));
         assertEquals('b', sb.codePointBefore(2));
@@ -651,18 +492,12 @@
         } catch (IndexOutOfBoundsException e) {
             
         }
-    }
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.codePointCount(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointCount",
-        args = {int.class, int.class}
-    )
-    public void test_codePointCountII() {
+	/**
+	 * @tests java.lang.StringBuilder.codePointCount(int, int)
+	 */
+	public void test_codePointCountII() {
         assertEquals(1, new StringBuilder("\uD800\uDC00").codePointCount(0, 2));
         assertEquals(1, new StringBuilder("\uD800\uDC01").codePointCount(0, 2));
         assertEquals(1, new StringBuilder("\uD801\uDC01").codePointCount(0, 2));
@@ -693,371 +528,326 @@
         } catch (IndexOutOfBoundsException e) {
             
         }
-    }
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.delete(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "delete",
-        args = {int.class, int.class}
-    )
-    public void test_deleteII() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.delete(0, 0));
-        assertEquals(fixture, sb.toString());
-        assertSame(sb, sb.delete(5, 5));
-        assertEquals(fixture, sb.toString());
-        assertSame(sb, sb.delete(0, 1));
-        assertEquals("123456789", sb.toString());
-        assertEquals(9, sb.length());
-        assertSame(sb, sb.delete(0, sb.length()));
-        assertEquals("", sb.toString());
-        assertEquals(0, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.delete(int, int)
+	 */
+	public void test_deleteII() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.delete(0, 0));
+		assertEquals(fixture, sb.toString());
+		assertSame(sb, sb.delete(5, 5));
+		assertEquals(fixture, sb.toString());
+		assertSame(sb, sb.delete(0, 1));
+		assertEquals("123456789", sb.toString());
+		assertEquals(9, sb.length());
+		assertSame(sb, sb.delete(0, sb.length()));
+		assertEquals("", sb.toString());
+		assertEquals(0, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.delete(0, 11));
-        assertEquals("", sb.toString());
-        assertEquals(0, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.delete(0, 11));
+		assertEquals("", sb.toString());
+		assertEquals(0, sb.length());
 
-        try {
-            new StringBuilder(fixture).delete(-1, 2);
-            fail("no SIOOBE, negative start");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			new StringBuilder(fixture).delete(-1, 2);
+			fail("no SIOOBE, negative start");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            new StringBuilder(fixture).delete(11, 12);
-            fail("no SIOOBE, start too far");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			new StringBuilder(fixture).delete(11, 12);
+			fail("no SIOOBE, start too far");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            new StringBuilder(fixture).delete(13, 12);
-            fail("no SIOOBE, start larger than end");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			new StringBuilder(fixture).delete(13, 12);
+			fail("no SIOOBE, start larger than end");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-    /**
-     * @tests java.lang.StringBuilder.deleteCharAt(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "deleteCharAt",
-        args = {int.class}
-    )
-    public void test_deleteCharAtI() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.deleteCharAt(0));
-        assertEquals("123456789", sb.toString());
-        assertEquals(9, sb.length());
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.deleteCharAt(5));
-        assertEquals("012346789", sb.toString());
-        assertEquals(9, sb.length());
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.deleteCharAt(9));
-        assertEquals("012345678", sb.toString());
-        assertEquals(9, sb.length());
+                // HARMONY 6212
+                sb = new StringBuilder();
+                sb.append("abcde");
+                String str = sb.toString();
+                sb.delete(0, sb.length());
+                sb.append("YY");
+                assertEquals("abcde", str);
+                assertEquals("YY", sb.toString());
+	}
 
-        try {
-            new StringBuilder(fixture).deleteCharAt(-1);
-            fail("no SIOOBE, negative index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+	/**
+	 * @tests java.lang.StringBuilder.deleteCharAt(int)
+	 */
+	public void test_deleteCharAtI() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.deleteCharAt(0));
+		assertEquals("123456789", sb.toString());
+		assertEquals(9, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.deleteCharAt(5));
+		assertEquals("012346789", sb.toString());
+		assertEquals(9, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.deleteCharAt(9));
+		assertEquals("012345678", sb.toString());
+		assertEquals(9, sb.length());
 
-        try {
-            new StringBuilder(fixture).deleteCharAt(fixture.length());
-            fail("no SIOOBE, index equals length");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			new StringBuilder(fixture).deleteCharAt(-1);
+			fail("no SIOOBE, negative index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            new StringBuilder(fixture).deleteCharAt(fixture.length() + 1);
-            fail("no SIOOBE, index exceeds length");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			new StringBuilder(fixture).deleteCharAt(fixture.length());
+			fail("no SIOOBE, index equals length");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-    /**
-     * @tests java.lang.StringBuilder.ensureCapacity(int)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ensureCapacity",
-        args = {int.class}
-    )
-    public void test_ensureCapacityI() {
-        StringBuilder sb = new StringBuilder(5);
-        assertEquals(5, sb.capacity());
-        sb.ensureCapacity(10);
-        assertEquals(12, sb.capacity());
-        sb.ensureCapacity(26);
-        assertEquals(26, sb.capacity());
-        sb.ensureCapacity(55);
-        assertEquals(55, sb.capacity());
-    }
+		try {
+			new StringBuilder(fixture).deleteCharAt(fixture.length() + 1);
+			fail("no SIOOBE, index exceeds length");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.getChars(int, int, char[], int)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getChars",
-        args = {int.class, int.class, char[].class, int.class}
-    )
-    public void test_getCharsII$CI() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        char[] dst = new char[10];
-        sb.getChars(0, 10, dst, 0);
-        assertTrue(Arrays.equals(fixture.toCharArray(), dst));
+	/**
+	 * @tests java.lang.StringBuilder.ensureCapacity(int)'
+	 */
+	public void test_ensureCapacityI() {
+		StringBuilder sb = new StringBuilder(5);
+		assertEquals(5, sb.capacity());
+		sb.ensureCapacity(10);
+		assertEquals(12, sb.capacity());
+		sb.ensureCapacity(26);
+		assertEquals(26, sb.capacity());
+		sb.ensureCapacity(55);
+		assertEquals(55, sb.capacity());
+	}
 
-        Arrays.fill(dst, '\0');
-        sb.getChars(0, 5, dst, 0);
-        char[] fixtureChars = new char[10];
-        fixture.getChars(0, 5, fixtureChars, 0);
-        assertTrue(Arrays.equals(fixtureChars, dst));
+	/**
+	 * @tests java.lang.StringBuilder.getChars(int, int, char[], int)'
+	 */
+	public void test_getCharsII$CI() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		char[] dst = new char[10];
+		sb.getChars(0, 10, dst, 0);
+		assertTrue(Arrays.equals(fixture.toCharArray(), dst));
 
-        Arrays.fill(dst, '\0');
-        Arrays.fill(fixtureChars, '\0');
-        sb.getChars(0, 5, dst, 5);
-        fixture.getChars(0, 5, fixtureChars, 5);
-        assertTrue(Arrays.equals(fixtureChars, dst));
+		Arrays.fill(dst, '\0');
+		sb.getChars(0, 5, dst, 0);
+		char[] fixtureChars = new char[10];
+		fixture.getChars(0, 5, fixtureChars, 0);
+		assertTrue(Arrays.equals(fixtureChars, dst));
 
-        Arrays.fill(dst, '\0');
-        Arrays.fill(fixtureChars, '\0');
-        sb.getChars(5, 10, dst, 1);
-        fixture.getChars(5, 10, fixtureChars, 1);
-        assertTrue(Arrays.equals(fixtureChars, dst));
+		Arrays.fill(dst, '\0');
+		Arrays.fill(fixtureChars, '\0');
+		sb.getChars(0, 5, dst, 5);
+		fixture.getChars(0, 5, fixtureChars, 5);
+		assertTrue(Arrays.equals(fixtureChars, dst));
 
-        try {
-            sb.getChars(0, 10, null, 0);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
+		Arrays.fill(dst, '\0');
+		Arrays.fill(fixtureChars, '\0');
+		sb.getChars(5, 10, dst, 1);
+		fixture.getChars(5, 10, fixtureChars, 1);
+		assertTrue(Arrays.equals(fixtureChars, dst));
 
-        try {
-            sb.getChars(-1, 10, dst, 0);
-            fail("no IOOBE, srcBegin negative");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.getChars(0, 10, null, 0);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
 
-        try {
-            sb.getChars(0, 10, dst, -1);
-            fail("no IOOBE, dstBegin negative");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.getChars(-1, 10, dst, 0);
+			fail("no IOOBE, srcBegin negative");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.getChars(5, 4, dst, 0);
-            fail("no IOOBE, srcBegin > srcEnd");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.getChars(0, 10, dst, -1);
+			fail("no IOOBE, dstBegin negative");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.getChars(0, 11, dst, 0);
-            fail("no IOOBE, srcEnd > length");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.getChars(5, 4, dst, 0);
+			fail("no IOOBE, srcBegin > srcEnd");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.getChars(0, 10, dst, 5);
-            fail("no IOOBE, dstBegin and src size too large for what's left in dst");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb.getChars(0, 11, dst, 0);
+			fail("no IOOBE, srcEnd > length");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-    /**
-     * @tests java.lang.StringBuilder.indexOf(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "indexOf",
-        args = {java.lang.String.class}
-    )
-    public void test_indexOfLjava_lang_String() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertEquals(0, sb.indexOf("0"));
-        assertEquals(0, sb.indexOf("012"));
-        assertEquals(-1, sb.indexOf("02"));
-        assertEquals(8, sb.indexOf("89"));
+		try {
+			sb.getChars(0, 10, dst, 5);
+			fail("no IOOBE, dstBegin and src size too large for what's left in dst");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-        try {
-            sb.indexOf(null);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-    }
+	/**
+	 * @tests java.lang.StringBuilder.indexOf(String)
+	 */
+	public void test_indexOfLjava_lang_String() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertEquals(0, sb.indexOf("0"));
+		assertEquals(0, sb.indexOf("012"));
+		assertEquals(-1, sb.indexOf("02"));
+		assertEquals(8, sb.indexOf("89"));
 
-    /**
-     * @tests java.lang.StringBuilder.indexOf(String, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "indexOf",
-        args = {java.lang.String.class, int.class}
-    )
-    public void test_IndexOfStringInt() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertEquals(0, sb.indexOf("0"));
-        assertEquals(0, sb.indexOf("012"));
-        assertEquals(-1, sb.indexOf("02"));
-        assertEquals(8, sb.indexOf("89"));
+		try {
+			sb.indexOf(null);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
 
-        assertEquals(0, sb.indexOf("0"), 0);
-        assertEquals(0, sb.indexOf("012"), 0);
-        assertEquals(-1, sb.indexOf("02"), 0);
-        assertEquals(8, sb.indexOf("89"), 0);
+	/**
+	 * @tests java.lang.StringBuilder.indexOf(String, int)
+	 */
+	public void test_IndexOfStringInt() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertEquals(0, sb.indexOf("0"));
+		assertEquals(0, sb.indexOf("012"));
+		assertEquals(-1, sb.indexOf("02"));
+		assertEquals(8, sb.indexOf("89"));
 
-        assertEquals(-1, sb.indexOf("0"), 5);
-        assertEquals(-1, sb.indexOf("012"), 5);
-        assertEquals(-1, sb.indexOf("02"), 0);
-        assertEquals(8, sb.indexOf("89"), 5);
+		assertEquals(0, sb.indexOf("0"), 0);
+		assertEquals(0, sb.indexOf("012"), 0);
+		assertEquals(-1, sb.indexOf("02"), 0);
+		assertEquals(8, sb.indexOf("89"), 0);
 
-        try {
-            sb.indexOf(null, 0);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-    }
+		assertEquals(-1, sb.indexOf("0"), 5);
+		assertEquals(-1, sb.indexOf("012"), 5);
+		assertEquals(-1, sb.indexOf("02"), 0);
+		assertEquals(8, sb.indexOf("89"), 5);
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, boolean.class}
-    )
-    public void test_insertIZ() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, true));
-        assertEquals("true0000", sb.toString());
-        assertEquals(8, sb.length());
+		try {
+			sb.indexOf(null, 0);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, false));
-        assertEquals("false0000", sb.toString());
-        assertEquals(9, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, boolean)
+	 */
+	public void test_insertIZ() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, true));
+		assertEquals("true0000", sb.toString());
+		assertEquals(8, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, false));
-        assertEquals("00false00", sb.toString());
-        assertEquals(9, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, false));
+		assertEquals("false0000", sb.toString());
+		assertEquals(9, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, false));
-        assertEquals("0000false", sb.toString());
-        assertEquals(9, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, false));
+		assertEquals("00false00", sb.toString());
+		assertEquals(9, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, false);
-            fail("no SIOOBE, negative index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, false));
+		assertEquals("0000false", sb.toString());
+		assertEquals(9, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, false);
-            fail("no SIOOBE, index too large index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, false);
+			fail("no SIOOBE, negative index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, false);
+			fail("no SIOOBE, index too large index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
+
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, char)
+	 */
+	public void test_insertIC() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, 'a'));
+		assertEquals("a0000", sb.toString());
+		assertEquals(5, sb.length());
+
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, 'b'));
+		assertEquals("b0000", sb.toString());
+		assertEquals(5, sb.length());
+
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, 'b'));
+		assertEquals("00b00", sb.toString());
+		assertEquals(5, sb.length());
+
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, 'b'));
+		assertEquals("0000b", sb.toString());
+		assertEquals(5, sb.length());
+
+		// FIXME this fails on Sun JRE 5.0_5
+//		try {
+//			sb = new StringBuilder(fixture);
+//			sb.insert(-1, 'a');
+//			fail("no SIOOBE, negative index");
+//		} catch (StringIndexOutOfBoundsException e) {
+//			// Expected
+//		}
+
+		/*
+		 * FIXME This fails on Sun JRE 5.0_5, but that seems like a bug, since
+		 * the 'insert(int, char[]) behaves this way.
+		 */
+//		try {
+//			sb = new StringBuilder(fixture);
+//			sb.insert(5, 'a');
+//			fail("no SIOOBE, index too large index");
+//		} catch (StringIndexOutOfBoundsException e) {
+//			// Expected
+//		}
+	}
 
     /**
      * @tests java.lang.StringBuilder.insert(int, char)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IndexOutOfBoundsException is not verified.",
-        method = "insert",
-        args = {int.class, char.class}
-    )
-    public void test_insertIC() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, 'a'));
-        assertEquals("a0000", sb.toString());
-        assertEquals(5, sb.length());
-
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, 'b'));
-        assertEquals("b0000", sb.toString());
-        assertEquals(5, sb.length());
-
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, 'b'));
-        assertEquals("00b00", sb.toString());
-        assertEquals(5, sb.length());
-
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, 'b'));
-        assertEquals("0000b", sb.toString());
-        assertEquals(5, sb.length());
-
-        // FIXME this fails on Sun JRE 5.0_5
-//        try {
-//            sb = new StringBuilder(fixture);
-//            sb.insert(-1, 'a');
-//            fail("no SIOOBE, negative index");
-//        } catch (StringIndexOutOfBoundsException e) {
-//            // Expected
-//        }
-
-        /*
-         * FIXME This fails on Sun JRE 5.0_5, but that seems like a bug, since
-         * the 'insert(int, char[]) behaves this way.
-         */
-//        try {
-//            sb = new StringBuilder(fixture);
-//            sb.insert(5, 'a');
-//            fail("no SIOOBE, index too large index");
-//        } catch (StringIndexOutOfBoundsException e) {
-//            // Expected
-//        }
-    }
-
-    /**
-     * @tests java.lang.StringBuilder.insert(int, char)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies ArrayIndexOutOfBoundsException.",
-        method = "insert",
-        args = {int.class, char.class}
-    )
     public void test_insertIC_2() {
         StringBuilder obj = new StringBuilder();
         try {
@@ -1069,668 +859,584 @@
     }
 
     /**
-     * @tests java.lang.StringBuilder.insert(int, char[])'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, char[].class}
-    )
-    public void test_insertI$C() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }));
-        assertEquals("ab0000", sb.toString());
-        assertEquals(6, sb.length());
+	 * @tests java.lang.StringBuilder.insert(int, char[])'
+	 */
+	public void test_insertI$C() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }));
+		assertEquals("ab0000", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }));
-        assertEquals("00ab00", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }));
+		assertEquals("00ab00", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }));
-        assertEquals("0000ab", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }));
+		assertEquals("0000ab", sb.toString());
+		assertEquals(6, sb.length());
 
-        /*
-         * TODO This NPE is the behavior on Sun's JRE 5.0_5, but it's
-         * undocumented. The assumption is that this method behaves like
-         * String.valueOf(char[]), which does throw a NPE too, but that is also
-         * undocumented.
-         */
+		/*
+		 * TODO This NPE is the behavior on Sun's JRE 5.0_5, but it's
+		 * undocumented. The assumption is that this method behaves like
+		 * String.valueOf(char[]), which does throw a NPE too, but that is also
+		 * undocumented.
+		 */
 
-        try {
-            sb.insert(0, (char[]) null);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
+		try {
+			sb.insert(0, (char[]) null);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, new char[] { 'a', 'b' });
-            fail("no SIOOBE, negative index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, new char[] { 'a', 'b' });
+			fail("no SIOOBE, negative index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' });
-            fail("no SIOOBE, index too large index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' });
+			fail("no SIOOBE, index too large index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, char[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, char[].class, int.class, int.class}
-    )
-    public void test_insertI$CII() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }, 0, 2));
-        assertEquals("ab0000", sb.toString());
-        assertEquals(6, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, char[], int, int)
+	 */
+	public void test_insertI$CII() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }, 0, 2));
+		assertEquals("ab0000", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }, 0, 1));
-        assertEquals("a0000", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, new char[] { 'a', 'b' }, 0, 1));
+		assertEquals("a0000", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }, 0, 2));
-        assertEquals("00ab00", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }, 0, 2));
+		assertEquals("00ab00", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }, 0, 1));
-        assertEquals("00a00", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, new char[] { 'a', 'b' }, 0, 1));
+		assertEquals("00a00", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }, 0, 2));
-        assertEquals("0000ab", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }, 0, 2));
+		assertEquals("0000ab", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }, 0, 1));
-        assertEquals("0000a", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, new char[] { 'a', 'b' }, 0, 1));
+		assertEquals("0000a", sb.toString());
+		assertEquals(5, sb.length());
 
-        /*
-         * TODO This NPE is the behavior on Sun's JRE 5.0_5, but it's
-         * undocumented. The assumption is that this method behaves like
-         * String.valueOf(char[]), which does throw a NPE too, but that is also
-         * undocumented.
-         */
+		/*
+		 * TODO This NPE is the behavior on Sun's JRE 5.0_5, but it's
+		 * undocumented. The assumption is that this method behaves like
+		 * String.valueOf(char[]), which does throw a NPE too, but that is also
+		 * undocumented.
+		 */
 
-        try {
-            sb.insert(0, (char[]) null, 0, 2);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
+		try {
+			sb.insert(0, (char[]) null, 0, 2);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, new char[] { 'a', 'b' }, 0, 2);
-            fail("no SIOOBE, negative index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, new char[] { 'a', 'b' }, 0, 2);
+			fail("no SIOOBE, negative index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' }, 0, 2);
-            fail("no SIOOBE, index too large index");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' }, 0, 2);
+			fail("no SIOOBE, index too large index");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' }, -1, 2);
-            fail("no SIOOBE, negative offset");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' }, -1, 2);
+			fail("no SIOOBE, negative offset");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
-            fail("no SIOOBE, negative length");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
+			fail("no SIOOBE, negative length");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
-            fail("no SIOOBE, too long");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
+			fail("no SIOOBE, too long");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, CharSequence)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, java.lang.CharSequence.class}
-    )
-    public void test_insertILjava_lang_CharSequence() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, (CharSequence) "ab"));
-        assertEquals("ab0000", sb.toString());
-        assertEquals(6, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, CharSequence)
+	 */
+	public void test_insertILjava_lang_CharSequence() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, (CharSequence) "ab"));
+		assertEquals("ab0000", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, (CharSequence) "ab"));
-        assertEquals("00ab00", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, (CharSequence) "ab"));
+		assertEquals("00ab00", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (CharSequence) "ab"));
-        assertEquals("0000ab", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (CharSequence) "ab"));
+		assertEquals("0000ab", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (CharSequence) null));
-        assertEquals("0000null", sb.toString());
-        assertEquals(8, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (CharSequence) null));
+		assertEquals("0000null", sb.toString());
+		assertEquals(8, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, (CharSequence) "ab");
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, (CharSequence) "ab");
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, (CharSequence) "ab");
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, (CharSequence) "ab");
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, CharSequence, int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, java.lang.CharSequence.class, int.class, int.class}
-    )
-    @SuppressWarnings("cast")
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, CharSequence, int, int)
+	 */
+	@SuppressWarnings("cast")
     public void test_insertILjava_lang_CharSequenceII() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 2));
-        assertEquals("ab0000", sb.toString());
-        assertEquals(6, sb.length());
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 2));
+		assertEquals("ab0000", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 1));
-        assertEquals("a0000", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 1));
+		assertEquals("a0000", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 2));
-        assertEquals("00ab00", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 2));
+		assertEquals("00ab00", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 1));
-        assertEquals("00a00", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 1));
+		assertEquals("00a00", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 2));
-        assertEquals("0000ab", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 2));
+		assertEquals("0000ab", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 1));
-        assertEquals("0000a", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 1));
+		assertEquals("0000a", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (CharSequence) null, 0, 2));
-        assertEquals("0000nu", sb.toString());
-        assertEquals(6, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (CharSequence) null, 0, 2));
+		assertEquals("0000nu", sb.toString());
+		assertEquals(6, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, (CharSequence) "ab", 0, 2);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, (CharSequence) "ab", 0, 2);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, (CharSequence) "ab", 0, 2);
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, (CharSequence) "ab", 0, 2);
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, (CharSequence) "ab", -1, 2);
-            fail("no IOOBE, negative offset");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, (CharSequence) "ab", -1, 2);
+			fail("no IOOBE, negative offset");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
-            fail("no IOOBE, negative length");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' }, 0, -1);
+			fail("no IOOBE, negative length");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
-            fail("no IOOBE, too long");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, new char[] { 'a', 'b' }, 0, 3);
+			fail("no IOOBE, too long");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, double.class}
-    )
-    public void test_insertID() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, -1D));
-        assertEquals("-1.00000", sb.toString());
-        assertEquals(8, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, double)
+	 */
+	public void test_insertID() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, -1D));
+		assertEquals("-1.00000", sb.toString());
+		assertEquals(8, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, 0D));
-        assertEquals("0.00000", sb.toString());
-        assertEquals(7, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, 0D));
+		assertEquals("0.00000", sb.toString());
+		assertEquals(7, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, 1D));
-        assertEquals("001.000", sb.toString());
-        assertEquals(7, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, 1D));
+		assertEquals("001.000", sb.toString());
+		assertEquals(7, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, 2D));
-        assertEquals("00002.0", sb.toString());
-        assertEquals(7, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, 2D));
+		assertEquals("00002.0", sb.toString());
+		assertEquals(7, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, 1D);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, 1D);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, 1D);
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, 1D);
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, float.class}
-    )
-    public void test_insertIF() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, -1F));
-        assertEquals("-1.00000", sb.toString());
-        assertEquals(8, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, float)
+	 */
+	public void test_insertIF() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, -1F));
+		assertEquals("-1.00000", sb.toString());
+		assertEquals(8, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, 0F));
-        assertEquals("0.00000", sb.toString());
-        assertEquals(7, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, 0F));
+		assertEquals("0.00000", sb.toString());
+		assertEquals(7, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, 1F));
-        assertEquals("001.000", sb.toString());
-        assertEquals(7, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, 1F));
+		assertEquals("001.000", sb.toString());
+		assertEquals(7, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, 2F));
-        assertEquals("00002.0", sb.toString());
-        assertEquals(7, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, 2F));
+		assertEquals("00002.0", sb.toString());
+		assertEquals(7, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, 1F);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, 1F);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, 1F);
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, 1F);
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, int.class}
-    )
-    public void test_insertII() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, -1));
-        assertEquals("-10000", sb.toString());
-        assertEquals(6, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, int)
+	 */
+	public void test_insertII() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, -1));
+		assertEquals("-10000", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, 0));
-        assertEquals("00000", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, 0));
+		assertEquals("00000", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, 1));
-        assertEquals("00100", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, 1));
+		assertEquals("00100", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, 2));
-        assertEquals("00002", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, 2));
+		assertEquals("00002", sb.toString());
+		assertEquals(5, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, 1);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, 1);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, 1);
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, 1);
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, long.class}
-    )
-    public void test_insertIJ() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, -1L));
-        assertEquals("-10000", sb.toString());
-        assertEquals(6, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, long)
+	 */
+	public void test_insertIJ() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, -1L));
+		assertEquals("-10000", sb.toString());
+		assertEquals(6, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, 0L));
-        assertEquals("00000", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, 0L));
+		assertEquals("00000", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, 1L));
-        assertEquals("00100", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, 1L));
+		assertEquals("00100", sb.toString());
+		assertEquals(5, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, 2L));
-        assertEquals("00002", sb.toString());
-        assertEquals(5, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, 2L));
+		assertEquals("00002", sb.toString());
+		assertEquals(5, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, 1L);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, 1L);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, 1L);
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, 1L);
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, Object)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, java.lang.Object.class}
-    )
-    public void test_insertILjava_lang_Object() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, Fixture.INSTANCE));
-        assertEquals("fixture0000", sb.toString());
-        assertEquals(11, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, Object)
+	 */
+	public void test_insertILjava_lang_Object() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, Fixture.INSTANCE));
+		assertEquals("fixture0000", sb.toString());
+		assertEquals(11, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, Fixture.INSTANCE));
-        assertEquals("00fixture00", sb.toString());
-        assertEquals(11, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, Fixture.INSTANCE));
+		assertEquals("00fixture00", sb.toString());
+		assertEquals(11, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, Fixture.INSTANCE));
-        assertEquals("0000fixture", sb.toString());
-        assertEquals(11, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, Fixture.INSTANCE));
+		assertEquals("0000fixture", sb.toString());
+		assertEquals(11, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (Object) null));
-        assertEquals("0000null", sb.toString());
-        assertEquals(8, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (Object) null));
+		assertEquals("0000null", sb.toString());
+		assertEquals(8, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, Fixture.INSTANCE);
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, Fixture.INSTANCE);
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, Fixture.INSTANCE);
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, Fixture.INSTANCE);
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.insert(int, String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "insert",
-        args = {int.class, java.lang.String.class}
-    )
-    public void test_insertILjava_lang_String() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(0, "fixture"));
-        assertEquals("fixture0000", sb.toString());
-        assertEquals(11, sb.length());
+	/**
+	 * @tests java.lang.StringBuilder.insert(int, String)
+	 */
+	public void test_insertILjava_lang_String() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(0, "fixture"));
+		assertEquals("fixture0000", sb.toString());
+		assertEquals(11, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(2, "fixture"));
-        assertEquals("00fixture00", sb.toString());
-        assertEquals(11, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(2, "fixture"));
+		assertEquals("00fixture00", sb.toString());
+		assertEquals(11, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, "fixture"));
-        assertEquals("0000fixture", sb.toString());
-        assertEquals(11, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, "fixture"));
+		assertEquals("0000fixture", sb.toString());
+		assertEquals(11, sb.length());
 
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.insert(4, (Object) null));
-        assertEquals("0000null", sb.toString());
-        assertEquals(8, sb.length());
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.insert(4, (Object) null));
+		assertEquals("0000null", sb.toString());
+		assertEquals(8, sb.length());
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(-1, "fixture");
-            fail("no IOOBE, negative index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(-1, "fixture");
+			fail("no IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb = new StringBuilder(fixture);
-            sb.insert(5, "fixture");
-            fail("no IOOBE, index too large index");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb = new StringBuilder(fixture);
+			sb.insert(5, "fixture");
+			fail("no IOOBE, index too large index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.lastIndexOf(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "lastIndexOf",
-        args = {java.lang.String.class}
-    )
-    public void test_lastIndexOfLjava_lang_String() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertEquals(0, sb.lastIndexOf("0"));
-        assertEquals(0, sb.lastIndexOf("012"));
-        assertEquals(-1, sb.lastIndexOf("02"));
-        assertEquals(8, sb.lastIndexOf("89"));
+	/**
+	 * @tests java.lang.StringBuilder.lastIndexOf(String)
+	 */
+	public void test_lastIndexOfLjava_lang_String() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertEquals(0, sb.lastIndexOf("0"));
+		assertEquals(0, sb.lastIndexOf("012"));
+		assertEquals(-1, sb.lastIndexOf("02"));
+		assertEquals(8, sb.lastIndexOf("89"));
 
-        try {
-            sb.lastIndexOf(null);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-    }
+		try {
+			sb.lastIndexOf(null);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.lastIndexOf(String, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "lastIndexOf",
-        args = {java.lang.String.class, int.class}
-    )
-    public void test_lastIndexOfLjava_lang_StringI() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertEquals(0, sb.lastIndexOf("0"));
-        assertEquals(0, sb.lastIndexOf("012"));
-        assertEquals(-1, sb.lastIndexOf("02"));
-        assertEquals(8, sb.lastIndexOf("89"));
+	/**
+	 * @tests java.lang.StringBuilder.lastIndexOf(String, int)
+	 */
+	public void test_lastIndexOfLjava_lang_StringI() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertEquals(0, sb.lastIndexOf("0"));
+		assertEquals(0, sb.lastIndexOf("012"));
+		assertEquals(-1, sb.lastIndexOf("02"));
+		assertEquals(8, sb.lastIndexOf("89"));
 
-        assertEquals(0, sb.lastIndexOf("0"), 0);
-        assertEquals(0, sb.lastIndexOf("012"), 0);
-        assertEquals(-1, sb.lastIndexOf("02"), 0);
-        assertEquals(8, sb.lastIndexOf("89"), 0);
+		assertEquals(0, sb.lastIndexOf("0"), 0);
+		assertEquals(0, sb.lastIndexOf("012"), 0);
+		assertEquals(-1, sb.lastIndexOf("02"), 0);
+		assertEquals(8, sb.lastIndexOf("89"), 0);
 
-        assertEquals(-1, sb.lastIndexOf("0"), 5);
-        assertEquals(-1, sb.lastIndexOf("012"), 5);
-        assertEquals(-1, sb.lastIndexOf("02"), 0);
-        assertEquals(8, sb.lastIndexOf("89"), 5);
+		assertEquals(-1, sb.lastIndexOf("0"), 5);
+		assertEquals(-1, sb.lastIndexOf("012"), 5);
+		assertEquals(-1, sb.lastIndexOf("02"), 0);
+		assertEquals(8, sb.lastIndexOf("89"), 5);
 
-        try {
-            sb.lastIndexOf(null, 0);
-            fail("no NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-    }
+		try {
+			sb.lastIndexOf(null, 0);
+			fail("no NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.length()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "length",
-        args = {}
-    )
-    public void test_length() {
-        StringBuilder sb = new StringBuilder();
-        assertEquals(0, sb.length());
-        sb.append("0000");
-        assertEquals(4, sb.length());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.length()
+	 */
+	public void test_length() {
+		StringBuilder sb = new StringBuilder();
+		assertEquals(0, sb.length());
+		sb.append("0000");
+		assertEquals(4, sb.length());
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.offsetByCodePoints(int, int)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "offsetByCodePoints",
-        args = {int.class, int.class}
-    )
-    public void test_offsetByCodePointsII() {
+	/**
+	 * @tests java.lang.StringBuilder.offsetByCodePoints(int, int)'
+	 */
+	public void test_offsetByCodePointsII() {
         int result = new StringBuilder("a\uD800\uDC00b").offsetByCodePoints(0, 2);
         assertEquals(3, result);
 
@@ -1791,87 +1497,102 @@
         } catch (IndexOutOfBoundsException e) {
             
         }
+	}
+
+	/**
+	 * @tests java.lang.StringBuilder.replace(int, int, String)'
+	 */
+	public void test_replaceIILjava_lang_String() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertSame(sb, sb.replace(1, 3, "11"));
+		assertEquals("0110", sb.toString());
+		assertEquals(4, sb.length());
+
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.replace(1, 2, "11"));
+		assertEquals("01100", sb.toString());
+		assertEquals(5, sb.length());
+
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.replace(4, 5, "11"));
+		assertEquals("000011", sb.toString());
+		assertEquals(6, sb.length());
+
+		sb = new StringBuilder(fixture);
+		assertSame(sb, sb.replace(4, 6, "11"));
+		assertEquals("000011", sb.toString());
+		assertEquals(6, sb.length());
+
+		// FIXME Undocumented NPE in Sun's JRE 5.0_5
+		try {
+			sb.replace(1, 2, null);
+			fail("No NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+
+		try {
+			sb = new StringBuilder(fixture);
+			sb.replace(-1, 2, "11");
+			fail("No SIOOBE, negative start");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb = new StringBuilder(fixture);
+			sb.replace(5, 2, "11");
+			fail("No SIOOBE, start > length");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb = new StringBuilder(fixture);
+			sb.replace(3, 2, "11");
+			fail("No SIOOBE, start > end");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		// Regression for HARMONY-348
+		StringBuilder buffer = new StringBuilder("1234567");
+		buffer.replace(2, 6, "XXX");
+		assertEquals("12XXX7",buffer.toString());
+	}
+
+    private void reverseTest(String org, String rev, String back) {
+        // create non-shared StringBuilder
+        StringBuilder sb = new StringBuilder(org);
+        sb.reverse();
+        String reversed = sb.toString();
+        assertEquals(rev, reversed);
+        // create non-shared StringBuilder
+        sb = new StringBuilder(reversed);
+        sb.reverse();
+        reversed = sb.toString();
+        assertEquals(back, reversed);
+
+        // test algorithm when StringBuilder is shared
+        sb = new StringBuilder(org);
+        String copy = sb.toString();
+        assertEquals(org, copy);
+        sb.reverse();
+        reversed = sb.toString();
+        assertEquals(rev, reversed);
+        sb = new StringBuilder(reversed);
+        copy = sb.toString();
+        assertEquals(rev, copy);
+        sb.reverse();
+        reversed = sb.toString();
+        assertEquals(back, reversed);
     }
 
-    /**
-     * @tests java.lang.StringBuilder.replace(int, int, String)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "replace",
-        args = {int.class, int.class, java.lang.String.class}
-    )
-    public void test_replaceIILjava_lang_String() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertSame(sb, sb.replace(1, 3, "11"));
-        assertEquals("0110", sb.toString());
-        assertEquals(4, sb.length());
-
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.replace(1, 2, "11"));
-        assertEquals("01100", sb.toString());
-        assertEquals(5, sb.length());
-
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.replace(4, 5, "11"));
-        assertEquals("000011", sb.toString());
-        assertEquals(6, sb.length());
-
-        sb = new StringBuilder(fixture);
-        assertSame(sb, sb.replace(4, 6, "11"));
-        assertEquals("000011", sb.toString());
-        assertEquals(6, sb.length());
-
-        // FIXME Undocumented NPE in Sun's JRE 5.0_5
-        try {
-            sb.replace(1, 2, null);
-            fail("No NPE");
-        } catch (NullPointerException e) {
-            // Expected
-        }
-
-        try {
-            sb = new StringBuilder(fixture);
-            sb.replace(-1, 2, "11");
-            fail("No SIOOBE, negative start");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-
-        try {
-            sb = new StringBuilder(fixture);
-            sb.replace(5, 2, "11");
-            fail("No SIOOBE, start > length");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-
-        try {
-            sb = new StringBuilder(fixture);
-            sb.replace(3, 2, "11");
-            fail("No SIOOBE, start > end");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-
-        // Regression for HARMONY-348
-        StringBuilder buffer = new StringBuilder("1234567");
-        buffer.replace(2, 6, "XXX");
-        assertEquals("12XXX7",buffer.toString());
-    }
-
-    /**
-     * @tests java.lang.StringBuilder.reverse()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "reverse",
-        args = {}
-    )
-    public void test_reverse() {
+	/**
+	 * @tests java.lang.StringBuilder.reverse()
+	 */
+	public void test_reverse() {
         final String fixture = "0123456789";
         StringBuilder sb = new StringBuilder(fixture);
         assertSame(sb, sb.reverse());
@@ -1888,251 +1609,335 @@
         sb.setLength(0);
         assertSame(sb, sb.reverse());
         assertEquals("", sb.toString());
+
+        String str;
+        str = "a";
+        reverseTest(str, str, str);
+
+        str = "ab";
+        reverseTest(str, "ba", str);
+
+        str = "abcdef";
+        reverseTest(str, "fedcba", str);
+
+        str = "abcdefg";
+        reverseTest(str, "gfedcba", str);
+
+        str = "\ud800\udc00";
+        reverseTest(str, str, str);
+
+        str = "\udc00\ud800";
+        reverseTest(str, "\ud800\udc00", "\ud800\udc00");
+
+        str = "a\ud800\udc00";
+        reverseTest(str, "\ud800\udc00a", str);
+
+        str = "ab\ud800\udc00";
+        reverseTest(str, "\ud800\udc00ba", str);
+
+        str = "abc\ud800\udc00";
+        reverseTest(str, "\ud800\udc00cba", str);
+
+        str = "\ud800\udc00\udc01\ud801\ud802\udc02";
+        reverseTest(str, "\ud802\udc02\ud801\udc01\ud800\udc00",
+                "\ud800\udc00\ud801\udc01\ud802\udc02");
+
+        str = "\ud800\udc00\ud801\udc01\ud802\udc02";
+        reverseTest(str, "\ud802\udc02\ud801\udc01\ud800\udc00", str);
+
+        str = "\ud800\udc00\udc01\ud801a";
+        reverseTest(str, "a\ud801\udc01\ud800\udc00",
+                "\ud800\udc00\ud801\udc01a");
+
+        str = "a\ud800\udc00\ud801\udc01";
+        reverseTest(str, "\ud801\udc01\ud800\udc00a", str);
+
+        str = "\ud800\udc00\udc01\ud801ab";
+        reverseTest(str, "ba\ud801\udc01\ud800\udc00",
+                "\ud800\udc00\ud801\udc01ab");
+
+        str = "ab\ud800\udc00\ud801\udc01";
+        reverseTest(str, "\ud801\udc01\ud800\udc00ba", str);
+
+        str = "\ud800\udc00\ud801\udc01";
+        reverseTest(str, "\ud801\udc01\ud800\udc00", str);
+
+        str = "a\ud800\udc00z\ud801\udc01";
+        reverseTest(str, "\ud801\udc01z\ud800\udc00a", str);
+
+        str = "a\ud800\udc00bz\ud801\udc01";
+        reverseTest(str, "\ud801\udc01zb\ud800\udc00a", str);
+
+        str = "abc\ud802\udc02\ud801\udc01\ud800\udc00";
+        reverseTest(str, "\ud800\udc00\ud801\udc01\ud802\udc02cba", str);
+
+        str = "abcd\ud802\udc02\ud801\udc01\ud800\udc00";
+        reverseTest(str, "\ud800\udc00\ud801\udc01\ud802\udc02dcba", str);
     }
 
-    /**
-     * @tests java.lang.StringBuilder.setCharAt(int, char)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setCharAt",
-        args = {int.class, char.class}
-    )
-    public void test_setCharAtIC() {
-        final String fixture = "0000";
-        StringBuilder sb = new StringBuilder(fixture);
-        sb.setCharAt(0, 'A');
-        assertEquals("A000", sb.toString());
-        sb.setCharAt(1, 'B');
-        assertEquals("AB00", sb.toString());
-        sb.setCharAt(2, 'C');
-        assertEquals("ABC0", sb.toString());
-        sb.setCharAt(3, 'D');
-        assertEquals("ABCD", sb.toString());
+	/**
+	 * @tests java.lang.StringBuilder.setCharAt(int, char)
+	 */
+	public void test_setCharAtIC() {
+		final String fixture = "0000";
+		StringBuilder sb = new StringBuilder(fixture);
+		sb.setCharAt(0, 'A');
+		assertEquals("A000", sb.toString());
+		sb.setCharAt(1, 'B');
+		assertEquals("AB00", sb.toString());
+		sb.setCharAt(2, 'C');
+		assertEquals("ABC0", sb.toString());
+		sb.setCharAt(3, 'D');
+		assertEquals("ABCD", sb.toString());
 
+		try {
+			sb.setCharAt(-1, 'A');
+			fail("No IOOBE, negative index");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb.setCharAt(4, 'A');
+			fail("No IOOBE, index == length");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb.setCharAt(5, 'A');
+			fail("No IOOBE, index > length");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
+
+	/**
+	 * @tests java.lang.StringBuilder.setLength(int)'
+	 */
+	public void test_setLengthI() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		sb.setLength(5);
+		assertEquals(5, sb.length());
+		assertEquals("01234", sb.toString());
+		sb.setLength(6);
+		assertEquals(6, sb.length());
+		assertEquals("01234\0", sb.toString());
+		sb.setLength(0);
+		assertEquals(0, sb.length());
+		assertEquals("", sb.toString());
+
+		try {
+			sb.setLength(-1);
+			fail("No IOOBE, negative length.");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+
+        sb = new StringBuilder("abcde");
+        assertEquals("abcde", sb.toString());
+        sb.setLength(1);
+        sb.append('g');
+        assertEquals("ag", sb.toString());
+
+        sb = new StringBuilder("abcde");
+        sb.setLength(3);
+        sb.append('g');
+        assertEquals("abcg", sb.toString());
+
+        sb = new StringBuilder("abcde");
+        sb.setLength(2);
         try {
-            sb.setCharAt(-1, 'A');
-            fail("No IOOBE, negative index");
+            sb.charAt(3);
+            fail("should throw IndexOutOfBoundsException");
         } catch (IndexOutOfBoundsException e) {
             // Expected
         }
 
-        try {
-            sb.setCharAt(4, 'A');
-            fail("No IOOBE, index == length");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-
-        try {
-            sb.setCharAt(5, 'A');
-            fail("No IOOBE, index > length");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
-
-    /**
-     * @tests java.lang.StringBuilder.setLength(int)'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setLength",
-        args = {int.class}
-    )
-    public void test_setLengthI() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
+        sb = new StringBuilder();
+        sb.append("abcdefg");
+        sb.setLength(2);
         sb.setLength(5);
-        assertEquals(5, sb.length());
-        assertEquals("01234", sb.toString());
-        sb.setLength(6);
-        assertEquals(6, sb.length());
-        assertEquals("01234\0", sb.toString());
-        sb.setLength(0);
-        assertEquals(0, sb.length());
-        assertEquals("", sb.toString());
-
-        try {
-            sb.setLength(-1);
-            fail("No IOOBE, negative length.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
-
-    /**
-     * @tests java.lang.StringBuilder.subSequence(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "subSequence",
-        args = {int.class, int.class}
-    )
-    public void test_subSequenceII() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        CharSequence ss = sb.subSequence(0, 5);
-        assertEquals("01234", ss.toString());
-
-        ss = sb.subSequence(0, 0);
-        assertEquals("", ss.toString());
-
-        try {
-            sb.subSequence(-1, 1);
-            fail("No IOOBE, negative start.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
+        for (int i = 2; i < 5; i++) {
+            assertEquals(0, sb.charAt(i));
         }
 
-        try {
-            sb.subSequence(0, -1);
-            fail("No IOOBE, negative end.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
+        sb = new StringBuilder();
+        sb.append("abcdefg");
+        sb.delete(2, 4);
+        sb.setLength(7);
+        assertEquals('a', sb.charAt(0));
+        assertEquals('b', sb.charAt(1));
+        assertEquals('e', sb.charAt(2));
+        assertEquals('f', sb.charAt(3));
+        assertEquals('g', sb.charAt(4));
+        for (int i = 5; i < 7; i++) {
+            assertEquals(0, sb.charAt(i));
         }
 
-        try {
-            sb.subSequence(0, fixture.length() + 1);
-            fail("No IOOBE, end > length.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
+        sb = new StringBuilder();
+        sb.append("abcdefg");
+        sb.replace(2, 5, "z");
+        sb.setLength(7);
+        for (int i = 5; i < 7; i++) {
+            assertEquals(0, sb.charAt(i));
         }
+	}
 
-        try {
-            sb.subSequence(3, 2);
-            fail("No IOOBE, start > end.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+	/**
+	 * @tests java.lang.StringBuilder.subSequence(int, int)
+	 */
+	public void test_subSequenceII() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		CharSequence ss = sb.subSequence(0, 5);
+		assertEquals("01234", ss.toString());
 
-    /**
-     * @tests java.lang.StringBuilder.substring(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "substring",
-        args = {int.class}
-    )
-    public void test_substringI() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        String ss = sb.substring(0);
-        assertEquals(fixture, ss);
+		ss = sb.subSequence(0, 0);
+		assertEquals("", ss.toString());
 
-        ss = sb.substring(10);
-        assertEquals("", ss);
+		try {
+			sb.subSequence(-1, 1);
+			fail("No IOOBE, negative start.");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.substring(-1);
-            fail("No SIOOBE, negative start.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.subSequence(0, -1);
+			fail("No IOOBE, negative end.");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.substring(0, -1);
-            fail("No SIOOBE, negative end.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.subSequence(0, fixture.length() + 1);
+			fail("No IOOBE, end > length.");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.substring(fixture.length() + 1);
-            fail("No SIOOBE, start > length.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+		try {
+			sb.subSequence(3, 2);
+			fail("No IOOBE, start > end.");
+		} catch (IndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-    /**
-     * @tests java.lang.StringBuilder.substring(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "substring",
-        args = {int.class, int.class}
-    )
-    public void test_substringII() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        String ss = sb.substring(0, 5);
-        assertEquals("01234", ss);
+	/**
+	 * @tests java.lang.StringBuilder.substring(int)
+	 */
+	public void test_substringI() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		String ss = sb.substring(0);
+		assertEquals(fixture, ss);
 
-        ss = sb.substring(0, 0);
-        assertEquals("", ss);
+		ss = sb.substring(10);
+		assertEquals("", ss);
 
-        try {
-            sb.substring(-1, 1);
-            fail("No SIOOBE, negative start.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.substring(-1);
+			fail("No SIOOBE, negative start.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.substring(0, -1);
-            fail("No SIOOBE, negative end.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.substring(0, -1);
+			fail("No SIOOBE, negative end.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
 
-        try {
-            sb.substring(0, fixture.length() + 1);
-            fail("No SIOOBE, end > length.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
+		try {
+			sb.substring(fixture.length() + 1);
+			fail("No SIOOBE, start > length.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
-        try {
-            sb.substring(3, 2);
-            fail("No SIOOBE, start > end.");
-        } catch (StringIndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+	/**
+	 * @tests java.lang.StringBuilder.substring(int, int)
+	 */
+	public void test_substringII() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		String ss = sb.substring(0, 5);
+		assertEquals("01234", ss);
+
+		ss = sb.substring(0, 0);
+		assertEquals("", ss);
+
+		try {
+			sb.substring(-1, 1);
+			fail("No SIOOBE, negative start.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb.substring(0, -1);
+			fail("No SIOOBE, negative end.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb.substring(0, fixture.length() + 1);
+			fail("No SIOOBE, end > length.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+
+		try {
+			sb.substring(3, 2);
+			fail("No SIOOBE, start > end.");
+		} catch (StringIndexOutOfBoundsException e) {
+			// Expected
+		}
+	}
 
     /**
      * @tests java.lang.StringBuilder.toString()'
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
-    public void test_toString() {
+    public void test_toString() throws Exception {
         final String fixture = "0123456789";
         StringBuilder sb = new StringBuilder(fixture);
         assertEquals(fixture, sb.toString());
+
+        sb.setLength(0);
+        sb.append("abcde");
+        assertEquals("abcde", sb.toString());
+        sb.setLength(1000);
+        byte[] bytes = sb.toString().getBytes("GB18030");
+        for (int i = 5; i < bytes.length; i++) {
+            assertEquals(0, bytes[i]);
+        }
+
+        sb.setLength(5);
+        sb.append("fghij");
+        assertEquals("abcdefghij", sb.toString());
     }
 
-    /**
-     * @tests java.lang.StringBuilder.trimToSize()'
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "trimToSize",
-        args = {}
-    )
-    public void test_trimToSize() {
-        final String fixture = "0123456789";
-        StringBuilder sb = new StringBuilder(fixture);
-        assertTrue(sb.capacity() > fixture.length());
-        assertEquals(fixture.length(), sb.length());
-        assertEquals(fixture, sb.toString());
-        int prevCapacity = sb.capacity();
-        sb.trimToSize();
-        assertTrue(prevCapacity > sb.capacity());
-        assertEquals(fixture.length(), sb.length());
-        assertEquals(fixture, sb.toString());
-    }
+	/**
+	 * @tests java.lang.StringBuilder.trimToSize()'
+	 */
+	public void test_trimToSize() {
+		final String fixture = "0123456789";
+		StringBuilder sb = new StringBuilder(fixture);
+		assertTrue(sb.capacity() > fixture.length());
+		assertEquals(fixture.length(), sb.length());
+		assertEquals(fixture, sb.toString());
+		int prevCapacity = sb.capacity();
+		sb.trimToSize();
+		assertTrue(prevCapacity > sb.capacity());
+		assertEquals(fixture.length(), sb.length());
+		assertEquals(fixture, sb.toString());
+	}
 
     // comparator for StringBuilder objects
     private static final SerializableAssert STRING_BILDER_COMPARATOR = new SerializableAssert() {
@@ -2149,12 +1954,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization.",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new StringBuilder("0123456789"),
@@ -2164,28 +1963,22 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new StringBuilder("0123456789"),
                 STRING_BILDER_COMPARATOR);
     }
 
-    private static final class Fixture {
-        static final Fixture INSTANCE = new Fixture();
+	private static final class Fixture {
+		static final Fixture INSTANCE = new Fixture();
 
-        private Fixture() {
-            super();
-        }
+		private Fixture() {
+			super();
+		}
 
-        @Override
+		@Override
         public String toString() {
-            return "fixture";
-        }
-    }
+			return "fixture";
+		}
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java
index 2adf610..8ffeb3a 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringIndexOutOfBoundsExceptionTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(StringIndexOutOfBoundsException.class) 
 public class StringIndexOutOfBoundsExceptionTest extends TestCase {
 
     /**
      * @tests java.lang.StringIndexOutOfBoundsException#StringIndexOutOfBoundsException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringIndexOutOfBoundsException",
-        args = {}
-    )
     public void test_Constructor() {
         StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException();
         assertNull(e.getMessage());
@@ -46,26 +34,9 @@
     /**
      * @tests java.lang.StringIndexOutOfBoundsException#StringIndexOutOfBoundsException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringIndexOutOfBoundsException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "StringIndexOutOfBoundsException",
-        args = {int.class}
-    )
-    public void test_ConstructorLint() {
-        StringIndexOutOfBoundsException e = new StringIndexOutOfBoundsException(0);
-        assertTrue(e.getMessage().contains("0"));
-    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java
index 4ad0c52..efbb198 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/StringTest.java
@@ -17,31 +17,40 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Constructor;
+import java.nio.charset.Charset;
+import java.util.SortedMap;
 
 import junit.framework.TestCase;
 
-import java.io.UnsupportedEncodingException;
-import java.math.BigDecimal;
-
-@TestTargetClass(String.class) 
 public class StringTest extends TestCase {
 
-    private static String newString(int start, int len, char[] data) {
-        return new String(data, start,len);
+    private static final Constructor<String> UNSAFE_CONSTRUCTOR;
+    static {
+        Constructor<String> uc;
+        try {
+            uc = String.class.getDeclaredConstructor(new Class[] { int.class,
+                    int.class, char[].class });
+            uc.setAccessible(true);
+        } catch (Exception e) {
+            uc = null;
+        }
+        UNSAFE_CONSTRUCTOR = uc;
+    }
+
+    private static String newString(int start, int len, char[] data) throws Exception {
+        if (UNSAFE_CONSTRUCTOR == null) {
+            return new String(data, start, len);
+        }
+
+        return UNSAFE_CONSTRUCTOR.newInstance(Integer.valueOf(start), Integer.valueOf(len),
+                    data);
     }
     
     /**
      * @tests java.lang.String#String()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {}
-    )
     public void test_Constructor() {
         assertEquals("Created incorrect string", "", new String());
     }
@@ -49,12 +58,6 @@
     /**
      * @tests java.lang.String#String(byte[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {byte[].class}
-    )
     public void test_Constructor$B() {
         assertEquals("Failed to create string", "HelloWorld", new String(
                 "HelloWorld".getBytes()));
@@ -63,12 +66,6 @@
     /**
      * @tests java.lang.String#String(byte[], int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {byte[].class, int.class}
-    )
     @SuppressWarnings("deprecation")
     public void test_Constructor$BI() {
         String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0);
@@ -80,12 +77,6 @@
     /**
      * @tests java.lang.String#String(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_Constructor$BII() {
         byte[] hwba = "HelloWorld".getBytes();
         assertEquals("Failed to create string", "HelloWorld", new String(hwba,
@@ -101,12 +92,6 @@
     /**
      * @tests java.lang.String#String(byte[], int, int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "IndexOutOfBoundsException is not verified.",
-        method = "String",
-        args = {byte[].class, int.class, int.class, int.class}
-    )
     @SuppressWarnings("deprecation")
     public void test_Constructor$BIII() {
         String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 1, 3);
@@ -118,33 +103,21 @@
     /**
      * @tests java.lang.String#String(byte[], int, int, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {byte[].class, int.class, int.class, java.lang.String.class}
-    )
     public void test_Constructor$BIILjava_lang_String() throws Exception {
         String s = new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "8859_1");
         assertEquals("Incorrect string returned: " + s, "ABCDE", s);
         
         try {
-            new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "");
-            fail("Should throw UnsupportedEncodingException");
+        	new String(new byte[] { 65, 66, 67, 68, 69 }, 0, 5, "");
+        	fail("Should throw UnsupportedEncodingException");
         } catch (UnsupportedEncodingException e) {
-            //expected
+        	//expected
         }
     }
 
     /**
      * @tests java.lang.String#String(byte[], java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "UnsupportedEncodingException is not verified.",
-        method = "String",
-        args = {byte[].class, java.lang.String.class}
-    )
     public void test_Constructor$BLjava_lang_String() throws Exception {
         String s = new String(new byte[] { 65, 66, 67, 68, 69 }, "8859_1");
         assertEquals("Incorrect string returned: " + s, "ABCDE", s);
@@ -153,12 +126,6 @@
     /**
      * @tests java.lang.String#String(char[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {char[].class}
-    )
     public void test_Constructor$C() {
         assertEquals("Failed Constructor test", "World", new String(new char[] {
                 'W', 'o', 'r', 'l', 'd' }));
@@ -167,12 +134,6 @@
     /**
      * @tests java.lang.String#String(char[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {char[].class, int.class, int.class}
-    )
     public void test_Constructor$CII() throws Exception {
         char[] buf = { 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' };
         String s = new String(buf, 0, buf.length);
@@ -188,12 +149,6 @@
     /**
      * @tests java.lang.String#String(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         String s = new String("Hello World");
         assertEquals("Failed to construct correct string", "Hello World", s);
@@ -202,12 +157,6 @@
     /**
      * @tests java.lang.String#String(java.lang.StringBuffer)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {java.lang.StringBuffer.class}
-    )
     public void test_ConstructorLjava_lang_StringBuffer() {
         StringBuffer sb = new StringBuffer();
         sb.append("HelloWorld");
@@ -217,12 +166,6 @@
     /**
      * @tests java.lang.String#String(java.lang.StringBuilder)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {java.lang.StringBuilder.class}
-    )
     public void test_ConstructorLjava_lang_StringBuilder() {
         StringBuilder sb = new StringBuilder(32);
         sb.append("HelloWorld");
@@ -238,12 +181,6 @@
     /**
      * @tests java.lang.String#String(int[],int,int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "String",
-        args = {int[].class, int.class, int.class}
-    )
     public void test_Constructor$III() {
         assertEquals("HelloWorld", new String(new int[] { 'H', 'e', 'l', 'l',
                 'o', 'W', 'o', 'r', 'l', 'd' }, 0, 10));
@@ -292,13 +229,7 @@
     /**
      * @tests java.lang.String#contentEquals(CharSequence)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "contentEquals",
-        args = {java.lang.CharSequence.class}
-    )
-    public void test_contentEqualsLjava_lang_CharSequence() {
+    public void test_contentEqualsLjava_lang_CharSequence() throws Exception {
         String s = "abc";
         assertTrue(s.contentEquals((CharSequence) new StringBuffer("abc")));
         assertFalse(s.contentEquals((CharSequence) new StringBuffer("def")));
@@ -319,14 +250,8 @@
     /**
      * @tests java.lang.String#contentEquals(StringBuffer)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "contentEquals",
-        args = {java.lang.StringBuffer.class}
-    )
     @SuppressWarnings("nls")
-    public void test_boolean_contentEquals_StringBuffer() {
+    public void test_boolean_contentEquals_StringBuffer() throws Exception {
         String s = "abc";
         assertTrue(s.contentEquals(new StringBuffer("abc")));
         assertFalse(s.contentEquals(new StringBuffer("def")));
@@ -348,14 +273,8 @@
     /**
      * @tests java.lang.String#contains(CharSequence)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "contains",
-        args = {java.lang.CharSequence.class}
-    )
     @SuppressWarnings("cast")
-    public void test_containsLjava_lang_CharSequence() {
+    public void test_containsLjava_lang_CharSequence() throws Exception {
         String s = "abcdefghijklmnopqrstuvwxyz";
         assertTrue(s.contains((CharSequence) new StringBuffer("abc")));
         assertTrue(s.contains((CharSequence) new StringBuffer("def")));
@@ -376,13 +295,7 @@
     /**
      * @tests java.lang.String.offsetByCodePoints(int, int)'
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "offsetByCodePoints",
-        args = {int.class, int.class}
-    )
-    public void test_offsetByCodePointsII() {
+    public void test_offsetByCodePoints_II() throws Exception {
         int result = new String("a\uD800\uDC00b").offsetByCodePoints(0, 2);
         assertEquals(3, result);
 
@@ -505,13 +418,7 @@
     /**
      * @tests java.lang.StringBuilder.codePointAt(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointAt",
-        args = {int.class}
-    )
-    public void test_codePointAtI() {
+    public void test_codePointAtI() throws Exception {
         String s = "abc";
         assertEquals('a', s.codePointAt(0));
         assertEquals('b', s.codePointAt(1));
@@ -572,13 +479,7 @@
     /**
      * @tests java.lang.StringBuilder.codePointBefore(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointBefore",
-        args = {int.class}
-    )
-    public void test_codePointBeforeI() {
+    public void test_codePointBeforeI() throws Exception {
         String s = "abc";
         assertEquals('a', s.codePointBefore(1));
         assertEquals('b', s.codePointBefore(2));
@@ -639,13 +540,7 @@
     /**
      * @tests java.lang.StringBuilder.codePointCount(int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "codePointCount",
-        args = {int.class, int.class}
-    )
-    public void test_codePointCountII() {
+    public void test_codePointCountII() throws Exception {
         assertEquals(1, "\uD800\uDC00".codePointCount(0, 2));
         assertEquals(1, "\uD800\uDC01".codePointCount(0, 2));
         assertEquals(1, "\uD801\uDC01".codePointCount(0, 2));
@@ -700,40 +595,165 @@
         } catch (IndexOutOfBoundsException e) {
         }
     }
-
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-    )
-    public void testProblemCases() {
-        BigDecimal[] input = new BigDecimal[] {
-            new BigDecimal("20.00000"),
-            new BigDecimal("20.000000"),
-            new BigDecimal(".2"),
-            new BigDecimal("2"),
-            new BigDecimal("-2"),
-            new BigDecimal("200000000000000000000000"),
-            new BigDecimal("20000000000000000000000000000000000000000000000000")
-        };
-
-        String[] output = new String[] {
-                "20.00",
-                "20.00",
-                "0.20",
-                "2.00",
-                "-2.00",
-                "200000000000000000000000.00",
-                "20000000000000000000000000000000000000000000000000.00"
-        };
-        
-        for (int i = 0; i < input.length; i++) {
-            String result = String.format("%.2f", input[i]);
-            assertEquals("Format test for \"" + input[i] + "\" failed, " +
-                    "expected=" + output[i] + ", " +
-                    "actual=" + result, output[i], result);
+    
+    /**
+     * @tests {@link java.lang.String#String(byte[], int, int, Charset)} 
+     * 
+     * @since 1.6
+     */
+    public void test_ConstructorBIIL() throws Exception {
+        // can construct normally
+        new String(new byte[8], 0, 4, Charset.defaultCharset());
+        new String(new byte[8], 8, 0, Charset.defaultCharset());
+        new String(new byte[0], 0, 0, Charset.defaultCharset());
+        // throws exceptions
+        try {
+            new String(new byte[8], 0, 9, Charset.defaultCharset());
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            new String(new byte[8], 9, 0, Charset.defaultCharset());
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            new String(new byte[8], -1, 0, Charset.defaultCharset());
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            new String(new byte[8], 9, -1, Charset.defaultCharset());
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            new String(null, -1, 0, Charset.defaultCharset());
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            new String(null, 0, -1, Charset.defaultCharset());
+            fail("should throw StringIndexOutOfBoundsException");
+        } catch (StringIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            new String(null, 0, 9, Charset.defaultCharset());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(null, 0, 0, Charset.defaultCharset());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(null, -1, 0, (Charset)null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(new byte[8], -1, 0, (Charset)null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(new byte[8], 0, 9, (Charset)null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(new byte[8], 0, 4, (Charset)null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
         }
     }
     
+    /**
+     * @tests {@link java.lang.String#String(byte[], Charset)}
+     * 
+     *  @since 1.6
+     */
+    public void test_ConstructorBL() throws Exception {
+        new String(new byte[8], Charset.defaultCharset());
+        try {
+            new String(new byte[8],(Charset)null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(new byte[0],(Charset)null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            new String(null,Charset.defaultCharset());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        new String(new byte[0], Charset.defaultCharset());
+    }
+    
+    /**
+     * @tests {@link java.lang.String#isEmpty()}
+     * 
+     * @since 1.6
+     */
+    public void test_isEmpty() throws Exception {
+        assertTrue(new String(new byte[0], Charset.defaultCharset()).isEmpty());
+        assertTrue(new String(new byte[8], Charset.defaultCharset()).substring(0, 0).isEmpty());
+    }
+    
+    /**
+     * @tests {@link java.lang.String#getBytes(Charset)}
+     * 
+     * @since 1.6
+     */
+    public void test_getBytesLCharset() throws Exception {
+        byte[] emptyBytes = new byte[0];
+        byte[] someBytes = new byte[]{'T','h','i','s',' ',' ','i','s',' ','t','e','s','t',' ','b','y','t','e','s'};
+        assertEquals(0, new String(emptyBytes, Charset.defaultCharset()).getBytes(Charset.defaultCharset()).length);
+        try{
+            new String(emptyBytes, Charset.defaultCharset()).getBytes((Charset)null);
+            fail("should throw NPE");
+        } catch (NullPointerException e){
+            // correct
+        }
+        assertTrue(bytesEquals(someBytes,new String(someBytes, Charset.defaultCharset()).getBytes(Charset.defaultCharset())));
+        SortedMap<String, Charset> charsets = Charset.availableCharsets();
+
+        Charset ascii = charsets.get("US-ASCII");
+        Charset utf8 = charsets.get("UTF-8");
+        if (charsets.size() >= 2){
+            // assertTrue(bytesEquals(someBytes,new String(someBytes, charsets.get(charsets.firstKey())).getBytes(charsets.get(charsets.lastKey()))));  android-changed: invalid test
+            assertFalse(bytesEquals("\u4f60\u597d".getBytes(ascii), "\u4f60\u597d".getBytes(utf8)));
+        }
+    }
+    
+    boolean bytesEquals(byte[] bytes1, byte[] bytes2){
+        if (bytes1.length == bytes2.length){
+            for (int i = 0; i < bytes1.length; i++){
+                if (bytes1[i] != bytes2[i]){
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadDeathTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadDeathTest.java
index abb52c1..c40e0b0 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadDeathTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadDeathTest.java
@@ -17,26 +17,14 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-@TestTargetClass(ThreadDeath.class) 
 public class ThreadDeathTest extends junit.framework.TestCase {
 
-    /**
-     * @tests java.lang.ThreadDeath#ThreadDeath()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ThreadDeath",
-        args = {}
-    )
-    public void test_Constructor() {
-        ThreadDeath td = new ThreadDeath();
+	/**
+	 * @tests java.lang.ThreadDeath#ThreadDeath()
+	 */
+	public void test_Constructor() {
+		ThreadDeath td = new ThreadDeath();
         assertNull(td.getCause());
         assertNull(td.getMessage());
-    }
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TypeNotPresentExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TypeNotPresentExceptionTest.java
index 4b01a98..1f86648 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TypeNotPresentExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/TypeNotPresentExceptionTest.java
@@ -16,25 +16,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(TypeNotPresentException.class) 
 public class TypeNotPresentExceptionTest extends TestCase {
 
     /**
      * @tests java.lang.TypeNotPresentException.TypeNotPresentException(String, Throwable)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "TypeNotPresentException",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
     public void test_constructorLjava_lang_StringLjava_lang_Throwable() {
         TypeNotPresentException e = new TypeNotPresentException(null, null);
         assertNotNull(e);
@@ -55,12 +43,6 @@
     /**
      * @tests java.lang.TypeNotPresentException.typeName()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "typeName",
-        args = {}
-    )
     public void test_typeName() {
         TypeNotPresentException e = new TypeNotPresentException(null, null);
         assertNull(e.typeName());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnknownErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnknownErrorTest.java
index a894d7e..15f264b 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnknownErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnknownErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(UnknownError.class) 
 public class UnknownErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.UnknownError#UnknownError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnknownError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.UnknownError#UnknownError()
+	 */
     public void test_Constructor() {
         UnknownError e = new UnknownError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.UnknownError#UnknownError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnknownError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         UnknownError e = new UnknownError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsatisfiedLinkErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsatisfiedLinkErrorTest.java
index 39a8855..84229d8 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsatisfiedLinkErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsatisfiedLinkErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(UnsatisfiedLinkError.class) 
 public class UnsatisfiedLinkErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsatisfiedLinkError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError()
+	 */
     public void test_Constructor() {
         UnsatisfiedLinkError e = new UnsatisfiedLinkError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.UnsatisfiedLinkError#UnsatisfiedLinkError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsatisfiedLinkError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         UnsatisfiedLinkError e = new UnsatisfiedLinkError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedClassVersionErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedClassVersionErrorTest.java
index c1f3ee9..e9757f1 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedClassVersionErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedClassVersionErrorTest.java
@@ -1,55 +1,46 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import junit.framework.TestCase; // android-changed
 
-import junit.framework.TestCase;
+public class UnsupportedClassVersionErrorTest extends TestCase { // android-changed
+    /**
+     * Thrown when the Java Virtual Machine attempts to read a class file and
+     * determines that the major and minor version numbers in the file are not
+     * supported.
+     */
 
-@TestTargetClass(UnsupportedClassVersionError.class) 
-public class UnsupportedClassVersionErrorTest extends TestCase {
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsupportedClassVersionError",
-        args = {}
-    )
-    public void test_Constructor() {
-        UnsupportedClassVersionError ucve = new UnsupportedClassVersionError();
-        assertNull(ucve.getMessage());
-        assertNull(ucve.getCause());        
+    /**
+     * @tests java.lang.UnsupportedClassVersionError#UnsupportedClassVersionError()
+     */
+    public void test_UnsupportedClassVersionError() {
+        UnsupportedClassVersionError error = new UnsupportedClassVersionError();
+        assertNotNull(error);
+        assertNull(error.getMessage());
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsupportedClassVersionError",
-        args = {java.lang.String.class}
-    )
-    public void test_ConstructorLString() {
-        String message = "Test message";
-        UnsupportedClassVersionError ucve = new UnsupportedClassVersionError(
-                message);
-        assertEquals(message, ucve.getMessage());
-        ucve = new UnsupportedClassVersionError(null);
-        assertNull(ucve.getMessage());
+
+    /**
+     *@tests java.lang.UnsupportedClassVersionError#UnsupportedClassVersionError(java.lang.String)
+     */
+    public void test_UnsupportedClassVersionError_LString() {
+        UnsupportedClassVersionError e = new UnsupportedClassVersionError(
+                "Some Error Message");
+        assertEquals("Wrong message", "Some Error Message", e.getMessage());
     }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedOperationExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedOperationExceptionTest.java
index 73176bb..0458012 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedOperationExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/UnsupportedOperationExceptionTest.java
@@ -17,26 +17,15 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(UnsupportedOperationException.class) 
 public class UnsupportedOperationExceptionTest extends TestCase {
 
-    /**
-     * @tests java.lang.UnsupportedOperationException#UnsupportedOperationException()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsupportedOperationException",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.UnsupportedOperationException#UnsupportedOperationException()
+	 */
     public void test_Constructor() {
         UnsupportedOperationException e = new UnsupportedOperationException();
         assertNull(e.getMessage());
@@ -47,55 +36,54 @@
     /**
      * @tests java.lang.UnsupportedOperationException#UnsupportedOperationException(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsupportedOperationException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         UnsupportedOperationException e = new UnsupportedOperationException("fixture");
         assertEquals("fixture", e.getMessage());
         assertNull(e.getCause());
     }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsupportedOperationException",
-        args = {java.lang.String.class, java.lang.Throwable.class}
-    )
-    public void test_ConstructorLStringLThrowable() {
-        String message = "Test message";
-        NullPointerException npe = new NullPointerException();
-        UnsupportedOperationException uoe = new UnsupportedOperationException(message, npe);
-        assertEquals(message, uoe.getMessage());
-        assertEquals(npe, uoe.getCause());
+    /**
+     * @tests {@link java.land.UnsupportedOperationException#UnsupportedOperationException(java.lang.Throwable)}
+     */
+    public void test_ConstructorLjava_lang_Throwable() {
+        Throwable emptyThrowable = new Exception();
+        UnsupportedOperationException emptyException = new UnsupportedOperationException(
+                emptyThrowable);
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+        Throwable throwable = new Exception("msg");
+        UnsupportedOperationException exception = new UnsupportedOperationException(throwable);
+        assertEquals(throwable.getClass().getName() + ": " + "msg", exception.getMessage());
+        assertEquals(throwable.getClass().getName(), emptyException.getLocalizedMessage());
+        assertEquals(throwable.getClass().getName(), emptyException.getCause().toString());
+    }
+
+    /**
+     * @tests {@link java.land.UnsupportedOperationException#UnsupportedOperationException(java.lang.String, java.lang.Throwable)}
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_Throwable() {
+        Throwable emptyThrowable = new Exception();
+        UnsupportedOperationException emptyException = new UnsupportedOperationException(
+                "msg", emptyThrowable);
+        assertEquals("msg", emptyException.getMessage());
+        assertEquals("msg", emptyException.getLocalizedMessage());
+        assertEquals(emptyThrowable.getClass().getName(), emptyException.getCause().toString());
+
+        Throwable throwable = new Exception("msg_exception");
+        UnsupportedOperationException exception = new UnsupportedOperationException(
+                "msg", throwable);
+        assertEquals("msg", exception.getMessage());
+        assertEquals("msg", exception.getLocalizedMessage());
+        assertEquals(throwable.getClass().getName() + ": " + throwable.getMessage(), exception
+                .getCause().toString());
     }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnsupportedOperationException",
-        args = {java.lang.Throwable.class}
-    )
-    public void test_ConstructorLThrowable(){
-        NullPointerException npe = new NullPointerException();
-        UnsupportedOperationException uoe = new UnsupportedOperationException(npe);
-        assertEquals(npe, uoe.getCause());
-        uoe = new UnsupportedOperationException((Throwable) null);
-        assertNull("The cause is not null.", uoe.getCause());
-    }
-    
+	
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationSelf",
-        args = {}
-    )    
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new UnsupportedOperationException());
@@ -104,12 +92,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization/deserialization compatibility.",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VerifyErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VerifyErrorTest.java
index 3115698..7bd2581 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VerifyErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VerifyErrorTest.java
@@ -17,25 +17,13 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
-@TestTargetClass(VerifyError.class) 
 public class VerifyErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.VerifyError#VerifyError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "VerifyError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.VerifyError#VerifyError()
+	 */
     public void test_Constructor() {
         VerifyError e = new VerifyError();
         assertNull(e.getMessage());
@@ -46,12 +34,6 @@
     /**
      * @tests java.lang.VerifyError#VerifyError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "VerifyError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         VerifyError e = new VerifyError("fixture");
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VirtualMachineErrorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VirtualMachineErrorTest.java
index b998b98..c8ce58c 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VirtualMachineErrorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/VirtualMachineErrorTest.java
@@ -17,26 +17,14 @@
 
 package org.apache.harmony.luni.tests.java.lang;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 @SuppressWarnings("serial")
-@TestTargetClass(VirtualMachineError.class) 
 public class VirtualMachineErrorTest extends TestCase {
 
-    /**
-     * @tests java.lang.VirtualMachineError#VirtualMachineError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "VirtualMachineError",
-        args = {}
-    )
+	/**
+	 * @tests java.lang.VirtualMachineError#VirtualMachineError()
+	 */
     public void test_Constructor() {
         VirtualMachineError e = new VirtualMachineError() {};
         assertNull(e.getMessage());
@@ -47,12 +35,6 @@
     /**
      * @tests java.lang.VirtualMachineError#VirtualMachineError(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "VirtualMachineError",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         VirtualMachineError e = new VirtualMachineError("fixture") {};
         assertEquals("fixture", e.getMessage());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/AllTests.java
index 91ca3a4..ef60ac3 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/AllTests.java
@@ -30,7 +30,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.net");
+        TestSuite suite = new TestSuite("Tests for java.net");
 
         // add net testsuites here
         suite.addTestSuite(ContentHandlerTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerTest.java
index 6b1957a..07a374b 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.luni.tests.java.net;
 
-import dalvik.annotation.TestTargetClass; 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.IOException;
 import java.net.ContentHandler;
 import java.net.URL;
@@ -29,19 +24,12 @@
 
 import junit.framework.TestCase;
 
-@TestTargetClass(ContentHandler.class) 
 public class ContentHandlerTest extends TestCase {
 
     /**
      * @tests java.net.ContentHandler#getContent(java.net.URLConnection,
      *        java.lang.Class[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getContent",
-        args = {java.net.URLConnection.class, java.lang.Class[].class}
-    )
     public void test_getContent() throws IOException {
         URLConnection conn = new URL("http://www.apache.org").openConnection();
         Class[] classes = { Foo.class, String.class, };
@@ -49,7 +37,7 @@
         ((ContentHandlerImpl) handler).setContent(new Foo());
         Object content = handler.getContent(conn, classes);
         assertEquals("Foo", ((Foo) content).getFoo());
-        
+
         ((ContentHandlerImpl) handler).setContent(new FooSub());
         content = handler.getContent(conn, classes);
         assertEquals("FooSub", ((Foo) content).getFoo());
@@ -58,33 +46,6 @@
         ((ContentHandlerImpl) handler).setContent(new Foo());
         content = handler.getContent(conn, classes2);
         assertNull(content);
-      
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getContent",
-        args = {java.net.URLConnection.class}
-    )
-    public void test_getContentLURLConnection() throws IOException {
-        URLConnection conn = new URL("http://www.apache.org").openConnection();
-        Class[] classes = { Foo.class, String.class, };
-        ContentHandler handler = new ContentHandlerImpl();
-        ((ContentHandlerImpl) handler).setContent(new Foo());
-        Object content = handler.getContent(conn);
-        assertEquals("Foo", ((Foo) content).getFoo());
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ContentHandler",
-        args = {}
-    )
-    public void test_Constructor() {
-        ContentHandlerImpl ch = new ContentHandlerImpl();
-        ch.setContent(new Object());
     }
 }
 
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpRetryExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpRetryExceptionTest.java
index 3e3cafe..bc14d6f 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpRetryExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/HttpRetryExceptionTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.luni.tests.java.net;
 
-import dalvik.annotation.TestTargetClass; 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.Serializable;
 import java.net.HttpRetryException;
 
@@ -30,7 +25,6 @@
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(HttpRetryException.class) 
 public class HttpRetryExceptionTest extends TestCase {
 
     private static final String LOCATION = "Http test"; //$NON-NLS-1$
@@ -54,12 +48,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Checks serialization",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
         SerializationTest.verifySelf(new HttpRetryException(DETAIL, 100,
                 LOCATION), comparator);
@@ -68,12 +56,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Checks serialization",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
         SerializationTest.verifyGolden(this, new HttpRetryException(DETAIL,
                 100, LOCATION), comparator);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URITest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URITest.java
index e290e27..e7be391 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URITest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URITest.java
@@ -1,177 +1,1859 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.net;
 
-import dalvik.annotation.TestTargetClass; 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
+import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 
 import junit.framework.TestCase;
 
-@TestTargetClass(URI.class) 
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
 public class URITest extends TestCase {
+
+    private URI[] uris;
+
+    private URI[] getUris() throws URISyntaxException {
+        if (uris != null) {
+            return uris;
+        }
+
+        uris = new URI[] {
+                // single arg constructor
+                new URI(
+                        "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag"),
+                // escaped octets for illegal chars
+                new URI(
+                        "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g"),
+                // escaped octets for unicode chars
+                new URI(
+                        "ascheme://user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g"),
+                // unicode chars equivalent to = new
+                // URI("ascheme://user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery#fr\u00e4\u00e8g"),
+
+                // multiple arg constructors
+                new URI("http", "user%60%20info", "host", 80, "/a%20path", //$NON-NLS-4$
+                        "qu%60%20ery", "fr%5E%20ag"),
+                // escaped octets for illegal
+                new URI("http", "user%C3%9F%C2%A3info", "host", -1,
+                        "/a%E2%82%ACpath", "qu%C2%A9%C2%AEery",
+                        "fr%C3%A4%C3%A8g"),
+                // escaped octets for unicode
+                new URI("ascheme", "user\u00DF\u00A3info", "host", 80,
+                        "/a\u20ACpath", "qu\u00A9\u00AEery", "fr\u00E4\u00E8g"),
+                // unicode chars equivalent to = new
+                // URI("ascheme", "user\u00df\u00a3info", "host", 80,
+                // "/a\u0080path", "qu\u00a9\u00aeery", "fr\u00e4\u00e8g"),
+                new URI("http", "user` info", "host", 81, "/a path", "qu` ery",
+                        "fr^ ag"), // illegal chars
+                new URI("http", "user%info", "host", 0, "/a%path", "que%ry",
+                        "f%rag"),
+                // % as illegal char, not escaped octet
+
+                // urls with undefined components
+                new URI("mailto", "user@domain.com", null),
+                // no host, path, query or fragment
+                new URI("../adirectory/file.html#"),
+                // relative path with empty fragment;
+                new URI("news", "comp.infosystems.www.servers.unix", null), //
+                new URI(null, null, null, "fragment"), // only fragment
+                new URI("telnet://server.org"), // only host
+                new URI("http://reg:istry?query"),
+                // malformed hostname, therefore registry-based,
+                // with query
+                new URI("file:///c:/temp/calculate.pl?"),
+        // empty authority, non empty path, empty query
+        };
+        return uris;
+    }
+
     /**
-     * @tests java.net.URI(java.lang.String)
+     * @tests java.net.URI#URI(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "NullPointerException checking missed.",
-        method = "URI",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() throws URISyntaxException {
+        // tests for public URI(String uri) throws URISyntaxException
+
+        String[] constructorTests = new String[] {
+                "http://user@www.google.com:45/search?q=helpinfo#somefragment",
+                // http with authority, query and fragment
+                "ftp://ftp.is.co.za/rfc/rfc1808.txt", // ftp
+                "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles", // gopher
+                "mailto:mduerst@ifi.unizh.ch", // mailto
+                "news:comp.infosystems.www.servers.unix", // news
+                "telnet://melvyl.ucop.edu/", // telnet
+                "http://123.24.17.98/test", // IPv4 authority
+                "http://www.google.com:80/test",// domain name authority
+                "http://joe@[3ffe:2a00:100:7031::1]:80/test",
+                // IPv6 authority, with userinfo and port
+                "/relative", // relative starting with /
+                "//relative", // relative starting with //
+                "relative", // relative with no /
+                "#fragment",// relative just with fragment
+                "http://user@host:80", // UI, host,port
+                "http://user@host", // ui, host
+                "http://host", // host
+                "http://host:80", // host,port
+                "http://joe@:80", // ui, port (becomes registry-based)
+                "file:///foo/bar", // empty authority, non empty path
+                "ht?tp://hoe@host:80", // miscellaneous tests
+                "mai/lto:hey?joe#man", "http://host/a%20path#frag",
+                // path with an escaped octet for space char
+                "http://host/a%E2%82%ACpath#frag",
+                // path with escaped octet for unicode char, not USASCII
+                "http://host/a\u20ACpath#frag",
+                // path with unicode char, not USASCII equivalent to
+                // = "http://host/a\u0080path#frag",
+                "http://host%20name/", // escaped octets in host (becomes
+                // registry based)
+                "http://host\u00DFname/", // unicodechar in host (becomes
+                // registry based)
+                // equivalent to = "http://host\u00dfname/",
+                "ht123-+tp://www.google.com:80/test", // legal chars in scheme
+        };
+
+        for (int i = 0; i < constructorTests.length; i++) {
+            try {
+                new URI(constructorTests[i]);
+            } catch (URISyntaxException e) {
+                fail("Failed to construct URI for: " + constructorTests[i]
+                        + " : " + e);
+            }
+        }
+
+        String[] constructorTestsInvalid = new String[] {
+                "http:///a path#frag", // space char in path, not in escaped
+                // octet form, with no host
+                "http://host/a[path#frag", // an illegal char, not in escaped
+                // octet form, should throw an
+                // exception
+                "http://host/a%path#frag", // invalid escape sequence in path
+                "http://host/a%#frag", // incomplete escape sequence in path
+
+                "http://host#a frag", // space char in fragment, not in
+                // escaped octet form, no path
+                "http://host/a#fr#ag", // illegal char in fragment
+                "http:///path#fr%ag", // invalid escape sequence in fragment,
+                // with no host
+                "http://host/path#frag%", // incomplete escape sequence in
+                // fragment
+
+                "http://host/path?a query#frag", // space char in query, not
+                // in escaped octet form
+                "http://host?query%ag", // invalid escape sequence in query, no
+                // path
+                "http:///path?query%", // incomplete escape sequence in query,
+                // with no host
+
+                "mailto:user^name@fklkf.com" // invalid char in scheme
+        // specific part
+        };
+
+        int[] constructorTestsInvalidIndices = new int[] { 9, 13, 13, 13, 13,
+                16, 15, 21, 18, 17, 18, 11 };
+
+        for (int i = 0; i < constructorTestsInvalid.length; i++) {
+            try {
+                new URI(constructorTestsInvalid[i]);
+                fail("Failed to throw URISyntaxException for: "
+                        + constructorTestsInvalid[i]);
+            } catch (URISyntaxException e) {
+                assertTrue("Wrong index in URISytaxException for: "
+                        + constructorTestsInvalid[i] + " expected: "
+                        + constructorTestsInvalidIndices[i] + ", received: "
+                        + e.getIndex(),
+                        e.getIndex() == constructorTestsInvalidIndices[i]);
+            }
+        }
+
+        String invalid2[] = {
+                // authority validation
+                "http://user@[3ffe:2x00:100:7031::1]:80/test", // malformed
+                // IPv6 authority
+                "http://[ipv6address]/apath#frag", // malformed ipv6 address
+                "http://[ipv6address/apath#frag", // malformed ipv6 address
+                "http://ipv6address]/apath#frag", // illegal char in host name
+                "http://ipv6[address/apath#frag",
+                "http://ipv6addr]ess/apath#frag",
+                "http://ipv6address[]/apath#frag",
+                // illegal char in username...
+                "http://us[]er@host/path?query#frag", "http://host name/path", // illegal
+                // char
+                // in
+                // authority
+                "http://host^name#fragment", // illegal char in authority
+                "telnet://us er@hostname/", // illegal char in authority
+                // missing components
+                "//", // Authority expected
+                "ascheme://", // Authority expected
+                "ascheme:", // Scheme-specific part expected
+                // scheme validation
+                "a scheme://reg/", // illegal char
+                "1scheme://reg/", // non alpha char as 1st char
+                "asche\u00dfme:ssp", // unicode char , not USASCII
+                "asc%20heme:ssp" // escape octets
+        };
+
+        for (int i = 0; i < invalid2.length; i++) {
+            try {
+                new URI(invalid2[i]);
+                fail("Failed to throw URISyntaxException for: " + invalid2[i]);
+            } catch (URISyntaxException e) {
+            }
+        }
+
         // Regression test for HARMONY-23
         try {
             new URI("%3");
             fail("Assert 0: URI constructor failed to throw exception on invalid input.");
         } catch (URISyntaxException e) {
             // Expected
-            assertEquals("Assert 1: Wrong index in URISyntaxException.", 0, e.getIndex());
+            assertEquals("Assert 1: Wrong index in URISyntaxException.", 0, e
+                    .getIndex());
         }
-        
+
         // Regression test for HARMONY-25
-        // if port value is negative, the authority should be considered registry-based.
+        // if port value is negative, the authority should be considered
+        // registry-based.
         URI uri = new URI("http://host:-8096/path/index.html");
         assertEquals("Assert 2: returned wrong port value,", -1, uri.getPort());
         assertNull("Assert 3: returned wrong host value,", uri.getHost());
         try {
             uri.parseServerAuthority();
             fail("Assert 4: Expected URISyntaxException");
-        } catch (URISyntaxException e){
+        } catch (URISyntaxException e) {
             // Expected
         }
-        
-        uri = new URI("http","//myhost:-8096", null);
+
+        uri = new URI("http", "//myhost:-8096", null);
         assertEquals("Assert 5: returned wrong port value,", -1, uri.getPort());
         assertNull("Assert 6: returned wrong host value,", uri.getHost());
         try {
             uri.parseServerAuthority();
             fail("Assert 7: Expected URISyntaxException");
-        } catch (URISyntaxException e){
+        } catch (URISyntaxException e) {
             // Expected
         }
     }
-    
+
     /**
-     * @tests java.net.URI(java.lang.String, java.lang.String, java.lang.String)
+     * @tests java.net.URI#URI(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exceptions checked only.",
-        method = "URI",
-        args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
-    )
-    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String() {
-        // scheme can not be empty string    
+    public void test_URI_String() {
         try {
-            new URI("","//authority/path", "fragment");
-            fail ("Assert 0: Expected URISyntaxException with empty URI scheme");    
-        } catch(URISyntaxException e) {
-            // Expected
-            assertEquals("Assert 1: Wrong index in URISyntaxException.", 0, e.getIndex());
+            URI myUri = new URI(":abc@mymail.com");
+            fail("TestA, URISyntaxException expected, but not received.");
+        } catch (URISyntaxException e) {
+            assertEquals("TestA, Wrong URISyntaxException index, ", 0, e
+                    .getIndex());
+        }
+
+        try {
+            URI uri = new URI("path[one");
+            fail("TestB, URISyntaxException expected, but not received.");
+        } catch (URISyntaxException e1) {
+            assertEquals("TestB, Wrong URISyntaxException index, ", 4, e1
+                    .getIndex());
+        }
+
+        try {
+            URI uri = new URI(" ");
+            fail("TestC, URISyntaxException expected, but not received.");
+        } catch (URISyntaxException e2) {
+            assertEquals("TestC, Wrong URISyntaxException index, ", 0, e2
+                    .getIndex());
         }
     }
-    
+
+    /**
+     * @tests java.net.URI#URI(java.lang.String, java.lang.String,
+     *        java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String()
+            throws URISyntaxException {
+        URI uri = new URI("mailto", "mduerst@ifi.unizh.ch", null);
+        assertNull("wrong userinfo", uri.getUserInfo());
+        assertNull("wrong hostname", uri.getHost());
+        assertNull("wrong authority", uri.getAuthority());
+        assertEquals("wrong port number", -1, uri.getPort());
+        assertNull("wrong path", uri.getPath());
+        assertNull("wrong query", uri.getQuery());
+        assertNull("wrong fragment", uri.getFragment());
+        assertEquals("wrong SchemeSpecificPart", "mduerst@ifi.unizh.ch", uri
+                .getSchemeSpecificPart());
+
+        // scheme specific part can not be null
+        try {
+            uri = new URI("mailto", null, null);
+            fail("Expected URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        // scheme needs to start with an alpha char
+        try {
+            uri = new URI("3scheme", "//authority/path", "fragment");
+            fail("Expected URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        // scheme can not be empty string
+        try {
+            uri = new URI("", "//authority/path", "fragment");
+            fail("Expected URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.net.URI#URI(java.lang.String, java.lang.String,
+     *        java.lang.String, int, java.lang.String, java.lang.String,
+     *        java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_StringILjava_lang_StringLjava_lang_StringLjava_lang_String() {
+        // check for URISyntaxException for invalid Server Authority
+        construct1("http", "user", "host\u00DFname", -1, "/file", "query",
+                "fragment"); // unicode chars in host name
+        // equivalent to construct1("http", "user", "host\u00dfname", -1,
+        // "/file", "query", "fragment");
+        construct1("http", "user", "host%20name", -1, "/file", "query",
+                "fragment"); // escaped octets in host name
+        construct1("http", "user", "host name", -1, "/file", "query",
+                "fragment"); // illegal char in host name
+        construct1("http", "user", "host]name", -1, "/file", "query",
+                "fragment"); // illegal char in host name
+
+        // missing host name
+        construct1("http", "user", "", 80, "/file", "query", "fragment");
+
+        // missing host name
+        construct1("http", "user", "", -1, "/file", "query", "fragment");
+
+        // malformed ipv4 address
+        construct1("telnet", null, "256.197.221.200", -1, null, null, null);
+
+        // malformed ipv4 address
+        construct1("ftp", null, "198.256.221.200", -1, null, null, null);
+
+        // These tests fail on other implementations...
+        // construct1("http", "user", null, 80, "/file", "query", "fragment");
+        // //missing host name
+        // construct1("http", "user", null, -1, "/file", "query", "fragment");
+        // //missing host name
+
+        // check for URISyntaxException for invalid scheme
+        construct1("ht\u00DFtp", "user", "hostname", -1, "/file", "query",
+                "fragment"); // unicode chars in scheme
+        // equivalent to construct1("ht\u00dftp", "user", "hostname", -1,
+        // "/file",
+        // "query", "fragment");
+
+        construct1("ht%20tp", "user", "hostname", -1, "/file", "query",
+                "fragment"); // escaped octets in scheme
+        construct1("ht tp", "user", "hostname", -1, "/file", "query",
+                "fragment"); // illegal char in scheme
+        construct1("ht]tp", "user", "hostname", -1, "/file", "query",
+                "fragment"); // illegal char in scheme
+
+        // relative path with scheme
+        construct1("http", "user", "hostname", -1, "relative", "query",
+                "fragment"); // unicode chars in scheme
+
+        // functional test
+        URI uri;
+        try {
+            uri = new URI("http", "us:e@r", "hostname", 85, "/file/dir#/qu?e/",
+                    "qu?er#y", "frag#me?nt");
+            assertEquals("wrong userinfo", "us:e@r", uri.getUserInfo());
+            assertEquals("wrong hostname", "hostname", uri.getHost());
+            assertEquals("wrong port number", 85, uri.getPort());
+            assertEquals("wrong path", "/file/dir#/qu?e/", uri.getPath());
+            assertEquals("wrong query", "qu?er#y", uri.getQuery());
+            assertEquals("wrong fragment", "frag#me?nt", uri.getFragment());
+            assertEquals("wrong SchemeSpecificPart",
+                    "//us:e@r@hostname:85/file/dir#/qu?e/?qu?er#y", uri
+                            .getSchemeSpecificPart());
+        } catch (URISyntaxException e) {
+            fail("Unexpected Exception: " + e);
+        }
+    }
+
+    /*
+     * helper method checking if the 7 arg constructor throws URISyntaxException
+     * for a given set of parameters
+     */
+    private void construct1(String scheme, String userinfo, String host,
+            int port, String path, String query, String fragment) {
+        try {
+            URI uri = new URI(scheme, userinfo, host, port, path, query,
+                    fragment);
+            fail("Expected URISyntaxException not thrown for URI: "
+                    + uri.toString());
+        } catch (URISyntaxException e) {
+            // this constructor throws URISyntaxException for malformed server
+            // based authorities
+        }
+    }
+
+    /**
+     * @throws URISyntaxException
+     * @tests java.net.URI#URI(java.lang.String, java.lang.String,
+     *        java.lang.String, java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_StringLjava_lang_String()
+            throws URISyntaxException {
+        // relative path
+        try {
+            URI myUri = new URI("http", "www.joe.com", "relative", "jimmy");
+            fail("URISyntaxException expected but not received.");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        // valid parameters for this constructor
+        URI uri;
+
+        uri = new URI("http", "www.joe.com", "/path", "jimmy");
+
+        // illegal char in path
+        uri = new URI("http", "www.host.com", "/path?q", "somefragment");
+
+        // empty fragment
+        uri = new URI("ftp", "ftp.is.co.za", "/rfc/rfc1808.txt", "");
+
+        // path with escaped octet for unicode char, not USASCII
+        uri = new URI("http", "host", "/a%E2%82%ACpath", "frag");
+
+        // frag with unicode char, not USASCII
+        // equivalent to = uri = new URI("http", "host", "/apath",
+        // "\u0080frag");
+        uri = new URI("http", "host", "/apath", "\u20ACfrag");
+
+        // Regression test for Harmony-1693
+        new URI(null, null, null, null);
+
+        // regression for Harmony-1346
+        try {
+            uri = new URI("http", ":2:3:4:5:6:7:8", "/apath", "\u20ACfrag");
+            fail("Should throw URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @throws URISyntaxException
+     * @tests java.net.URI#URI(java.lang.String, java.lang.String,
+     *        java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_StringLjava_lang_StringLjava_lang_String()
+            throws URISyntaxException {
+        // URISyntaxException on relative path
+        try {
+            URI myUri = new URI("http", "www.joe.com", "relative", "query",
+                    "jimmy");
+            fail("URISyntaxException expected but not received.");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        // test if empty authority is parsed into undefined host, userinfo and
+        // port and if unicode chars and escaped octets in components are
+        // preserved, illegal chars are quoted
+        URI uri = new URI("ht12-3+tp", "", "/p#a%E2%82%ACth", "q^u%25ery",
+                "f/r\u00DFag");
+
+        assertEquals("wrong scheme", "ht12-3+tp", uri.getScheme());
+        assertNull("wrong authority", uri.getUserInfo());
+        assertNull("wrong userinfo", uri.getUserInfo());
+        assertNull("wrong hostname", uri.getHost());
+        assertEquals("wrong port number", -1, uri.getPort());
+        assertEquals("wrong path", "/p#a%E2%82%ACth", uri.getPath());
+        assertEquals("wrong query", "q^u%25ery", uri.getQuery());
+        assertEquals("wrong fragment", "f/r\u00DFag", uri.getFragment());
+        // equivalent to = assertTrue("wrong fragment",
+        // uri.getFragment().equals("f/r\u00dfag"));
+        assertEquals("wrong SchemeSpecificPart", "///p#a%E2%82%ACth?q^u%25ery",
+                uri.getSchemeSpecificPart());
+        assertEquals("wrong RawSchemeSpecificPart",
+                "///p%23a%25E2%2582%25ACth?q%5Eu%2525ery", uri
+                        .getRawSchemeSpecificPart());
+        assertEquals(
+                "incorrect toString()",
+                "ht12-3+tp:///p%23a%25E2%2582%25ACth?q%5Eu%2525ery#f/r\u00dfag",
+                uri.toString());
+        assertEquals("incorrect toASCIIString()",
+
+        "ht12-3+tp:///p%23a%25E2%2582%25ACth?q%5Eu%2525ery#f/r%C3%9Fag", uri
+                .toASCIIString());
+    }
+
+    /**
+     * @throws URISyntaxException
+     * @tests java.net.URI#URI(java.lang.String, java.lang.String,
+     *        java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void test_fiveArgConstructor() throws URISyntaxException {
+        // accept [] as part of valid ipv6 host name
+        URI uri = new URI("ftp", "[0001:1234::0001]", "/dir1/dir2", "query",
+                "frag");
+        assertEquals("Returned incorrect host", "[0001:1234::0001]", uri
+                .getHost());
+
+        // do not accept [] as part of invalid ipv6 address
+        try {
+            uri = new URI("ftp", "[www.abc.com]", "/dir1/dir2", "query", "frag");
+            fail("Expected URISyntaxException for invalid ipv6 address");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        // do not accept [] as part of user info
+        try {
+            uri = new URI("ftp", "[user]@host", "/dir1/dir2", "query", "frag");
+            fail("Expected URISyntaxException invalid user info");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.net.URI#compareTo(java.lang.Object)
+     */
+    public void test_compareToLjava_lang_Object() throws Exception {
+        // compareTo tests
+
+        String[][] compareToData = new String[][] {
+                // scheme tests
+                { "http:test", "" }, // scheme null, scheme not null
+                { "", "http:test" }, // reverse
+                { "http:test", "ftp:test" }, // schemes different
+                { "/test", "/test" }, // schemes null
+                { "http://joe", "http://joe" }, // schemes same
+                { "http://joe", "hTTp://joe" }, // schemes same ignoring case
+
+                // opacity : one opaque, the other not
+                { "http:opaque", "http://nonopaque" },
+                { "http://nonopaque", "http:opaque" },
+                { "mailto:abc", "mailto:abc" }, // same ssp
+                { "mailto:abC", "mailto:Abc" }, // different, by case
+                { "mailto:abc", "mailto:def" }, // different by letter
+                { "mailto:abc#ABC", "mailto:abc#DEF" },
+                { "mailto:abc#ABC", "mailto:abc#ABC" },
+                { "mailto:abc#DEF", "mailto:abc#ABC" },
+
+                // hierarchical tests..
+
+                // different authorities
+                { "//www.test.com/test", "//www.test2.com/test" },
+
+                { "/nullauth", "//nonnullauth/test" }, // one null authority
+                { "//nonnull", "/null" },
+                { "/hello", "/hello" }, // both authorities null
+                // different userinfo
+                { "http://joe@test.com:80", "http://test.com" },
+                { "http://jim@test.com", "http://james@test.com" },
+                // different hostnames
+                { "http://test.com", "http://toast.com" },
+                { "http://test.com:80", "test.com:87" }, // different ports
+                { "http://test.com", "http://test.com:80" },
+                // different paths
+                { "http://test.com:91/dir1", "http://test.com:91/dir2" },
+                // one null host
+                { "http:/hostless", "http://hostfilled.com/hostless" },
+
+                // queries
+                { "http://test.com/dir?query", "http://test.com/dir?koory" },
+                { "/test?query", "/test" },
+                { "/test", "/test?query" },
+                { "/test", "/test" },
+
+                // fragments
+                { "ftp://test.com/path?query#frag", "ftp://test.com/path?query" },
+                { "ftp://test.com/path?query", "ftp://test.com/path?query#frag" },
+                { "#frag", "#frag" }, { "p", "" },
+
+                { "http://www.google.com", "#test" } // miscellaneous
+        };
+
+        int[] compareToResults = { 1, -1, 2, 0, 0, 0, 1, -1, 0, 32, -3, -3, 0,
+                3, -4, -1, 1, 0, 1, 8, -10, -12, -81, -1, -1, 6, 1, -1, 0, 1,
+                -1, 0, 1, 1, };
+
+        // test compareTo functionality
+        for (int i = 0; i < compareToResults.length; i++) {
+            URI b = new URI(compareToData[i][0]);
+            URI r = new URI(compareToData[i][1]);
+            if (b.compareTo(r) != compareToResults[i]) {
+                fail("Test " + i + ": " + compareToData[i][0] + " compared to "
+                        + compareToData[i][1] + " -> " + b.compareTo(r)
+                        + " rather than " + compareToResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @throws URISyntaxException
+     * @tests java.net.URI#compareTo(java.lang.Object)
+     */
+    public void test_compareTo2() throws URISyntaxException {
+        URI uri, uri2;
+
+        // test URIs with host names with different casing
+        uri = new URI("http://AbC.cOm/root/news");
+        uri2 = new URI("http://aBc.CoM/root/news");
+        assertEquals("TestA", 0, uri.compareTo(uri2));
+        assertEquals("TestB", 0, uri.compareTo(uri2));
+
+        // test URIs with one undefined component
+        uri = new URI("http://abc.com:80/root/news");
+        uri2 = new URI("http://abc.com/root/news");
+        assertTrue("TestC", uri.compareTo(uri2) > 0);
+        assertTrue("TestD", uri2.compareTo(uri) < 0);
+
+        // test URIs with one undefined component
+        uri = new URI("http://user@abc.com/root/news");
+        uri2 = new URI("http://abc.com/root/news");
+        assertTrue("TestE", uri.compareTo(uri2) > 0);
+        assertTrue("TestF", uri2.compareTo(uri) < 0);
+    }
+
+    /**
+     * @tests java.net.URI#create(java.lang.String)
+     */
+    public void test_createLjava_lang_String() {
+        try {
+            URI myUri = URI.create("a scheme://reg/");
+            fail("IllegalArgumentException expected but not received.");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.net.URI#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() throws Exception {
+        String[][] equalsData = new String[][] {
+                { "", "" }, // null frags
+                { "/path", "/path#frag" },
+                { "#frag", "#frag2" },
+                { "#frag", "#FRag" },
+
+                // case insensitive on hex escapes
+                { "#fr%4F", "#fr%4f" },
+
+                { "scheme:test", "scheme2:test" }, // scheme stuff
+                { "test", "http:test" },
+                { "http:test", "test" },
+                { "SCheme:test", "schEMe:test" },
+
+                // hierarchical/opaque mismatch
+                { "mailto:jim", "mailto://jim" },
+                { "mailto://test", "mailto:test" },
+
+                // opaque
+                { "mailto:name", "mailto:name" },
+                { "mailtO:john", "mailto:jim" },
+
+                // test hex case insensitivity on ssp
+                { "mailto:te%4Fst", "mailto:te%4fst" },
+
+                { "mailto:john#frag", "mailto:john#frag2" },
+
+                // hierarchical
+                { "/test", "/test" }, // paths
+                { "/te%F4st", "/te%f4st" },
+                { "/TEst", "/teSt" },
+                { "", "/test" },
+
+                // registry based because they don't resolve properly to
+                // server-based add more tests here
+                { "//host.com:80err", "//host.com:80e" },
+                { "//host.com:81e%Abrr", "//host.com:81e%abrr" },
+
+                { "/test", "//auth.com/test" },
+                { "//test.com", "/test" },
+
+                { "//test.com", "//test.com" }, // hosts
+
+                // case insensitivity for hosts
+                { "//HoSt.coM/", "//hOsT.cOm/" },
+                { "//te%ae.com", "//te%aE.com" },
+                { "//test.com:80", "//test.com:81" },
+                { "//joe@test.com:80", "//test.com:80" },
+                { "//jo%3E@test.com:82", "//jo%3E@test.com:82" },
+                { "//test@test.com:85", "//test@test.com" }, };
+
+        boolean[] equalsResults = new boolean[] { true, false, false, false,
+                true, false, false, false, true, false, false, true, false,
+                true, false, true, true, false, false, false, true, false,
+                false, true, true, true, false, false, true, false, };
+
+        // test equals functionality
+        for (int i = 0; i < equalsResults.length; i++) {
+            URI b = new URI(equalsData[i][0]);
+            URI r = new URI(equalsData[i][1]);
+            if (b.equals(r) != equalsResults[i]) {
+                fail("Error: " + equalsData[i][0] + " == " + equalsData[i][1]
+                        + "? -> " + b.equals(r) + " expected "
+                        + equalsResults[i]);
+            }
+        }
+
+    }
+
+    /**
+     * @throws URISyntaxException
+     * @tests java.net.URI#equals(java.lang.Object)
+     */
+    public void test_equals2() throws URISyntaxException {
+        // test URIs with empty string authority
+        URI uri = new URI("http:///~/dictionary");
+        URI uri2 = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(),
+                uri.getQuery(), uri.getFragment());
+        assertTrue(uri2.equals(uri));
+
+        // test URIs with port number
+        uri = new URI("http://abc.com%E2%82%AC:88/root/news");
+        uri2 = new URI("http://abc.com%E2%82%AC/root/news");
+        assertFalse(uri.equals(uri2));
+        assertFalse(uri2.equals(uri));
+
+        // test URIs with host names with different casing
+        uri = new URI("http://AbC.cOm/root/news");
+        uri2 = new URI("http://aBc.CoM/root/news");
+        assertTrue(uri.equals(uri2));
+        assertTrue(uri2.equals(uri));
+    }
+
+    /**
+     * @tests java.net.URI#getAuthority()
+     */
+    public void test_getAuthority() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getAuthorityResults = {
+                "user` info@host",
+                "user\u00DF\u00A3info@host:80", // =
+                // "user\u00df\u00a3info@host:80",
+                "user\u00DF\u00A3info@host:0", // =
+                // "user\u00df\u00a3info@host:0",
+                "user%60%20info@host:80",
+                "user%C3%9F%C2%A3info@host",
+                "user\u00DF\u00A3info@host:80", // =
+                // "user\u00df\u00a3info@host:80",
+                "user` info@host:81", "user%info@host:0", null, null, null,
+                null, "server.org", "reg:istry", null, };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getAuthority();
+            if (getAuthorityResults[i] != result
+                    && !getAuthorityResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getAuthority() returned: " + result
+                        + ", expected: " + getAuthorityResults[i]);
+            }
+        }
+        // regression test for HARMONY-1119
+        assertNull(new URI(null, null, null, 127, null, null, null)
+                .getAuthority());
+    }
+
+    /**
+     * @tests java.net.URI#getAuthority()
+     */
+    public void test_getAuthority2() throws Exception {
+        // tests for URIs with empty string authority component
+
+        URI uri = new URI("file:///tmp/");
+        assertNull("Authority not null for URI: " + uri, uri.getAuthority());
+        assertNull("Host not null for URI " + uri, uri.getHost());
+        assertEquals("testA, toString() returned incorrect value",
+                "file:///tmp/", uri.toString());
+
+        uri = new URI("file", "", "/tmp", "frag");
+        assertNull("Authority not null for URI: " + uri, uri.getAuthority());
+        assertNull("Host not null for URI " + uri, uri.getHost());
+        assertEquals("testB, toString() returned incorrect value",
+                "file:///tmp#frag", uri.toString());
+
+        uri = new URI("file", "", "/tmp", "query", "frag");
+        assertNull("Authority not null for URI: " + uri, uri.getAuthority());
+        assertNull("Host not null for URI " + uri, uri.getHost());
+        assertEquals("test C, toString() returned incorrect value",
+                "file:///tmp?query#frag", uri.toString());
+
+        // after normalization the host string info may be lost since the
+        // uri string is reconstructed
+        uri = new URI("file", "", "/tmp/a/../b/c", "query", "frag");
+        URI uri2 = uri.normalize();
+        assertNull("Authority not null for URI: " + uri2, uri.getAuthority());
+        assertNull("Host not null for URI " + uri2, uri.getHost());
+        assertEquals("test D, toString() returned incorrect value",
+                "file:///tmp/a/../b/c?query#frag", uri.toString());
+        assertEquals("test E, toString() returned incorrect value",
+                "file:/tmp/b/c?query#frag", uri2.toString());
+
+        // the empty string host will give URISyntaxException
+        // for the 7 arg constructor
+        try {
+            uri = new URI("file", "user", "", 80, "/path", "query", "frag");
+            fail("Expected URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getFragment()
+     */
+    public void test_getFragment() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getFragmentResults = { "fr^ ag", "fr\u00E4\u00E8g", // =
+                // "fr\u00e4\u00e8g",
+                "fr\u00E4\u00E8g", // = "fr\u00e4\u00e8g",
+                "fr%5E%20ag", "fr%C3%A4%C3%A8g", "fr\u00E4\u00E8g", // =
+                // "fr\u00e4\u00e8g",
+                "fr^ ag", "f%rag", null, "", null, "fragment", null, null, null };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getFragment();
+            if (getFragmentResults[i] != result
+                    && !getFragmentResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getFragment() returned: " + result
+                        + ", expected: " + getFragmentResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getHost()
+     */
+    public void test_getHost() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getHostResults = { "host", "host", "host", "host", "host",
+                "host", "host", "host", null, null, null, null, "server.org",
+                null, null };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getHost();
+            if (getHostResults[i] != result
+                    && !getHostResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getHost() returned: " + result + ", expected: "
+                        + getHostResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getPath()
+     */
+    public void test_getPath() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getPathResults = { "/a path",
+                "/a\u20ACpath", // = "/a\u0080path",
+                "/a\u20ACpath", // = "/a\u0080path",
+                "/a%20path", "/a%E2%82%ACpath",
+                "/a\u20ACpath", // = "/a\u0080path",
+                "/a path", "/a%path", null, "../adirectory/file.html", null,
+                "", "", "", "/c:/temp/calculate.pl" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getPath();
+            if (getPathResults[i] != result
+                    && !getPathResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getPath() returned: " + result + ", expected: "
+                        + getPathResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getPort()
+     */
+    public void test_getPort() throws Exception {
+        URI[] uris = getUris();
+
+        int[] getPortResults = { -1, 80, 0, 80, -1, 80, 81, 0, -1, -1, -1, -1,
+                -1, -1, -1 };
+
+        for (int i = 0; i < uris.length; i++) {
+            int result = uris[i].getPort();
+            assertTrue("Error: For URI \"" + uris[i].toString()
+                    + "\", getPort() returned: " + result + ", expected: "
+                    + getPortResults[i], result == getPortResults[i]);
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getPort()
+     */
+    public void test_getPort2() throws Exception {
+        // if port value is negative, the authority should be
+        // consider registry based.
+
+        URI uri = new URI("http://myhost:-8096/site/index.html");
+        assertEquals("TestA, returned wrong port value,", -1, uri.getPort());
+        assertNull("TestA, returned wrong host value,", uri.getHost());
+        try {
+            uri.parseServerAuthority();
+            fail("TestA, Expected URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        uri = new URI("http", "//myhost:-8096", null);
+        assertEquals("TestB returned wrong port value,", -1, uri.getPort());
+        assertNull("TestB returned wrong host value,", uri.getHost());
+        try {
+            uri.parseServerAuthority();
+            fail("TestB, Expected URISyntaxException");
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getQuery()
+     */
+    public void test_getQuery() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getQueryResults = { "qu` ery", "qu\u00A9\u00AEery", // =
+                // "qu\u00a9\u00aeery",
+                "qu\u00A9\u00AEery", // = "qu\u00a9\u00aeery",
+                "qu%60%20ery", "qu%C2%A9%C2%AEery", "qu\u00A9\u00AEery", // =
+                // "qu\u00a9\u00aeery",
+                "qu` ery", "que%ry", null, null, null, null, null, "query", "" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getQuery();
+            if (getQueryResults[i] != result
+                    && !getQueryResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getQuery() returned: " + result + ", expected: "
+                        + getQueryResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getRawAuthority()
+     */
+    public void test_getRawAuthority() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getRawAuthorityResults = {
+                "user%60%20info@host",
+                "user%C3%9F%C2%A3info@host:80",
+                "user\u00DF\u00A3info@host:0", // =
+                // "user\u00df\u00a3info@host:0",
+                "user%2560%2520info@host:80",
+                "user%25C3%259F%25C2%25A3info@host",
+                "user\u00DF\u00A3info@host:80", // =
+                // "user\u00df\u00a3info@host:80",
+                "user%60%20info@host:81", "user%25info@host:0", null, null,
+                null, null, "server.org", "reg:istry", null };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getRawAuthority();
+            if (getRawAuthorityResults[i] != result
+                    && !getRawAuthorityResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getRawAuthority() returned: " + result
+                        + ", expected: " + getRawAuthorityResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getRawFragment()
+     */
+    public void test_getRawFragment() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getRawFragmentResults = { "fr%5E%20ag",
+                "fr%C3%A4%C3%A8g",
+                "fr\u00E4\u00E8g", // = "fr\u00e4\u00e8g",
+                "fr%255E%2520ag", "fr%25C3%25A4%25C3%25A8g",
+                "fr\u00E4\u00E8g", // =
+                // "fr\u00e4\u00e8g",
+                "fr%5E%20ag", "f%25rag", null, "", null, "fragment", null,
+                null, null };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getRawFragment();
+            if (getRawFragmentResults[i] != result
+                    && !getRawFragmentResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getRawFragment() returned: " + result
+                        + ", expected: " + getRawFragmentResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getRawPath()
+     */
+    public void test_getRawPath() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getRawPathResults = { "/a%20path",
+                "/a%E2%82%ACpath",
+                "/a\u20ACpath", // = "/a\u0080path",
+                "/a%2520path", "/a%25E2%2582%25ACpath",
+                "/a\u20ACpath", // =
+                // "/a\u0080path",
+                "/a%20path", "/a%25path", null, "../adirectory/file.html",
+                null, "", "", "", "/c:/temp/calculate.pl" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getRawPath();
+            if (getRawPathResults[i] != result
+                    && !getRawPathResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getRawPath() returned: " + result
+                        + ", expected: " + getRawPathResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getRawQuery()
+     */
+    public void test_getRawQuery() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getRawQueryResults = {
+                "qu%60%20ery",
+                "qu%C2%A9%C2%AEery",
+                "qu\u00A9\u00AEery", // = "qu\u00a9\u00aeery",
+                "qu%2560%2520ery",
+                "qu%25C2%25A9%25C2%25AEery",
+                "qu\u00A9\u00AEery", // = "qu\u00a9\u00aeery",
+                "qu%60%20ery", "que%25ry", null, null, null, null, null,
+                "query", "" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getRawQuery();
+            if (getRawQueryResults[i] != result
+                    && !getRawQueryResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getRawQuery() returned: " + result
+                        + ", expected: " + getRawQueryResults[i]);
+            }
+        }
+
+    }
+
+    /**
+     * @tests java.net.URI#getRawSchemeSpecificPart()
+     */
+    public void test_getRawSchemeSpecificPart() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getRawSspResults = {
+                "//user%60%20info@host/a%20path?qu%60%20ery",
+                "//user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery",
+                "//user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery", // =
+                // "//user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery"
+                "//user%2560%2520info@host:80/a%2520path?qu%2560%2520ery",
+                "//user%25C3%259F%25C2%25A3info@host/a%25E2%2582%25ACpath?qu%25C2%25A9%25C2%25AEery",
+                "//user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery", // =
+                // "//user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery"
+                "//user%60%20info@host:81/a%20path?qu%60%20ery",
+                "//user%25info@host:0/a%25path?que%25ry", "user@domain.com",
+                "../adirectory/file.html", "comp.infosystems.www.servers.unix",
+                "", "//server.org", "//reg:istry?query",
+                "///c:/temp/calculate.pl?" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getRawSchemeSpecificPart();
+            if (!getRawSspResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getRawSchemeSpecificPart() returned: " + result
+                        + ", expected: " + getRawSspResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getRawUserInfo()
+     */
+    public void test_getRawUserInfo() throws URISyntaxException {
+        URI[] uris = getUris();
+
+        String[] getRawUserInfoResults = {
+                "user%60%20info",
+                "user%C3%9F%C2%A3info",
+                "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+                "user%2560%2520info",
+                "user%25C3%259F%25C2%25A3info",
+                "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+                "user%60%20info", "user%25info", null, null, null, null, null,
+                null, null };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getRawUserInfo();
+            if (getRawUserInfoResults[i] != result
+                    && !getRawUserInfoResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getRawUserInfo() returned: " + result
+                        + ", expected: " + getRawUserInfoResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getScheme()
+     */
+    public void test_getScheme() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getSchemeResults = { "http", "http", "ascheme", "http",
+                "http", "ascheme", "http", "http", "mailto", null, "news",
+                null, "telnet", "http", "file" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getScheme();
+            if (getSchemeResults[i] != result
+                    && !getSchemeResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getScheme() returned: " + result
+                        + ", expected: " + getSchemeResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#getSchemeSpecificPart()
+     */
+    public void test_getSchemeSpecificPart() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getSspResults = {
+                "//user` info@host/a path?qu` ery",
+                "//user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery", // =
+                // "//user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery",
+                "//user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery", // =
+                // "//user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery",
+                "//user%60%20info@host:80/a%20path?qu%60%20ery",
+                "//user%C3%9F%C2%A3info@host/a%E2%82%ACpath?qu%C2%A9%C2%AEery",
+                "//user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery", // =
+                // "//user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery",
+                "//user` info@host:81/a path?qu` ery",
+                "//user%info@host:0/a%path?que%ry", "user@domain.com",
+                "../adirectory/file.html", "comp.infosystems.www.servers.unix",
+                "", "//server.org", "//reg:istry?query",
+                "///c:/temp/calculate.pl?" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getSchemeSpecificPart();
+            if (!getSspResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getSchemeSpecificPart() returned: " + result
+                        + ", expected: " + getSspResults[i]);
+            }
+        }
+
+    }
+
+    /**
+     * @tests java.net.URI#getUserInfo()
+     */
+    public void test_getUserInfo() throws Exception {
+        URI[] uris = getUris();
+
+        String[] getUserInfoResults = {
+                "user` info",
+                "user\u00DF\u00A3info", // =
+                // "user\u00df\u00a3info",
+                "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+                "user%60%20info",
+                "user%C3%9F%C2%A3info",
+                "user\u00DF\u00A3info", // = "user\u00df\u00a3info",
+                "user` info", "user%info", null, null, null, null, null, null,
+                null };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].getUserInfo();
+            if (getUserInfoResults[i] != result
+                    && !getUserInfoResults[i].equals(result)) {
+                fail("Error: For URI \"" + uris[i].toString()
+                        + "\", getUserInfo() returned: " + result
+                        + ", expected: " + getUserInfoResults[i]);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#hashCode()
+     */
+    public void test_hashCode() throws Exception {
+        String[][] hashCodeData = new String[][] {
+                { "", "" }, // null frags
+                { "/path", "/path#frag" },
+                { "#frag", "#frag2" },
+                { "#frag", "#FRag" },
+
+                { "#fr%4F", "#fr%4F" }, // case insensitive on hex escapes
+
+                { "scheme:test", "scheme2:test" }, // scheme
+                { "test", "http:test" },
+                { "http:test", "test" },
+
+                // case insensitivity for scheme
+                { "SCheme:test", "schEMe:test" },
+
+                // hierarchical/opaque mismatch
+                { "mailto:jim", "mailto://jim" },
+                { "mailto://test", "mailto:test" },
+
+                // opaque
+                { "mailto:name", "mailto:name" },
+                { "mailtO:john", "mailto:jim" },
+                { "mailto:te%4Fst", "mailto:te%4Fst" },
+                { "mailto:john#frag", "mailto:john#frag2" },
+
+                // hierarchical
+                { "/test/", "/test/" }, // paths
+                { "/te%F4st", "/te%F4st" },
+                { "/TEst", "/teSt" },
+                { "", "/test" },
+
+                // registry based because they don't resolve properly to
+                // server-based
+                // add more tests here
+                { "//host.com:80err", "//host.com:80e" },
+                { "//host.com:81e%Abrr", "//host.com:81e%Abrr" },
+                { "//Host.com:80e", "//hoSt.com:80e" },
+
+                { "/test", "//auth.com/test" },
+                { "//test.com", "/test" },
+
+                { "//test.com", "//test.com" }, // server based
+
+                // case insensitivity for host
+                { "//HoSt.coM/", "//hOsT.cOm/" },
+                { "//te%aE.com", "//te%aE.com" },
+                { "//test.com:80", "//test.com:81" },
+                { "//joe@test.com:80", "//test.com:80" },
+                { "//jo%3E@test.com:82", "//jo%3E@test.com:82" },
+                { "//test@test.com:85", "//test@test.com" }, };
+
+        boolean[] hashCodeResults = new boolean[] { true, false, false, false,
+                true, false, false, false, true, false, false, true, false,
+                true, false, true, true, false, false, false, true, false,
+                false, false, true, true, true, false, false, true, false, };
+
+        for (int i = 0; i < hashCodeResults.length; i++) {
+            URI b = new URI(hashCodeData[i][0]);
+            URI r = new URI(hashCodeData[i][1]);
+            assertEquals("Error in hashcode equals results for" + b.toString()
+                    + " " + r.toString(), hashCodeResults[i], b.hashCode() == r
+                    .hashCode());
+        }
+
+    }
+
+    /**
+     * @tests java.net.URI#isAbsolute()
+     */
+    public void test_isAbsolute() throws URISyntaxException {
+        String[] isAbsoluteData = new String[] { "mailto:user@ca.ibm.com",
+                "urn:isbn:123498989h", "news:software.ibm.com",
+                "http://www.amazon.ca", "file:///d:/temp/results.txt",
+                "scheme:ssp", "calculate.pl?isbn=123498989h",
+                "?isbn=123498989h", "//www.amazon.ca", "a.html", "#top",
+                "//pc1/", "//user@host/path/file" };
+
+        boolean results[] = new boolean[] { true, true, true, true, true, true,
+                false, false, false, false, false, false, false };
+
+        for (int i = 0; i < isAbsoluteData.length; i++) {
+            boolean result = new URI(isAbsoluteData[i]).isAbsolute();
+            assertEquals("new URI(" + isAbsoluteData[i] + ").isAbsolute()",
+                    results[i], result);
+        }
+    }
+
+    /**
+     * @tests java.net.URI#isOpaque()
+     */
+    public void test_isOpaque() throws URISyntaxException {
+        String[] isOpaqueData = new String[] { "mailto:user@ca.ibm.com",
+                "urn:isbn:123498989h", "news:software.ibm.com",
+                "http://www.amazon.ca", "file:///d:/temp/results.txt",
+                "scheme:ssp", "calculate.pl?isbn=123498989h",
+                "?isbn=123498989h", "//www.amazon.ca", "a.html", "#top",
+                "//pc1/", "//user@host/path/file" };
+
+        boolean results[] = new boolean[] { true, true, true, false, false,
+                true, false, false, false, false, false, false, false };
+
+        for (int i = 0; i < isOpaqueData.length; i++) {
+            boolean result = new URI(isOpaqueData[i]).isOpaque();
+            assertEquals("new URI(" + isOpaqueData[i] + ").isOpaque()",
+                    results[i], result);
+        }
+    }
+
+    /**
+     * @tests java.net.URI#normalize()
+     */
+    public void test_normalize() throws Exception {
+
+        String[] normalizeData = new String[] {
+                // normal
+                "/",
+                "/a",
+                "/a/b",
+                "/a/b/c",
+                // single, '.'
+                "/.", "/./", "/./.", "/././",
+                "/./a",
+                "/./a/",
+                "/././a",
+                "/././a/",
+                "/a/.",
+                "/a/./",
+                "/a/./.",
+                "/a/./b",
+                // double, '..'
+                "/a/..", "/a/../", "/a/../b", "/a/../b/..", "/a/../b/../",
+                "/a/../b/../c", "/..", "/../", "/../..", "/../../", "/../a",
+                "/../a/", "/../../a", "/../../a/", "/a/b/../../c",
+                "/a/b/../..",
+                "/a/b/../../",
+                "/a/b/../../c",
+                "/a/b/c/../../../d",
+                "/a/b/..",
+                "/a/b/../",
+                "/a/b/../c",
+                // miscellaneous
+                "/a/b/.././../../c/./d/../e",
+                "/a/../../.c././../././c/d/../g/..",
+                // '.' in the middle of segments
+                "/a./b", "/.a/b", "/a.b/c", "/a/b../c",
+                "/a/..b/c",
+                "/a/b..c/d",
+                // no leading slash, miscellaneous
+                "", "a", "a/b", "a/b/c", "../", ".", "..", "../g",
+                "g/a/../../b/c/./g", "a/b/.././../../c/./d/../e",
+                "a/../../.c././../././c/d/../g/..", };
+
+        String[] normalizeResults = new String[] { "/", "/a", "/a/b", "/a/b/c",
+                "/", "/", "/", "/", "/a", "/a/", "/a", "/a/", "/a/", "/a/",
+                "/a/", "/a/b", "/", "/", "/b", "/", "/", "/c", "/..", "/../",
+                "/../..", "/../../", "/../a", "/../a/", "/../../a",
+                "/../../a/", "/c", "/", "/", "/c", "/d", "/a/", "/a/", "/a/c",
+                "/../c/e", "/../c/", "/a./b", "/.a/b", "/a.b/c", "/a/b../c",
+                "/a/..b/c", "/a/b..c/d", "", "a", "a/b", "a/b/c", "../", "",
+                "..", "../g", "b/c/g", "../c/e", "../c/", };
+
+        for (int i = 0; i < normalizeData.length; i++) {
+            URI test = new URI(normalizeData[i]);
+            String result = test.normalize().toString();
+            assertEquals("Normalized incorrectly, ", normalizeResults[i],
+                    result.toString());
+        }
+    }
+
+    /**
+     * @tests java.net.URI#normalize()
+     */
+    public void test_normalize2() throws URISyntaxException {
+        URI uri1 = null, uri2 = null;
+        uri1 = new URI("file:/D:/one/two/../../three");
+        uri2 = uri1.normalize();
+
+        assertEquals("Normalized to incorrect URI", "file:/D:/three", uri2
+                .toString());
+        assertTrue("Resolved URI is not absolute", uri2.isAbsolute());
+        assertFalse("Resolved URI is opaque", uri2.isOpaque());
+        assertEquals("Resolved URI has incorrect scheme  specific part",
+                "/D:/three", uri2.getRawSchemeSpecificPart());
+    }
+
+    /**
+     * @tests java.net.URI#normalize()
+     */
+    public void test_normalize3() throws URISyntaxException {
+        // return same URI if it has a normalized path already
+        URI uri1 = null, uri2 = null;
+        uri1 = new URI("http://host/D:/one/two/three");
+        uri2 = uri1.normalize();
+        assertSame("Failed to return same URI after normalization", uri1, uri2);
+
+        // try with empty path
+        uri1 = new URI("http", "host", null, "fragment");
+        uri2 = uri1.normalize();
+        assertSame("Failed to return same URI after normalization", uri1, uri2);
+    }
+
+    /**
+     * @tests java.net.URI#parseServerAuthority()
+     */
+    public void test_parseServerAuthority() throws URISyntaxException {
+        // registry based uris
+        URI[] uris = null;
+        uris = new URI[] {
+                // port number not digits
+                new URI("http://foo:bar/file#fragment"),
+                new URI("http", "//foo:bar/file", "fragment"),
+
+                // unicode char in the hostname = new
+                // URI("http://host\u00dfname/")
+                new URI("http://host\u00DFname/"),
+
+                new URI("http", "//host\u00DFname/", null),
+                // = new URI("http://host\u00dfname/", null),
+
+                // escaped octets in host name
+                new URI("http://host%20name/"),
+                new URI("http", "//host%20name/", null),
+
+                // missing host name, port number
+                new URI("http://joe@:80"),
+
+                // missing host name, no port number
+                new URI("http://user@/file?query#fragment"),
+
+                new URI("//host.com:80err"), // malformed port number
+                new URI("//host.com:81e%Abrr"),
+
+                // malformed ipv4 address
+                new URI("telnet", "//256.197.221.200", null),
+
+                new URI("telnet://198.256.221.200"),
+                new URI("//te%ae.com"), // misc ..
+                new URI("//:port"), new URI("//:80"),
+
+                // last label has to start with alpha char
+                new URI("//fgj234fkgj.jhj.123."),
+
+                new URI("//fgj234fkgj.jhj.123"),
+
+                // '-' cannot be first or last character in a label
+                new URI("//-domain.name"), new URI("//domain.name-"),
+                new URI("//domain-"),
+
+                // illegal char in host name
+                new URI("//doma*in"),
+
+                // host expected
+                new URI("http://:80/"), new URI("http://user@/"),
+
+                // ipv6 address not enclosed in "[]"
+                new URI("http://3ffe:2a00:100:7031:22:1:80:89/"),
+
+                // expected ipv6 addresses to be enclosed in "[]"
+                new URI("http", "34::56:78", "/path", "query", "fragment"),
+
+                // expected host
+                new URI("http", "user@", "/path", "query", "fragment") };
+        // these URIs do not have valid server based authorities,
+        // but single arg, 3 and 5 arg constructors
+        // parse them as valid registry based authorities
+
+        // exception should occur when parseServerAuthority is
+        // requested on these uris
+        for (int i = 0; i < uris.length; i++) {
+            try {
+                URI uri = uris[i].parseServerAuthority();
+                fail("URISyntaxException expected but not received for URI: "
+                        + uris[i].toString());
+            } catch (URISyntaxException e) {
+                // Expected
+            }
+        }
+
+        // valid Server based authorities
+        new URI("http", "3ffe:2a00:100:7031:2e:1:80:80", "/path", "fragment")
+                .parseServerAuthority();
+        new URI("http", "host:80", "/path", "query", "fragment")
+                .parseServerAuthority();
+        new URI("http://[::3abc:4abc]:80/").parseServerAuthority();
+        new URI("http", "34::56:78", "/path", "fragment")
+                .parseServerAuthority();
+        new URI("http", "[34:56::78]:80", "/path", "fragment")
+                .parseServerAuthority();
+
+        // invalid authorities (neither server nor registry)
+        try {
+            URI uri = new URI("http://us[er@host:80/");
+            fail("Expected URISyntaxException for URI " + uri.toString());
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        try {
+            URI uri = new URI("http://[ddd::hgghh]/");
+            fail("Expected URISyntaxException for URI " + uri.toString());
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        try {
+            URI uri = new URI("http", "[3ffe:2a00:100:7031:2e:1:80:80]a:80",
+                    "/path", "fragment");
+            fail("Expected URISyntaxException for URI " + uri.toString());
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        try {
+            URI uri = new URI("http", "host:80", "/path", "fragment");
+            fail("Expected URISyntaxException for URI " + uri.toString());
+        } catch (URISyntaxException e) {
+            // Expected
+        }
+
+        // regression test for HARMONY-1126
+        assertNotNull(URI.create("file://C:/1.txt").parseServerAuthority());
+    }
+
     /**
      * @tests java.net.URI#relativize(java.net.URI)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "NullPointerException checking missed.",
-        method = "relativize",
-        args = {java.net.URI.class}
-    )
-    public void test_relativizeLjava_net_URI() throws URISyntaxException{
+    public void test_relativizeLjava_net_URI() throws URISyntaxException {
+        // relativization tests
+        String[][] relativizeData = new String[][] {
+                // first is base, second is the one to relativize
+                { "http://www.google.com/dir1/dir2", "mailto:test" }, // rel =
+                // opaque
+                { "mailto:test", "http://www.google.com" }, // base = opaque
+
+                // different authority
+                { "http://www.eclipse.org/dir1",
+                        "http://www.google.com/dir1/dir2" },
+
+                // different scheme
+                { "http://www.google.com", "ftp://www.google.com" },
+
+                { "http://www.google.com/dir1/dir2/",
+                        "http://www.google.com/dir3/dir4/file.txt" },
+                { "http://www.google.com/dir1/",
+                        "http://www.google.com/dir1/dir2/file.txt" },
+                { "./dir1/", "./dir1/hi" },
+                { "/dir1/./dir2", "/dir1/./dir2/hi" },
+                { "/dir1/dir2/..", "/dir1/dir2/../hi" },
+                { "/dir1/dir2/..", "/dir1/dir2/hi" },
+                { "/dir1/dir2/", "/dir1/dir3/../dir2/text" },
+                { "//www.google.com", "//www.google.com/dir1/file" },
+                { "/dir1", "/dir1/hi" }, { "/dir1/", "/dir1/hi" }, };
+
+        // expected results
+        String[] relativizeResults = new String[] { "mailto:test",
+                "http://www.google.com", "http://www.google.com/dir1/dir2",
+                "ftp://www.google.com",
+                "http://www.google.com/dir3/dir4/file.txt", "dir2/file.txt",
+                "hi", "hi", "hi", "dir2/hi", "text", "dir1/file", "hi", "hi", };
+
+        for (int i = 0; i < relativizeData.length; i++) {
+            try {
+                URI b = new URI(relativizeData[i][0]);
+                URI r = new URI(relativizeData[i][1]);
+                if (!b.relativize(r).toString().equals(relativizeResults[i])) {
+                    fail("Error: relativize, " + relativizeData[i][0] + ", "
+                            + relativizeData[i][1] + " returned: "
+                            + b.relativize(r) + ", expected:"
+                            + relativizeResults[i]);
+                }
+            } catch (URISyntaxException e) {
+                fail("Exception on relativize test on data "
+                        + relativizeData[i][0] + ", " + relativizeData[i][1]
+                        + ": " + e);
+            }
+        }
+
         URI a = new URI("http://host/dir");
-        URI b = new URI("http://host/dir/file?query");        
-        assertEquals("Assert 0: URI relativized incorrectly,",
-                new URI("file?query"), a.relativize(b));        
-    
+        URI b = new URI("http://host/dir/file?query");
+        assertEquals("Assert 0: URI relativized incorrectly,", new URI(
+                "file?query"), a.relativize(b));
+
         // One URI with empty host
         a = new URI("file:///~/first");
         b = new URI("file://tools/~/first");
-        assertEquals("Assert 1: URI relativized incorrectly,",
-                new URI("file://tools/~/first"), a.relativize(b));        
-        assertEquals("Assert 2: URI relativized incorrectly,",
-                new URI("file:///~/first"), b.relativize(a));        
+        assertEquals("Assert 1: URI relativized incorrectly,", new URI(
+                "file://tools/~/first"), a.relativize(b));
+        assertEquals("Assert 2: URI relativized incorrectly,", new URI(
+                "file:///~/first"), b.relativize(a));
 
         // Both URIs with empty hosts
         b = new URI("file:///~/second");
-        assertEquals("Assert 3: URI relativized incorrectly,",
-                new URI("file:///~/second"), a.relativize(b));
-        assertEquals("Assert 4: URI relativized incorrectly,",
-                new URI("file:///~/first"), b.relativize(a));
+        assertEquals("Assert 3: URI relativized incorrectly,", new URI(
+                "file:///~/second"), a.relativize(b));
+        assertEquals("Assert 4: URI relativized incorrectly,", new URI(
+                "file:///~/first"), b.relativize(a));
     }
-    
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "NullPointerException checking missed.",
-        method = "relativize",
-        args = {java.net.URI.class}
-    )
-    public void test_relativizeBasedOneEclipseCoreResources() throws URISyntaxException {
+
+    // Regression test for HARMONY-6075
+    public void test_relativize3() throws Exception {
+        URI uri = new URI("file", null, "/test/location", null);
+
+        URI base = new URI("file", null, "/test", null);
+
+        URI relative = base.relativize(uri);
+        assertEquals("location", relative.getSchemeSpecificPart());
+        assertNull(relative.getScheme());
+    }
+
+    /**
+     * @tests java.net.URI#relativize(java.net.URI)
+     */
+    public void test_relativize2() throws URISyntaxException {
+        URI a = new URI("http://host/dir");
+        URI b = new URI("http://host/dir/file?query");
+        assertEquals("relativized incorrectly,", new URI("file?query"), a
+                .relativize(b));
+
+        // one URI with empty host
+        a = new URI("file:///~/dictionary");
+        b = new URI("file://tools/~/dictionary");
+        assertEquals("relativized incorrectly,", new URI(
+                "file://tools/~/dictionary"), a.relativize(b));
+        assertEquals("relativized incorrectly,",
+                new URI("file:///~/dictionary"), b.relativize(a));
+
+        // two URIs with empty hosts
+        b = new URI("file:///~/therasus");
+        assertEquals("relativized incorrectly,", new URI("file:///~/therasus"),
+                a.relativize(b));
+        assertEquals("relativized incorrectly,",
+                new URI("file:///~/dictionary"), b.relativize(a));
+
         URI one = new URI("file:/C:/test/ws");
         URI two = new URI("file:/C:/test/ws");
-        
+
         URI empty = new URI("");
         assertEquals(empty, one.relativize(two));
-        
+
         one = new URI("file:/C:/test/ws");
         two = new URI("file:/C:/test/ws/p1");
         URI result = new URI("p1");
         assertEquals(result, one.relativize(two));
-        
+
         one = new URI("file:/C:/test/ws/");
         assertEquals(result, one.relativize(two));
     }
+
+    /**
+     * @tests java.net.URI#resolve(java.net.URI)
+     */
+    public void test_resolve() throws URISyntaxException {
+        URI uri1 = null, uri2 = null;
+        uri1 = new URI("file:/D:/one/two/three");
+        uri2 = uri1.resolve(new URI(".."));
+
+        assertEquals("Resolved to incorrect URI", "file:/D:/one/", uri2
+                .toString());
+        assertTrue("Resolved URI is not absolute", uri2.isAbsolute());
+        assertFalse("Resolved URI is opaque", uri2.isOpaque());
+        assertEquals("Resolved URI has incorrect scheme  specific part",
+                "/D:/one/", uri2.getRawSchemeSpecificPart());
+    }
+
+    /**
+     * @tests java.net.URI#resolve(java.net.URI)
+     */
+    public void test_resolveLjava_net_URI() {
+        // resolution tests
+        String[][] resolveData = new String[][] {
+                // authority in given URI
+                { "http://www.test.com/dir",
+                        "//www.test.com/hello?query#fragment" },
+                // no authority, absolute path
+                { "http://www.test.com/dir", "/abspath/file.txt" },
+                // no authority, relative paths
+                { "/", "dir1/file.txt" }, { "/dir1", "dir2/file.txt" },
+                { "/dir1/", "dir2/file.txt" }, { "", "dir1/file.txt" },
+                { "dir1", "dir2/file.txt" }, { "dir1/", "dir2/file.txt" },
+                // normalization required
+                { "/dir1/dir2/../dir3/./", "dir4/./file.txt" },
+                // allow a standalone fragment to be resolved
+                { "http://www.google.com/hey/joe?query#fragment", "#frag2" },
+                // return given when base is opaque
+                { "mailto:idontexist@uk.ibm.com", "dir1/dir2" },
+                // return given when given is absolute
+                { "http://www.google.com/hi/joe", "http://www.oogle.com" }, };
+
+        // expected results
+        String[] resolveResults = new String[] {
+                "http://www.test.com/hello?query#fragment",
+                "http://www.test.com/abspath/file.txt", "/dir1/file.txt",
+                "/dir2/file.txt", "/dir1/dir2/file.txt", "dir1/file.txt",
+                "dir2/file.txt", "dir1/dir2/file.txt",
+                "/dir1/dir3/dir4/file.txt",
+                "http://www.google.com/hey/joe?query#frag2", "dir1/dir2",
+                "http://www.oogle.com", };
+
+        for (int i = 0; i < resolveResults.length; i++) {
+            try {
+                URI b = new URI(resolveData[i][0]);
+                URI r = new URI(resolveData[i][1]);
+                URI result = b.resolve(r);
+                if (!result.toString().equals(resolveResults[i])) {
+                    fail("Error: resolve, " + resolveData[i][0] + ", "
+                            + resolveData[i][1] + " returned: " + b.resolve(r)
+                            + ", expected:" + resolveResults[i]);
+                }
+                if (!b.isOpaque()) {
+                    assertEquals(b + " and " + result
+                            + " incorrectly differ in absoluteness", b
+                            .isAbsolute(), result.isAbsolute());
+                }
+            } catch (URISyntaxException e) {
+                fail("Exception on resolve test on data " + resolveData[i][0]
+                        + ", " + resolveData[i][1] + ": " + e);
+            }
+        }
+    }
+
+    /**
+     * @tests java.net.URI#toASCIIString()
+     */
+    public void test_toASCIIString() throws Exception {
+        URI[] uris = getUris();
+
+        String[] toASCIIStringResults0 = new String[] {
+                "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag",
+                "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+                "ascheme://user%C3%9F%C2%A3info@host:0/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+                "http://user%2560%2520info@host:80/a%2520path?qu%2560%2520ery#fr%255E%2520ag",
+                "http://user%25C3%259F%25C2%25A3info@host/a%25E2%2582%25ACpath?qu%25C2%25A9%25C2%25AEery#fr%25C3%25A4%25C3%25A8g",
+                "ascheme://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+                "http://user%60%20info@host:81/a%20path?qu%60%20ery#fr%5E%20ag",
+                "http://user%25info@host:0/a%25path?que%25ry#f%25rag",
+                "mailto:user@domain.com", "../adirectory/file.html#",
+                "news:comp.infosystems.www.servers.unix", "#fragment",
+                "telnet://server.org", "http://reg:istry?query",
+                "file:///c:/temp/calculate.pl?" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].toASCIIString();
+            assertTrue("Error: For URI \"" + uris[i].toString()
+                    + "\", toASCIIString() returned: " + result
+                    + ", expected: " + toASCIIStringResults0[i], result
+                    .equals(toASCIIStringResults0[i]));
+        }
+
+        String[] toASCIIStringData = new String[] {
+                "http://www.test.com/\u00DF/dir/",
+                "http://www.test.com/\u20AC/dir", "http://www.\u20AC.com/dir",
+                "http://www.test.com/\u20AC/dir/file#fragment",
+                "mailto://user@domain.com", "mailto://user\u00DF@domain.com", };
+
+        String[] toASCIIStringResults = new String[] {
+                "http://www.test.com/%C3%9F/dir/",
+                "http://www.test.com/%E2%82%AC/dir",
+                "http://www.%E2%82%AC.com/dir",
+                "http://www.test.com/%E2%82%AC/dir/file#fragment",
+                "mailto://user@domain.com", "mailto://user%C3%9F@domain.com", };
+
+        for (int i = 0; i < toASCIIStringData.length; i++) {
+            URI test = new URI(toASCIIStringData[i]);
+            String result = test.toASCIIString();
+            assertTrue("Error: new URI(\"" + toASCIIStringData[i]
+                    + "\").toASCIIString() returned: " + result
+                    + ", expected: " + toASCIIStringResults[i], result
+                    .equals(toASCIIStringResults[i]));
+        }
+    }
+
+    /**
+     * @tests java.net.URI#toString()
+     */
+    public void test_toString() throws Exception {
+        URI[] uris = getUris();
+
+        String[] toStringResults = {
+                "http://user%60%20info@host/a%20path?qu%60%20ery#fr%5E%20ag",
+                "http://user%C3%9F%C2%A3info@host:80/a%E2%82%ACpath?qu%C2%A9%C2%AEery#fr%C3%A4%C3%A8g",
+                "ascheme://user\u00DF\u00A3info@host:0/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g",
+                // =
+                // "ascheme://user\u00df\u00a3info@host:0/a\u0080path?qu\u00a9\u00aeery#fr\u00e4\u00e8g",
+                "http://user%2560%2520info@host:80/a%2520path?qu%2560%2520ery#fr%255E%2520ag",
+                "http://user%25C3%259F%25C2%25A3info@host/a%25E2%2582%25ACpath?qu%25C2%25A9%25C2%25AEery#fr%25C3%25A4%25C3%25A8g",
+                "ascheme://user\u00DF\u00A3info@host:80/a\u20ACpath?qu\u00A9\u00AEery#fr\u00E4\u00E8g",
+                // =
+                // "ascheme://user\u00df\u00a3info@host:80/a\u0080path?qu\u00a9\u00aeery#fr\u00e4\u00e8g",
+                "http://user%60%20info@host:81/a%20path?qu%60%20ery#fr%5E%20ag",
+                "http://user%25info@host:0/a%25path?que%25ry#f%25rag",
+                "mailto:user@domain.com", "../adirectory/file.html#",
+                "news:comp.infosystems.www.servers.unix", "#fragment",
+                "telnet://server.org", "http://reg:istry?query",
+                "file:///c:/temp/calculate.pl?" };
+
+        for (int i = 0; i < uris.length; i++) {
+            String result = uris[i].toString();
+            assertTrue("Error: For URI \"" + uris[i].toString()
+                    + "\", toString() returned: " + result + ", expected: "
+                    + toStringResults[i], result.equals(toStringResults[i]));
+        }
+    }
+
+    /**
+     * @tests java.net.URI#toURL()
+     */
+    public void test_toURL() throws Exception {
+        String absoluteuris[] = new String[] { "mailto:noreply@apache.org",
+                "urn:isbn:123498989h", "news:software.ibm.com",
+                "http://www.apache.org", "file:///d:/temp/results.txt",
+                "scheme:ssp", };
+
+        String relativeuris[] = new String[] { "calculate.pl?isbn=123498989h",
+                "?isbn=123498989h", "//www.apache.org", "a.html", "#top",
+                "//pc1/", "//user@host/path/file" };
+
+        for (int i = 0; i < absoluteuris.length; i++) {
+            try {
+                new URI(absoluteuris[i]).toURL();
+            } catch (MalformedURLException e) {
+                // not all the URIs can be translated into valid URLs
+            }
+        }
+
+        for (int i = 0; i < relativeuris.length; i++) {
+            try {
+                new URI(relativeuris[i]).toURL();
+                fail("Expected IllegalArgumentException not thrown");
+            } catch (IllegalArgumentException e) {
+                // Expected
+            }
+        }
+    }
     
     /**
-     * @tests java.net.URI#compareTo(java.net.URI)
+     * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.net.URI.class}
-    )
-    public void test_compareToLjava_net_URI() throws URISyntaxException{
-        URI uri1, uri2;
+    public void testSerializationSelf() throws Exception {
+        URI uri = new URI("http://harmony.apache.org/");
 
-        // URIs whose host names have different casing
-        uri1 = new URI("http://MixedCaseHost/path/resource");
-        uri2 = new URI("http://mixedcasehost/path/resource");
-        assertEquals("Assert 0: host name equality failure", 0, uri1.compareTo(uri2));
-        assertEquals("Assert 1: host name equality failure", 0, uri1.compareTo(uri2));
-
-        // URIs with one undefined component (port)
-        uri1 = new URI("http://anyhost:80/path/resource");
-        uri2 = new URI("http://anyhost/path/resource");
-        assertTrue("Assert 2: comparison failure", uri1.compareTo(uri2) > 0);
-        assertTrue("Assert 3: comparison failure", uri2.compareTo(uri1) < 0);
-        
-        // URIs with one undefined component (user-info)
-        uri1 = new URI("http://user-info@anyhost/path/resource");
-        uri2 = new URI("http://anyhost/path/resource");
-        assertTrue("Assert 4: comparison failure", uri1.compareTo(uri2) > 0);
-        assertTrue("Assert 5: comparison failure", uri2.compareTo(uri1) < 0);
-        
+        SerializationTest.verifySelf(uri);
     }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLEncoderTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLEncoderTest.java
index 52fdf4a..67a81cf 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLEncoderTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLEncoderTest.java
@@ -1,57 +1,67 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.net;
 
-import dalvik.annotation.TestTargetClass; 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 
 import junit.framework.TestCase;
+import tests.support.Support_Configuration;
 
-@TestTargetClass(URLEncoder.class) 
 public class URLEncoderTest extends TestCase {
-    
+
+    /**
+     * @tests java.net.URLEncoder#encode(java.lang.String)
+     */
+    @SuppressWarnings("deprecation")
+    public void test_encodeLjava_lang_String() {
+        final String URL = "http://" + Support_Configuration.HomeAddress;
+        final String URL2 = "telnet://justWantToHaveFun.com:400";
+        final String URL3 = "file://myServer.org/a file with spaces.jpg";
+
+        assertTrue("1. Incorrect encoding/decoding", URLDecoder.decode(
+                URLEncoder.encode(URL)).equals(URL));
+        assertTrue("2. Incorrect encoding/decoding", URLDecoder.decode(
+                URLEncoder.encode(URL2)).equals(URL2));
+        assertTrue("3. Incorrect encoding/decoding", URLDecoder.decode(
+                URLEncoder.encode(URL3)).equals(URL3));
+    }
+
     /**
      * @tests URLEncoder#encode(String, String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Regression test. Checks UnsupportedEncodingException & NullPointerException",
-        method = "encode",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
-    public void test_encodeLjava_lang_StringLjava_lang_String() throws Exception {
+    public void test_encodeLjava_lang_StringLjava_lang_String()
+            throws Exception {
         // Regression for HARMONY-24
         try {
-            URLEncoder.encode("str","unknown_enc");
+            URLEncoder.encode("str", "unknown_enc");
             fail("Assert 0: Should throw UEE for invalid encoding");
         } catch (UnsupportedEncodingException e) {
             // expected
-        } 
-        //Regression for HARMONY-1233
+        }
+
+        // Regression for HARMONY-1233
         try {
             URLEncoder.encode(null, "harmony");
             fail("NullPointerException expected");
         } catch (NullPointerException e) {
-            //expected
+            // expected
         }
     }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractCollectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractCollectionTest.java
index 801727c..6021c32 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractCollectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AbstractCollectionTest.java
@@ -17,29 +17,17 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.util.AbstractCollection;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import junit.framework.TestCase;
 
-@TestTargetClass(java.util.AbstractCollection.class)
 public class AbstractCollectionTest extends TestCase {
 
     /**
      * @tests java.util.AbstractCollection#add(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "add",
-        args = {java.lang.Object.class}
-    )
     public void test_addLjava_lang_Object() {
         AbstractCollection<Object> ac = new AbstractCollection<Object>() {
 
@@ -65,12 +53,6 @@
     /**
      * @tests java.util.AbstractCollection#addAll(java.util.Collection)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "addAll",
-        args = {java.util.Collection.class}
-    )
     public void test_addAllLjava_util_Collection() {
         final Collection<String> fixtures = Arrays.asList("0", "1", "2");
         AbstractCollection<String> ac = new AbstractCollection<String>() {
@@ -100,12 +82,6 @@
     /**
      * @tests java.util.AbstractCollection#containsAll(java.util.Collection)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "containsAll",
-        args = {java.util.Collection.class}
-    )
     public void test_containsAllLjava_util_Collection() {
         final Collection<String> fixtures = Arrays.asList("0", "1", "2");
         AbstractCollection<String> ac = new AbstractCollection<String>() {
@@ -135,12 +111,6 @@
     /**
      * @tests java.util.AbstractCollection#isEmpty()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "isEmpty",
-        args = {}
-    )
     public void test_isEmpty() {
         final boolean[] sizeCalled = new boolean[1];
         AbstractCollection<Object> ac = new AbstractCollection<Object>(){
@@ -162,12 +132,6 @@
     /**
      * @tests java.util.AbstractCollection#removeAll(java.util.Collection)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "removeAll",
-        args = {java.util.Collection.class}
-    )
     public void test_removeAllLjava_util_Collection() {
         final String[] removed = new String[3];
         AbstractCollection<String> ac = new AbstractCollection<String>() {
@@ -210,12 +174,6 @@
     /**
      * @tests java.util.AbstractCollection#retainAll(java.util.Collection)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "retainAll",
-        args = {java.util.Collection.class}
-    )
     public void test_retainAllLjava_util_Collection() {
         final String[] removed = new String[1];
         AbstractCollection<String> ac = new AbstractCollection<String>() {
@@ -254,12 +212,6 @@
     /**
      * @tests java.util.AbstractCollection#toArray()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toArray",
-        args = {}
-    )
     public void test_toArray() {
         AbstractCollection<String> ac = new AbstractCollection<String>() {
             @Override
@@ -300,12 +252,6 @@
     /**
      * @tests java.util.AbstractCollection#toArray(java.lang.Object[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toArray",
-        args = {java.lang.Object[].class}
-    )
     public void test_toArray$Ljava_lang_Object() {
         AbstractCollection<String> ac = new AbstractCollection<String>() {
             @Override
@@ -365,12 +311,6 @@
     /**
      * @tests java.util.AbstractCollection#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         // see HARMONY-1522
         // collection that returns null iterator(this is against the spec.)
@@ -396,128 +336,4 @@
         } catch (NullPointerException e) {
         }
     }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "AbstractCollection",
-        args = {}
-    )
-    public void test_Constructor() {
-        AbstractCollection<?> ac = new AbstractCollection<Object>() {
-            @Override
-            public Iterator<Object> iterator() {
-                return null;
-            }
-
-            @Override
-            public int size() {
-                return 0;
-            }
-        };
-        
-        assertNotNull(ac);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "clear",
-        args = {}
-    )
-    public void test_clear() {
-        AbstractCollection<?> ac = new AbstractCollection<Object>() {
-            @Override
-            public Iterator<Object> iterator() {
-                return new Iterator<Object>() {
-
-                    public boolean hasNext() {
-                        return false;
-                    }
-
-                    public Object next() {
-                        return null;
-                    }
-
-                    public void remove() {
-                    }
-                };
-            }
-
-            @Override
-            public int size() {
-                return 0;
-            }
-        };
-        
-        ac.clear();
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "contains",
-        args = {java.lang.Object.class}
-    )
-    public void test_containsLjava_lang_Object() {
-        AbstractCollection<?> ac = new AbstractCollection<Object>() {
-            @Override
-            public Iterator<Object> iterator() {
-                return new Iterator<Object>() {
-
-                    public boolean hasNext() {
-                        return false;
-                    }
-
-                    public Object next() {
-                        return null;
-                    }
-
-                    public void remove() {
-                    }
-                };
-            }
-
-            @Override
-            public int size() {
-                return 0;
-            }
-        };
-        
-        assertFalse(ac.contains(this));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Class is abstract. Functionality tested in subclasses for example in java.util.Vector.",
-        method = "remove",
-        args = {java.lang.Object.class}
-    )
-    public void test_removeLjava_lang_Object() {
-        AbstractCollection<?> ac = new AbstractCollection<Object>() {
-            @Override
-            public Iterator<Object> iterator() {
-                return new Iterator<Object>() {
-
-                    public boolean hasNext() {
-                        return false;
-                    }
-
-                    public Object next() {
-                        return null;
-                    }
-
-                    public void remove() {
-                    }
-                };
-            }
-
-            @Override
-            public int size() {
-                return 0;
-            }
-        };
-        
-        assertFalse(ac.remove(this));
-    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AllTests.java
index 2bfc7bf..88c4fad 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/AllTests.java
@@ -30,7 +30,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.util");
+        TestSuite suite = new TestSuite("Tests for java.util");
 
         suite.addTestSuite(AbstractCollectionTest.class);
         suite.addTestSuite(AbstractMapTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArrayListTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArrayListTest.java
index ab29579..7c58d45 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArrayListTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArrayListTest.java
@@ -1,24 +1,343 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
 
-@TestTargetClass(ArrayList.class) 
-public class ArrayListTest extends TestCase {
+import tests.support.Support_ListTest;
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Regression test.",
-        method = "add",
-        args = {java.lang.Object.class}
-    )
+public class ArrayListTest extends junit.framework.TestCase {
+
+    List alist;
+
+    static Object[] objArray;
+    {
+        objArray = new Object[100];
+        for (int i = 0; i < objArray.length; i++)
+            objArray[i] = new Integer(i);
+    }
+
+    /**
+     * @tests java.util.ArrayList#ArrayList()
+     */
+    public void test_Constructor() {
+        // Test for method java.util.ArrayList()
+        new Support_ListTest("", alist).runTest();
+
+        ArrayList subList = new ArrayList();
+        for (int i = -50; i < 150; i++)
+            subList.add(new Integer(i));
+        new Support_ListTest("", subList.subList(50, 150)).runTest();
+    }
+
+    /**
+     * @tests java.util.ArrayList#ArrayList(int)
+     */
+    public void test_ConstructorI() {
+        // Test for method java.util.ArrayList(int)
+        ArrayList al = new ArrayList(5);
+        assertEquals("Incorrect arrayList created", 0, al.size());
+        
+        al = new ArrayList(0);
+        assertEquals("Incorrect arrayList created", 0, al.size());
+        
+        try {
+            al = new ArrayList(-1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Excepted
+        }
+    }
+
+    /**
+     * @tests java.util.ArrayList#ArrayList(java.util.Collection)
+     */
+    public void test_ConstructorLjava_util_Collection() {
+        // Test for method java.util.ArrayList(java.util.Collection)
+        ArrayList al = new ArrayList(Arrays.asList(objArray));
+        assertTrue("arrayList created from collection has incorrect size", al
+                .size() == objArray.length);
+        for (int counter = 0; counter < objArray.length; counter++)
+            assertTrue(
+                    "arrayList created from collection has incorrect elements",
+                    al.get(counter) == objArray[counter]);
+
+    }
+
+    public void testConstructorWithConcurrentCollection() {
+        Collection<String> collection = shrinksOnSize("A", "B", "C", "D");
+        ArrayList<String> list = new ArrayList<String>(collection);
+        assertFalse(list.contains(null));
+    }
+
+    /**
+     * @tests java.util.ArrayList#add(int, java.lang.Object)
+     */
+    public void test_addILjava_lang_Object() {
+        // Test for method void java.util.ArrayList.add(int, java.lang.Object)
+        Object o;
+        alist.add(50, o = new Object());
+        assertTrue("Failed to add Object", alist.get(50) == o);
+        assertTrue("Failed to fix up list after insert",
+                alist.get(51) == objArray[50]
+                        && (alist.get(52) == objArray[51]));
+        Object oldItem = alist.get(25);
+        alist.add(25, null);
+        assertNull("Should have returned null", alist.get(25));
+        assertTrue("Should have returned the old item from slot 25", alist
+                .get(26) == oldItem);
+        
+        alist.add(0, o = new Object());
+        assertEquals("Failed to add Object", alist.get(0), o);
+        assertEquals(alist.get(1), objArray[0]);
+        assertEquals(alist.get(2), objArray[1]);
+
+        oldItem = alist.get(0);
+        alist.add(0, null);
+        assertNull("Should have returned null", alist.get(0));
+        assertEquals("Should have returned the old item from slot 0", alist
+                .get(1), oldItem);
+
+        try {
+            alist.add(-1, new Object());
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            alist.add(-1, null);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            alist.add(alist.size() + 1, new Object());
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            alist.add(alist.size() + 1, null);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+    }
+
+    /**
+     * @tests java.util.ArrayList#add(int, java.lang.Object)
+     */
+    public void test_addILjava_lang_Object_2() {
+        Object o = new Object();
+        int size = alist.size();
+        alist.add(size, o);
+        assertEquals("Failed to add Object", alist.get(size), o);
+        assertEquals(alist.get(size - 2), objArray[size - 2]);
+        assertEquals(alist.get(size - 1), objArray[size - 1]);
+
+        alist.remove(size);
+
+        size = alist.size();
+        alist.add(size, null);
+        assertNull("Should have returned null", alist.get(size));
+        assertEquals(alist.get(size - 2), objArray[size - 2]);
+        assertEquals(alist.get(size - 1), objArray[size - 1]);
+    }
+    
+    /**
+     * @tests java.util.ArrayList#add(java.lang.Object)
+     */
+    public void test_addLjava_lang_Object() {
+        // Test for method boolean java.util.ArrayList.add(java.lang.Object)
+        Object o = new Object();
+        alist.add(o);
+        assertTrue("Failed to add Object", alist.get(alist.size() - 1) == o);
+        alist.add(null);
+        assertNull("Failed to add null", alist.get(alist.size() - 1));
+    }
+
+    /**
+     * @tests java.util.ArrayList#addAll(int, java.util.Collection)
+     */
+    public void test_addAllILjava_util_Collection() {
+        // Test for method boolean java.util.ArrayList.addAll(int,
+        // java.util.Collection)
+        alist.addAll(50, alist);
+        assertEquals("Returned incorrect size after adding to existing list",
+                200, alist.size());
+        for (int i = 0; i < 50; i++)
+            assertTrue("Manipulated elements < index",
+                    alist.get(i) == objArray[i]);
+        for (int i = 0; i >= 50 && (i < 150); i++)
+            assertTrue("Failed to ad elements properly",
+                    alist.get(i) == objArray[i - 50]);
+        for (int i = 0; i >= 150 && (i < 200); i++)
+            assertTrue("Failed to ad elements properly",
+                    alist.get(i) == objArray[i - 100]);
+        ArrayList listWithNulls = new ArrayList();
+        listWithNulls.add(null);
+        listWithNulls.add(null);
+        listWithNulls.add("yoink");
+        listWithNulls.add("kazoo");
+        listWithNulls.add(null);
+        alist.addAll(100, listWithNulls);
+        assertTrue("Incorrect size: " + alist.size(), alist.size() == 205);
+        assertNull("Item at slot 100 should be null", alist.get(100));
+        assertNull("Item at slot 101 should be null", alist.get(101));
+        assertEquals("Item at slot 102 should be 'yoink'", "yoink", alist
+                .get(102));
+        assertEquals("Item at slot 103 should be 'kazoo'", "kazoo", alist
+                .get(103));
+        assertNull("Item at slot 104 should be null", alist.get(104));
+        alist.addAll(205, listWithNulls);
+        assertTrue("Incorrect size2: " + alist.size(), alist.size() == 210);
+    }
+
+    /**
+     * @tests java.util.ArrayList#addAll(int, java.util.Collection)
+     */
+    @SuppressWarnings("unchecked")
+    public void test_addAllILjava_util_Collection_2() {
+        // Regression for HARMONY-467
+        ArrayList obj = new ArrayList();
+        try {
+            obj.addAll((int) -1, (Collection) null);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        // Regression for HARMONY-5705
+        String[] data = new String[] { "1", "2", "3", "4", "5", "6", "7", "8" };
+        ArrayList list1 = new ArrayList();
+        ArrayList list2 = new ArrayList();
+        for (String d : data) {
+            list1.add(d);
+            list2.add(d);
+            list2.add(d);
+        }
+        while (list1.size() > 0)
+            list1.remove(0);
+        list1.addAll(list2);
+        assertTrue("The object list is not the same as original list", list1
+                .containsAll(list2)
+                && list2.containsAll(list1));
+
+        obj = new ArrayList();
+        for (int i = 0; i < 100; i++) {
+            if (list1.size() > 0) {
+                obj.removeAll(list1);
+                obj.addAll(list1);
+            }
+        }
+        assertTrue("The object list is not the same as original list", obj
+                .containsAll(list1)
+                && list1.containsAll(obj));
+
+        // Regression for Harmony-5799
+        list1 = new ArrayList();
+        list2 = new ArrayList();
+        int location = 2;
+
+        String[] strings = { "0", "1", "2", "3", "4", "5", "6" };
+        int[] integers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+        for (int i = 0; i < 7; i++) {
+            list1.add(strings[i]);
+        }
+        for (int i = 0; i < 10; i++) {
+            list2.add(integers[i]);
+        }
+        list1.remove(location);
+        list1.addAll(location, list2);
+
+        // Inserted elements should be equal to integers array
+        for (int i = 0; i < integers.length; i++) {
+            assertEquals(integers[i], list1.get(location + i));
+        }
+        // Elements after inserted location should
+        // be equals to related elements in strings array
+        for (int i = location + 1; i < strings.length; i++) {
+            assertEquals(strings[i], list1.get(i + integers.length - 1));
+        }
+    }
+    
+    /**
+     * @tests java.util.ArrayList#addAll(int, java.util.Collection)
+     */
+    public void test_addAllILjava_util_Collection_3() {
+        ArrayList obj = new ArrayList();
+        obj.addAll(0, obj);
+        obj.addAll(obj.size(), obj);
+        try {
+            obj.addAll(-1, obj);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            obj.addAll(obj.size() + 1, obj);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            obj.addAll(0, null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Excepted
+        }
+
+        try {
+            obj.addAll(obj.size() + 1, null);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            obj.addAll((int) -1, (Collection) null);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+    }
+
     public void test_addAllCollectionOfQextendsE() {
         // Regression for HARMONY-539
         // https://issues.apache.org/jira/browse/HARMONY-539
@@ -35,23 +354,652 @@
         assertEquals("d", blist.get(2));
     }
 
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Regression test.",
-            method = "addAll",
-            args = {java.util.Collection.class}
-    )
-    public void test_growForInsert() {
-        ArrayList<Integer> arrayList = new ArrayList<Integer>();
-        arrayList.addAll(0, Arrays.asList(1, 2));
-        arrayList.addAll(2, Arrays.asList(13));
-        arrayList.addAll(0, Arrays.asList(0));
-        arrayList.addAll(3, Arrays.asList(11, 12));
-        arrayList.addAll(6, Arrays.asList(22, 23, 24, 25, 26, 27, 28, 29));
-        arrayList.addAll(6, Arrays.asList(14, 15, 16, 17, 18, 19, 20, 21));
-        arrayList.addAll(3, Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10));
-        assertEquals(Arrays.asList(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),
-                arrayList);
+    /**
+     * @tests java.util.ArrayList#addAll(java.util.Collection)
+     */
+    public void test_addAllLjava_util_Collection() {
+        // Test for method boolean
+        // java.util.ArrayList.addAll(java.util.Collection)
+        List l = new ArrayList();
+        l.addAll(alist);
+        for (int i = 0; i < alist.size(); i++)
+            assertTrue("Failed to add elements properly", l.get(i).equals(
+                    alist.get(i)));
+        alist.addAll(alist);
+        assertEquals("Returned incorrect size after adding to existing list",
+                200, alist.size());
+        for (int i = 0; i < 100; i++) {
+            assertTrue("Added to list in incorrect order", alist.get(i).equals(
+                    l.get(i)));
+            assertTrue("Failed to add to existing list", alist.get(i + 100)
+                    .equals(l.get(i)));
+        }
+        Set setWithNulls = new HashSet();
+        setWithNulls.add(null);
+        setWithNulls.add(null);
+        setWithNulls.add("yoink");
+        setWithNulls.add("kazoo");
+        setWithNulls.add(null);
+        alist.addAll(100, setWithNulls);
+        Iterator i = setWithNulls.iterator();
+        assertTrue("Item at slot 100 is wrong: " + alist.get(100), alist
+                .get(100) == i.next());
+        assertTrue("Item at slot 101 is wrong: " + alist.get(101), alist
+                .get(101) == i.next());
+        assertTrue("Item at slot 103 is wrong: " + alist.get(102), alist
+                .get(102) == i.next());
+
+        try {
+            alist.addAll(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Excepted
+        }
+        
+        // Regression test for Harmony-3481
+        ArrayList<Integer> originalList = new ArrayList<Integer>(12);
+        for (int j = 0; j < 12; j++) {
+            originalList.add(j);
+        }
+
+        originalList.remove(0);
+        originalList.remove(0);
+
+        ArrayList<Integer> additionalList = new ArrayList<Integer>(11);
+        for (int j = 0; j < 11; j++) {
+            additionalList.add(j);
+        }
+        assertTrue(originalList.addAll(additionalList));
+        assertEquals(21, originalList.size());
+
     }
-}
\ No newline at end of file
+
+        public void test_ArrayList_addAll_scenario1() {
+        ArrayList arrayListA = new ArrayList();
+        arrayListA.add(1);
+        ArrayList arrayListB = new ArrayList();
+        arrayListB.add(1);
+        arrayListA.addAll(1, arrayListB);
+        int size = arrayListA.size();
+        assertEquals(2, size);
+        for (int index = 0; index < size; index++) {
+            assertEquals(1, arrayListA.get(index));
+        }
+    }
+
+    public void test_ArrayList_addAll_scenario2() {
+        ArrayList arrayList = new ArrayList();
+        arrayList.add(1);
+        arrayList.addAll(1, arrayList);
+        int size = arrayList.size();
+        assertEquals(2, size);
+        for (int index = 0; index < size; index++) {
+            assertEquals(1, arrayList.get(index));
+        }
+    }
+        
+    // Regression test for HARMONY-5839
+    public void testaddAllHarmony5839() {
+        Collection coll = Arrays.asList(new String[] { "1", "2" });
+        List list = new ArrayList();
+        list.add("a");
+        list.add(0, "b");
+        list.add(0, "c");
+        list.add(0, "d");
+        list.add(0, "e");
+        list.add(0, "f");
+        list.add(0, "g");
+        list.add(0, "h");
+        list.add(0, "i");
+
+        list.addAll(6, coll);
+
+        assertEquals(11, list.size());
+        assertFalse(list.contains(null));
+    }
+
+    /**
+     * @tests java.util.ArrayList#clear()
+     */
+    public void test_clear() {
+        // Test for method void java.util.ArrayList.clear()
+        alist.clear();
+        assertEquals("List did not clear", 0, alist.size());
+        alist.add(null);
+        alist.add(null);
+        alist.add(null);
+        alist.add("bam");
+        alist.clear();
+        assertEquals("List with nulls did not clear", 0, alist.size());
+        /*
+         * for (int i = 0; i < alist.size(); i++) assertNull("Failed to clear
+         * list", alist.get(i));
+         */
+
+    }
+
+    /**
+     * @tests java.util.ArrayList#clone()
+     */
+    public void test_clone() {
+        // Test for method java.lang.Object java.util.ArrayList.clone()
+        ArrayList x = (ArrayList) (((ArrayList) (alist)).clone());
+        assertTrue("Cloned list was inequal to original", x.equals(alist));
+        for (int i = 0; i < alist.size(); i++)
+            assertTrue("Cloned list contains incorrect elements",
+                    alist.get(i) == x.get(i));
+
+        alist.add(null);
+        alist.add(25, null);
+        x = (ArrayList) (((ArrayList) (alist)).clone());
+        assertTrue("nulls test - Cloned list was inequal to original", x
+                .equals(alist));
+        for (int i = 0; i < alist.size(); i++)
+            assertTrue("nulls test - Cloned list contains incorrect elements",
+                    alist.get(i) == x.get(i));
+
+    }
+
+    /**
+     * @tests java.util.ArrayList#contains(java.lang.Object)
+     */
+    public void test_containsLjava_lang_Object() {
+        // Test for method boolean
+        // java.util.ArrayList.contains(java.lang.Object)
+        assertTrue("Returned false for valid element", alist
+                .contains(objArray[99]));
+        assertTrue("Returned false for equal element", alist
+                .contains(new Integer(8)));
+        assertTrue("Returned true for invalid element", !alist
+                .contains(new Object()));
+        assertTrue("Returned true for null but should have returned false",
+                !alist.contains(null));
+        alist.add(null);
+        assertTrue("Returned false for null but should have returned true",
+                alist.contains(null));
+    }
+
+    /**
+     * @tests java.util.ArrayList#ensureCapacity(int)
+     */
+    public void test_ensureCapacityI() {
+        // Test for method void java.util.ArrayList.ensureCapacity(int)
+        // TODO : There is no good way to test this as it only really impacts on
+        // the private implementation.
+
+        Object testObject = new Object();
+        int capacity = 20;
+        ArrayList al = new ArrayList(capacity);
+        int i;
+        for (i = 0; i < capacity / 2; i++) {
+            al.add(i, new Object());
+        }
+        al.add(i, testObject);
+        int location = al.indexOf(testObject);
+        al.ensureCapacity(capacity);
+        assertTrue("EnsureCapacity moved objects around in array1.",
+                location == al.indexOf(testObject));
+        al.remove(0);
+        al.ensureCapacity(capacity);
+        assertTrue("EnsureCapacity moved objects around in array2.",
+                --location == al.indexOf(testObject));
+        al.ensureCapacity(capacity + 2);
+        assertTrue("EnsureCapacity did not change location.", location == al
+                .indexOf(testObject));
+    }
+
+    /**
+     * @tests java.util.ArrayList#get(int)
+     */
+    public void test_getI() {
+        // Test for method java.lang.Object java.util.ArrayList.get(int)
+        assertTrue("Returned incorrect element", alist.get(22) == objArray[22]);
+        try {
+            alist.get(8765);
+            fail("Failed to throw expected exception for index > size");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+    }
+
+    /**
+     * @tests java.util.ArrayList#indexOf(java.lang.Object)
+     */
+    public void test_indexOfLjava_lang_Object() {
+        // Test for method int java.util.ArrayList.indexOf(java.lang.Object)
+        assertEquals("Returned incorrect index", 87, alist
+                .indexOf(objArray[87]));
+        assertEquals("Returned index for invalid Object", -1, alist
+                .indexOf(new Object()));
+        alist.add(25, null);
+        alist.add(50, null);
+        assertTrue("Wrong indexOf for null.  Wanted 25 got: "
+                + alist.indexOf(null), alist.indexOf(null) == 25);
+    }
+
+    /**
+     * @tests java.util.ArrayList#isEmpty()
+     */
+    public void test_isEmpty() {
+        // Test for method boolean java.util.ArrayList.isEmpty()
+        assertTrue("isEmpty returned false for new list", new ArrayList()
+                .isEmpty());
+        assertTrue("Returned true for existing list with elements", !alist
+                .isEmpty());
+    }
+
+    /**
+     * @tests java.util.ArrayList#lastIndexOf(java.lang.Object)
+     */
+    public void test_lastIndexOfLjava_lang_Object() {
+        // Test for method int java.util.ArrayList.lastIndexOf(java.lang.Object)
+        alist.add(new Integer(99));
+        assertEquals("Returned incorrect index", 100, alist
+                .lastIndexOf(objArray[99]));
+        assertEquals("Returned index for invalid Object", -1, alist
+                .lastIndexOf(new Object()));
+        alist.add(25, null);
+        alist.add(50, null);
+        assertTrue("Wrong lastIndexOf for null.  Wanted 50 got: "
+                + alist.lastIndexOf(null), alist.lastIndexOf(null) == 50);
+    }
+
+    /**
+     * @tests {@link java.util.ArrayList#removeRange(int, int)}
+     */
+    public void test_removeRange() {
+        MockArrayList mylist = new MockArrayList();
+        mylist.removeRange(0, 0);
+
+        try {
+            mylist.removeRange(0, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        int[] data = { 1, 2, 3 };
+        for (int i = 0; i < data.length; i++) {
+            mylist.add(i, data[i]);
+        }
+
+        mylist.removeRange(0, 1);
+        assertEquals(data[1], mylist.get(0));
+        assertEquals(data[2], mylist.get(1));
+
+        try {
+            mylist.removeRange(-1, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            mylist.removeRange(0, -1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            mylist.removeRange(1, 0);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            mylist.removeRange(2, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+    }
+    
+    /**
+     * @tests java.util.ArrayList#remove(int)
+     */
+    public void test_removeI() {
+        // Test for method java.lang.Object java.util.ArrayList.remove(int)
+        alist.remove(10);
+        assertEquals("Failed to remove element", -1, alist
+                .indexOf(objArray[10]));
+        try {
+            alist.remove(999);
+            fail("Failed to throw exception when index out of range");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        ArrayList myList = (ArrayList) (((ArrayList) (alist)).clone());
+        alist.add(25, null);
+        alist.add(50, null);
+        alist.remove(50);
+        alist.remove(25);
+        assertTrue("Removing nulls did not work", alist.equals(myList));
+
+        List list = new ArrayList(Arrays.asList(new String[] { "a", "b", "c",
+                "d", "e", "f", "g" }));
+        assertTrue("Removed wrong element 1", list.remove(0) == "a");
+        assertTrue("Removed wrong element 2", list.remove(4) == "f");
+        String[] result = new String[5];
+        list.toArray(result);
+        assertTrue("Removed wrong element 3", Arrays.equals(result,
+                new String[] { "b", "c", "d", "e", "g" }));
+
+        List l = new ArrayList(0);
+        l.add(new Object());
+        l.add(new Object());
+        l.remove(0);
+        l.remove(0);
+        try {
+            l.remove(-1);
+            fail("-1 should cause exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+        try {
+            l.remove(0);
+            fail("0 should case exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+    }
+
+    /**
+     * @tests java.util.ArrayList#set(int, java.lang.Object)
+     */
+    public void test_setILjava_lang_Object() {
+        // Test for method java.lang.Object java.util.ArrayList.set(int,
+        // java.lang.Object)
+        Object obj;
+        alist.set(65, obj = new Object());
+        assertTrue("Failed to set object", alist.get(65) == obj);
+        alist.set(50, null);
+        assertNull("Setting to null did not work", alist.get(50));
+        assertTrue("Setting increased the list's size to: " + alist.size(),
+                alist.size() == 100);
+        
+        obj = new Object();
+        alist.set(0, obj);
+        assertTrue("Failed to set object", alist.get(0) == obj);
+
+        try {
+            alist.set(-1, obj);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            alist.set(alist.size(), obj);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            alist.set(-1, null);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+
+        try {
+            alist.set(alist.size(), null);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Expected
+            assertNotNull(e.getMessage());
+        }
+    }
+
+    /**
+     * @tests java.util.ArrayList#size()
+     */
+    public void test_size() {
+        // Test for method int java.util.ArrayList.size()
+        assertEquals("Returned incorrect size for exiting list", 100, alist
+                .size());
+        assertEquals("Returned incorrect size for new list", 0, new ArrayList()
+                .size());
+    }
+
+    /**
+     * @tests java.util.AbstractCollection#toString()
+     */
+    public void test_toString() {
+        ArrayList l = new ArrayList(1);
+        l.add(l);
+        String result = l.toString();
+        assertTrue("should contain self ref", result.indexOf("(this") > -1);
+    }
+    
+    /**
+     * @tests java.util.ArrayList#toArray()
+     */
+    public void test_toArray() {
+        // Test for method java.lang.Object [] java.util.ArrayList.toArray()
+        alist.set(25, null);
+        alist.set(75, null);
+        Object[] obj = alist.toArray();
+        assertEquals("Returned array of incorrect size", objArray.length,
+                obj.length);
+
+        for (int i = 0; i < obj.length; i++) {
+            if ((i == 25) || (i == 75))
+                assertNull("Should be null at: " + i + " but instead got: "
+                        + obj[i], obj[i]);
+            else
+                assertTrue("Returned incorrect array: " + i,
+                        obj[i] == objArray[i]);
+        }
+
+    }
+
+    /**
+     * @tests java.util.ArrayList#toArray(java.lang.Object[])
+     */
+    public void test_toArray$Ljava_lang_Object() {
+        // Test for method java.lang.Object []
+        // java.util.ArrayList.toArray(java.lang.Object [])
+        alist.set(25, null);
+        alist.set(75, null);
+        Integer[] argArray = new Integer[100];
+        Object[] retArray;
+        retArray = alist.toArray(argArray);
+        assertTrue("Returned different array than passed", retArray == argArray);
+        argArray = new Integer[1000];
+        retArray = alist.toArray(argArray);
+        assertNull("Failed to set first extra element to null", argArray[alist
+                .size()]);
+        for (int i = 0; i < 100; i++) {
+            if ((i == 25) || (i == 75))
+                assertNull("Should be null: " + i, retArray[i]);
+            else
+                assertTrue("Returned incorrect array: " + i,
+                        retArray[i] == objArray[i]);
+        }
+    }
+
+    /**
+     * @tests java.util.ArrayList#trimToSize()
+     */
+    public void test_trimToSize() {
+        // Test for method void java.util.ArrayList.trimToSize()
+        for (int i = 99; i > 24; i--)
+            alist.remove(i);
+        ((ArrayList) alist).trimToSize();
+        assertEquals("Returned incorrect size after trim", 25, alist.size());
+        for (int i = 0; i < alist.size(); i++)
+            assertTrue("Trimmed list contained incorrect elements", alist
+                    .get(i) == objArray[i]);
+        Vector v = new Vector();
+        v.add("a");
+        ArrayList al = new ArrayList(v);
+        Iterator it = al.iterator();
+        al.trimToSize();
+        try {
+            it.next();
+            fail("should throw a ConcurrentModificationException");
+        } catch (ConcurrentModificationException ioobe) {
+            // expected
+        }
+    }
+
+    /**
+     * @test java.util.ArrayList#addAll(int, Collection)
+     */
+    public void test_addAll() {
+        ArrayList list = new ArrayList();
+        list.add("one");
+        list.add("two");
+        assertEquals(2, list.size());
+
+        list.remove(0);
+        assertEquals(1, list.size());
+
+        ArrayList collection = new ArrayList();
+        collection.add("1");
+        collection.add("2");
+        collection.add("3");
+        assertEquals(3, collection.size());
+
+        list.addAll(0, collection);
+        assertEquals(4, list.size());
+
+        list.remove(0);
+        list.remove(0);
+        assertEquals(2, list.size());
+
+        collection.add("4");
+        collection.add("5");
+        collection.add("6");
+        collection.add("7");
+        collection.add("8");
+        collection.add("9");
+        collection.add("10");
+        collection.add("11");
+        collection.add("12");
+
+        assertEquals(12, collection.size());
+
+        list.addAll(0, collection);
+        assertEquals(14, list.size());
+    }
+
+    public void testAddAllWithConcurrentCollection() {
+        ArrayList<String> list = new ArrayList<String>();
+        list.addAll(shrinksOnSize("A", "B", "C", "D"));
+        assertFalse(list.contains(null));
+    }
+
+    public void testAddAllAtPositionWithConcurrentCollection() {
+        ArrayList<String> list = new ArrayList<String>(
+                Arrays.asList("A", "B", "C", "D"));
+
+        list.addAll(3, shrinksOnSize("E", "F", "G", "H"));
+        assertFalse(list.contains(null));
+    }
+
+    public void test_override_size() throws Exception {
+        ArrayList testlist = new MockArrayList();
+        // though size is overriden, it should passed without exception
+        testlist.add("test_0");
+        testlist.add("test_1");
+        testlist.add("test_2");
+        testlist.add(1, "test_3");
+        testlist.get(1);
+        testlist.remove(2);
+        testlist.set(1, "test_4");
+    }
+
+    public static class ArrayListExtend extends ArrayList {
+
+        private int size = 0;
+
+        public ArrayListExtend() {
+            super(10);
+        }
+
+        public boolean add(Object o) {
+            size++;
+            return super.add(o);
+        }
+
+        public int size() {
+            return size;
+        }
+    }
+
+    public class MockArrayList extends ArrayList {
+        public int size() {
+            return 0;
+        }
+        
+        public void removeRange(int start, int end) {
+            super.removeRange(start, end);
+        }
+    }
+
+    public void test_subclassing() {
+        ArrayListExtend a = new ArrayListExtend();
+        /*
+         * Regression test for subclasses that override size() (which used to
+         * cause an exception when growing 'a').
+         */
+        for (int i = 0; i < 100; i++) {
+            a.add(new Object());
+        }
+    }
+
+    /**
+     * Sets up the fixture, for example, open a network connection. This method
+     * is called before a test is executed.
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        alist = new ArrayList();
+        for (int i = 0; i < objArray.length; i++)
+            alist.add(objArray[i]);
+    }
+
+    /**
+     * Returns a collection that emulates another thread calling remove() each
+     * time the current thread calls size().
+     */
+    private <T> Collection<T> shrinksOnSize(T... elements) {
+        return new HashSet<T>(Arrays.asList(elements)) {
+            boolean shrink = true;
+
+            @Override
+            public int size() {
+                int result = super.size();
+                if (shrink) {
+                    Iterator<T> i = iterator();
+                    i.next();
+                    i.remove();
+                }
+                return result;
+            }
+
+            @Override
+            public Object[] toArray() {
+                shrink = false;
+                return super.toArray();
+            }
+        };
+    }
+}
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArraysTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArraysTest.java
index b26dd43..dafaaea 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArraysTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/ArraysTest.java
@@ -1,621 +1,3520 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-import java.io.Serializable;
+import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.Date;
+import java.util.LinkedList;
 import java.util.List;
-import java.util.RandomAccess;
 
-import org.apache.harmony.testframework.serialization.SerializationTest;
+import tests.support.Support_UnmodifiableCollectionTest;
 
-@TestTargetClass(Arrays.class) 
-public class ArraysTest extends TestCase {
+public class ArraysTest extends junit.framework.TestCase {
+
+	public static class ReversedIntegerComparator implements Comparator {
+		public int compare(Object o1, Object o2) {
+			return -(((Integer) o1).compareTo((Integer) o2));
+		}
+
+		public boolean equals(Object o1, Object o2) {
+			return ((Integer) o1).compareTo((Integer) o2) == 0;
+		}
+	}
+
+    static class MockComparable implements Comparable{
+        public int compareTo(Object o) {
+            return 0;
+        }
+    }
+    
+	final static int arraySize = 100;
+
+	static Object[] objArray;
+
+	static boolean[] booleanArray;
+
+	static byte[] byteArray;
+
+	static char[] charArray;
+
+	static double[] doubleArray;
+
+	static float[] floatArray;
+
+	static int[] intArray;
+
+	static long[] longArray;
+
+	static Object[] objectArray;
+
+	static short[] shortArray;
+	{
+		objArray = new Object[arraySize];
+		for (int i = 0; i < objArray.length; i++)
+			objArray[i] = new Integer(i);
+	}
+
+	/**
+	 * @tests java.util.Arrays#asList(java.lang.Object[])
+	 */
+	public void test_asList$Ljava_lang_Object() {
+		// Test for method java.util.List
+		// java.util.Arrays.asList(java.lang.Object [])
+		List convertedList = Arrays.asList(objectArray);
+		for (int counter = 0; counter < arraySize; counter++) {
+			assertTrue(
+					"Array and List converted from array do not contain identical elements",
+					convertedList.get(counter) == objectArray[counter]);
+		}
+		convertedList.set(50, new Integer(1000));
+		assertTrue("set/get did not work on coverted list", convertedList.get(
+				50).equals(new Integer(1000)));
+		convertedList.set(50, new Integer(50));
+		new Support_UnmodifiableCollectionTest("", convertedList).runTest();
+
+		Object[] myArray = (Object[]) (objectArray.clone());
+		myArray[30] = null;
+		myArray[60] = null;
+		convertedList = Arrays.asList(myArray);
+		for (int counter = 0; counter < arraySize; counter++) {
+			assertTrue(
+					"Array and List converted from array do not contain identical elements",
+					convertedList.get(counter) == myArray[counter]);
+		}
+
+		try {
+			Arrays.asList((Object[])null);
+			fail("asList with null arg didn't throw NPE");
+		} catch (NullPointerException e) {
+			// Expected
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(byte[], byte)
+	 */
+	public void test_binarySearch$BB() {
+		// Test for method int java.util.Arrays.binarySearch(byte [], byte)
+		for (byte counter = 0; counter < arraySize; counter++)
+			assertTrue("Binary search on byte[] answered incorrect position",
+					Arrays.binarySearch(byteArray, counter) == counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(intArray, (byte) -1));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(intArray, (byte) arraySize) == -(arraySize + 1));
+		for (byte counter = 0; counter < arraySize; counter++)
+			byteArray[counter] -= 50;
+		for (byte counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on byte[] involving negative numbers answered incorrect position",
+					Arrays.binarySearch(byteArray, (byte) (counter - 50)) == counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(char[], char)
+	 */
+	public void test_binarySearch$CC() {
+		// Test for method int java.util.Arrays.binarySearch(char [], char)
+		for (char counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on char[] answered incorrect position",
+					Arrays.binarySearch(charArray, (char) (counter + 1)) == counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(charArray, '\u0000'));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(charArray, (char) (arraySize + 1)) == -(arraySize + 1));
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(double[], double)
+	 */
+	public void test_binarySearch$DD() {
+		// Test for method int java.util.Arrays.binarySearch(double [], double)
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on double[] answered incorrect position",
+					Arrays.binarySearch(doubleArray, (double) counter) == (double) counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(doubleArray, (double) -1));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(doubleArray, (double) arraySize) == -(arraySize + 1));
+		for (int counter = 0; counter < arraySize; counter++)
+			doubleArray[counter] -= (double) 50;
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on double[] involving negative numbers answered incorrect position",
+					Arrays.binarySearch(doubleArray, (double) (counter - 50)) == (double) counter);
+
+		double[] specials = new double[] { Double.NEGATIVE_INFINITY,
+				-Double.MAX_VALUE, -2d, -Double.MIN_VALUE, -0d, 0d,
+				Double.MIN_VALUE, 2d, Double.MAX_VALUE,
+				Double.POSITIVE_INFINITY, Double.NaN };
+		for (int i = 0; i < specials.length; i++) {
+			int result = Arrays.binarySearch(specials, specials[i]);
+			assertTrue(specials[i] + " invalid: " + result, result == i);
+		}
+		assertEquals("-1d", -4, Arrays.binarySearch(specials, -1d));
+		assertEquals("1d", -8, Arrays.binarySearch(specials, 1d));
+
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(float[], float)
+	 */
+	public void test_binarySearch$FF() {
+		// Test for method int java.util.Arrays.binarySearch(float [], float)
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on float[] answered incorrect position",
+					Arrays.binarySearch(floatArray, (float) counter) == (float) counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(floatArray, (float) -1));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(floatArray, (float) arraySize) == -(arraySize + 1));
+		for (int counter = 0; counter < arraySize; counter++)
+			floatArray[counter] -= (float) 50;
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on float[] involving negative numbers answered incorrect position",
+					Arrays.binarySearch(floatArray, (float) counter - 50) == (float) counter);
+
+		float[] specials = new float[] { Float.NEGATIVE_INFINITY,
+				-Float.MAX_VALUE, -2f, -Float.MIN_VALUE, -0f, 0f,
+				Float.MIN_VALUE, 2f, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
+				Float.NaN };
+		for (int i = 0; i < specials.length; i++) {
+			int result = Arrays.binarySearch(specials, specials[i]);
+			assertTrue(specials[i] + " invalid: " + result, result == i);
+		}
+		assertEquals("-1f", -4, Arrays.binarySearch(specials, -1f));
+		assertEquals("1f", -8, Arrays.binarySearch(specials, 1f));
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(int[], int)
+	 */
+	public void test_binarySearch$II() {
+		// Test for method int java.util.Arrays.binarySearch(int [], int)
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Binary search on int[] answered incorrect position",
+					Arrays.binarySearch(intArray, counter) == counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(intArray, -1));
+		assertTrue("Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(intArray, arraySize) == -(arraySize + 1));
+		for (int counter = 0; counter < arraySize; counter++)
+			intArray[counter] -= 50;
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on int[] involving negative numbers answered incorrect position",
+					Arrays.binarySearch(intArray, counter - 50) == counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(long[], long)
+	 */
+	public void test_binarySearch$JJ() {
+		// Test for method int java.util.Arrays.binarySearch(long [], long)
+		for (long counter = 0; counter < arraySize; counter++)
+			assertTrue("Binary search on long[] answered incorrect position",
+					Arrays.binarySearch(longArray, counter) == counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(longArray, (long) -1));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(longArray, (long) arraySize) == -(arraySize + 1));
+		for (long counter = 0; counter < arraySize; counter++)
+			longArray[(int) counter] -= (long) 50;
+		for (long counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on long[] involving negative numbers answered incorrect position",
+					Arrays.binarySearch(longArray, counter - (long) 50) == counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(java.lang.Object[],
+	 *        java.lang.Object)
+	 */
+	public void test_binarySearch$Ljava_lang_ObjectLjava_lang_Object() {
+		// Test for method int java.util.Arrays.binarySearch(java.lang.Object
+		// [], java.lang.Object)
+		assertEquals(
+				"Binary search succeeded for non-comparable value in empty array",
+				-1, Arrays.binarySearch(new Object[] {}, new Object()));
+		assertEquals(
+				"Binary search succeeded for comparable value in empty array",
+				-1, Arrays.binarySearch(new Object[] {}, new Integer(-1)));
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on Object[] answered incorrect position",
+					Arrays.binarySearch(objectArray, objArray[counter]) == counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(objectArray, new Integer(-1)));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(objectArray, new Integer(arraySize)) == -(arraySize + 1));
+        
+        Object object = new Object();
+        Object[] objects = new MockComparable[] { new MockComparable() };
+        assertEquals("Should always return 0", 0, Arrays.binarySearch(objects, object));
+
+        Object[] string_objects = new String[] { "one" };
+        try {
+            Arrays.binarySearch(string_objects, object);
+            fail("No expected ClassCastException");
+        } catch (ClassCastException e) {
+            // Expected
+        }
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(java.lang.Object[],
+	 *        java.lang.Object, java.util.Comparator)
+	 */
+	public void test_binarySearch$Ljava_lang_ObjectLjava_lang_ObjectLjava_util_Comparator() {
+		// Test for method int java.util.Arrays.binarySearch(java.lang.Object
+		// [], java.lang.Object, java.util.Comparator)
+		Comparator comp = new ReversedIntegerComparator();
+		for (int counter = 0; counter < arraySize; counter++)
+			objectArray[counter] = objArray[arraySize - counter - 1];
+		assertTrue(
+				"Binary search succeeded for value not present in array 1",
+				Arrays.binarySearch(objectArray, new Integer(-1), comp) == -(arraySize + 1));
+		assertEquals("Binary search succeeded for value not present in array 2",
+				-1, Arrays.binarySearch(objectArray, new Integer(arraySize), comp));
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on Object[] with custom comparator answered incorrect position",
+					Arrays.binarySearch(objectArray, objArray[counter], comp) == arraySize
+							- counter - 1);
+	}
+
+	/**
+	 * @tests java.util.Arrays#binarySearch(short[], short)
+	 */
+	public void test_binarySearch$SS() {
+		// Test for method int java.util.Arrays.binarySearch(short [], short)
+		for (short counter = 0; counter < arraySize; counter++)
+			assertTrue("Binary search on short[] answered incorrect position",
+					Arrays.binarySearch(shortArray, counter) == counter);
+		assertEquals("Binary search succeeded for value not present in array 1",
+				-1, Arrays.binarySearch(intArray, (short) -1));
+		assertTrue(
+				"Binary search succeeded for value not present in array 2",
+				Arrays.binarySearch(intArray, (short) arraySize) == -(arraySize + 1));
+		for (short counter = 0; counter < arraySize; counter++)
+			shortArray[counter] -= 50;
+		for (short counter = 0; counter < arraySize; counter++)
+			assertTrue(
+					"Binary search on short[] involving negative numbers answered incorrect position",
+					Arrays.binarySearch(shortArray, (short) (counter - 50)) == counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(byte[], byte)
+	 */
+	public void test_fill$BB() {
+		// Test for method void java.util.Arrays.fill(byte [], byte)
+
+		byte d[] = new byte[1000];
+		Arrays.fill(d, Byte.MAX_VALUE);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill byte array correctly",
+					d[i] == Byte.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(byte[], int, int, byte)
+	 */
+	public void test_fill$BIIB() {
+		// Test for method void java.util.Arrays.fill(byte [], int, int, byte)
+		byte val = Byte.MAX_VALUE;
+		byte d[] = new byte[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill byte array correctly", d[i] == val);
+
+		int result;
+		try {
+			Arrays.fill(new byte[2], 2, 1, (byte) 27);
+			result = 0;
+		} catch (ArrayIndexOutOfBoundsException e) {
+			result = 1;
+		} catch (IllegalArgumentException e) {
+			result = 2;
+		}
+		assertEquals("Wrong exception1", 2, result);
+		try {
+			Arrays.fill(new byte[2], -1, 1, (byte) 27);
+			result = 0;
+		} catch (ArrayIndexOutOfBoundsException e) {
+			result = 1;
+		} catch (IllegalArgumentException e) {
+			result = 2;
+		}
+		assertEquals("Wrong exception2", 1, result);
+		try {
+			Arrays.fill(new byte[2], 1, 4, (byte) 27);
+			result = 0;
+		} catch (ArrayIndexOutOfBoundsException e) {
+			result = 1;
+		} catch (IllegalArgumentException e) {
+			result = 2;
+		}
+		assertEquals("Wrong exception", 1, result);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(short[], short)
+	 */
+	public void test_fill$SS() {
+		// Test for method void java.util.Arrays.fill(short [], short)
+
+		short d[] = new short[1000];
+		Arrays.fill(d, Short.MAX_VALUE);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill short array correctly",
+					d[i] == Short.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(short[], int, int, short)
+	 */
+	public void test_fill$SIIS() {
+		// Test for method void java.util.Arrays.fill(short [], int, int, short)
+		short val = Short.MAX_VALUE;
+		short d[] = new short[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill short array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(char[], char)
+	 */
+	public void test_fill$CC() {
+		// Test for method void java.util.Arrays.fill(char [], char)
+
+		char d[] = new char[1000];
+		Arrays.fill(d, 'V');
+		for (int i = 0; i < d.length; i++)
+			assertEquals("Failed to fill char array correctly", 'V', d[i]);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(char[], int, int, char)
+	 */
+	public void test_fill$CIIC() {
+		// Test for method void java.util.Arrays.fill(char [], int, int, char)
+		char val = 'T';
+		char d[] = new char[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill char array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(int[], int)
+	 */
+	public void test_fill$II() {
+		// Test for method void java.util.Arrays.fill(int [], int)
+
+		int d[] = new int[1000];
+		Arrays.fill(d, Integer.MAX_VALUE);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill int array correctly",
+					d[i] == Integer.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(int[], int, int, int)
+	 */
+	public void test_fill$IIII() {
+		// Test for method void java.util.Arrays.fill(int [], int, int, int)
+		int val = Integer.MAX_VALUE;
+		int d[] = new int[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill int array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(long[], long)
+	 */
+	public void test_fill$JJ() {
+		// Test for method void java.util.Arrays.fill(long [], long)
+
+		long d[] = new long[1000];
+		Arrays.fill(d, Long.MAX_VALUE);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill long array correctly",
+					d[i] == Long.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(long[], int, int, long)
+	 */
+	public void test_fill$JIIJ() {
+		// Test for method void java.util.Arrays.fill(long [], int, int, long)
+		long d[] = new long[1000];
+		Arrays.fill(d, 400, d.length, Long.MAX_VALUE);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == Long.MAX_VALUE));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill long array correctly",
+					d[i] == Long.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(float[], float)
+	 */
+	public void test_fill$FF() {
+		// Test for method void java.util.Arrays.fill(float [], float)
+		float d[] = new float[1000];
+		Arrays.fill(d, Float.MAX_VALUE);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill float array correctly",
+					d[i] == Float.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(float[], int, int, float)
+	 */
+	public void test_fill$FIIF() {
+		// Test for method void java.util.Arrays.fill(float [], int, int, float)
+		float val = Float.MAX_VALUE;
+		float d[] = new float[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill float array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(double[], double)
+	 */
+	public void test_fill$DD() {
+		// Test for method void java.util.Arrays.fill(double [], double)
+
+		double d[] = new double[1000];
+		Arrays.fill(d, Double.MAX_VALUE);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill double array correctly",
+					d[i] == Double.MAX_VALUE);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(double[], int, int, double)
+	 */
+	public void test_fill$DIID() {
+		// Test for method void java.util.Arrays.fill(double [], int, int,
+		// double)
+		double val = Double.MAX_VALUE;
+		double d[] = new double[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill double array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(boolean[], boolean)
+	 */
+	public void test_fill$ZZ() {
+		// Test for method void java.util.Arrays.fill(boolean [], boolean)
+
+		boolean d[] = new boolean[1000];
+		Arrays.fill(d, true);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill boolean array correctly", d[i]);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(boolean[], int, int, boolean)
+	 */
+	public void test_fill$ZIIZ() {
+		// Test for method void java.util.Arrays.fill(boolean [], int, int,
+		// boolean)
+		boolean val = true;
+		boolean d[] = new boolean[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill boolean array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(java.lang.Object[], java.lang.Object)
+	 */
+	public void test_fill$Ljava_lang_ObjectLjava_lang_Object() {
+		// Test for method void java.util.Arrays.fill(java.lang.Object [],
+		// java.lang.Object)
+		Object val = new Object();
+		Object d[] = new Object[1000];
+		Arrays.fill(d, 0, d.length, val);
+		for (int i = 0; i < d.length; i++)
+			assertTrue("Failed to fill Object array correctly", d[i] == val);
+	}
+
+	/**
+	 * @tests java.util.Arrays#fill(java.lang.Object[], int, int,
+	 *        java.lang.Object)
+	 */
+	public void test_fill$Ljava_lang_ObjectIILjava_lang_Object() {
+		// Test for method void java.util.Arrays.fill(java.lang.Object [], int,
+		// int, java.lang.Object)
+		Object val = new Object();
+		Object d[] = new Object[1000];
+		Arrays.fill(d, 400, d.length, val);
+		for (int i = 0; i < 400; i++)
+			assertTrue("Filled elements not in range", !(d[i] == val));
+		for (int i = 400; i < d.length; i++)
+			assertTrue("Failed to fill Object array correctly", d[i] == val);
+
+		Arrays.fill(d, 400, d.length, null);
+		for (int i = 400; i < d.length; i++)
+			assertNull("Failed to fill Object array correctly with nulls",
+					d[i]);
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(byte[], byte[])
+	 */
+	public void test_equals$B$B() {
+		// Test for method boolean java.util.Arrays.equals(byte [], byte [])
+		byte d[] = new byte[1000];
+		byte x[] = new byte[1000];
+		Arrays.fill(d, Byte.MAX_VALUE);
+		Arrays.fill(x, Byte.MIN_VALUE);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, Byte.MAX_VALUE);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(short[], short[])
+	 */
+	public void test_equals$S$S() {
+		// Test for method boolean java.util.Arrays.equals(short [], short [])
+		short d[] = new short[1000];
+		short x[] = new short[1000];
+		Arrays.fill(d, Short.MAX_VALUE);
+		Arrays.fill(x, Short.MIN_VALUE);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, Short.MAX_VALUE);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(char[], char[])
+	 */
+	public void test_equals$C$C() {
+		// Test for method boolean java.util.Arrays.equals(char [], char [])
+		char d[] = new char[1000];
+		char x[] = new char[1000];
+		char c = 'T';
+		Arrays.fill(d, c);
+		Arrays.fill(x, 'L');
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, c);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(int[], int[])
+	 */
+	public void test_equals$I$I() {
+		// Test for method boolean java.util.Arrays.equals(int [], int [])
+		int d[] = new int[1000];
+		int x[] = new int[1000];
+		Arrays.fill(d, Integer.MAX_VALUE);
+		Arrays.fill(x, Integer.MIN_VALUE);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, Integer.MAX_VALUE);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+		assertTrue("wrong result for null array1", !Arrays.equals(new int[2],
+				null));
+		assertTrue("wrong result for null array2", !Arrays.equals(null,
+				new int[2]));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(long[], long[])
+	 */
+	public void test_equals$J$J() {
+		// Test for method boolean java.util.Arrays.equals(long [], long [])
+		long d[] = new long[1000];
+		long x[] = new long[1000];
+		Arrays.fill(d, Long.MAX_VALUE);
+		Arrays.fill(x, Long.MIN_VALUE);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, Long.MAX_VALUE);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+		assertTrue("should be false", !Arrays.equals(
+				new long[] { 0x100000000L }, new long[] { 0x200000000L }));
+
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(float[], float[])
+	 */
+	public void test_equals$F$F() {
+		// Test for method boolean java.util.Arrays.equals(float [], float [])
+		float d[] = new float[1000];
+		float x[] = new float[1000];
+		Arrays.fill(d, Float.MAX_VALUE);
+		Arrays.fill(x, Float.MIN_VALUE);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, Float.MAX_VALUE);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+		assertTrue("NaN not equals", Arrays.equals(new float[] { Float.NaN },
+				new float[] { Float.NaN }));
+		assertTrue("0f equals -0f", !Arrays.equals(new float[] { 0f },
+				new float[] { -0f }));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(double[], double[])
+	 */
+	public void test_equals$D$D() {
+		// Test for method boolean java.util.Arrays.equals(double [], double [])
+		double d[] = new double[1000];
+		double x[] = new double[1000];
+		Arrays.fill(d, Double.MAX_VALUE);
+		Arrays.fill(x, Double.MIN_VALUE);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, Double.MAX_VALUE);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+
+		assertTrue("should be false", !Arrays.equals(new double[] { 1.0 },
+				new double[] { 2.0 }));
+
+		assertTrue("NaN not equals", Arrays.equals(new double[] { Double.NaN },
+				new double[] { Double.NaN }));
+		assertTrue("0d equals -0d", !Arrays.equals(new double[] { 0d },
+				new double[] { -0d }));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(boolean[], boolean[])
+	 */
+	public void test_equals$Z$Z() {
+		// Test for method boolean java.util.Arrays.equals(boolean [], boolean
+		// [])
+		boolean d[] = new boolean[1000];
+		boolean x[] = new boolean[1000];
+		Arrays.fill(d, true);
+		Arrays.fill(x, false);
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, true);
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+	}
+
+	/**
+	 * @tests java.util.Arrays#equals(java.lang.Object[], java.lang.Object[])
+	 */
+	public void test_equals$Ljava_lang_Object$Ljava_lang_Object() {
+		// Test for method boolean java.util.Arrays.equals(java.lang.Object [],
+		// java.lang.Object [])
+		Object d[] = new Object[1000];
+		Object x[] = new Object[1000];
+		Object o = new Object();
+		Arrays.fill(d, o);
+		Arrays.fill(x, new Object());
+		assertTrue("Inequal arrays returned true", !Arrays.equals(d, x));
+		Arrays.fill(x, o);
+		d[50] = null;
+		x[50] = null;
+		assertTrue("equal arrays returned false", Arrays.equals(d, x));
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(byte[])
+	 */
+	public void test_sort$B() {
+		// Test for method void java.util.Arrays.sort(byte [])
+		byte[] reversedArray = new byte[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = (byte) (arraySize - counter - 1);
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == (byte) counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(byte[], int, int)
+	 */
+	public void test_sort$BII() {
+		// Test for method void java.util.Arrays.sort(byte [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		byte[] reversedArray = new byte[arraySize];
+		byte[] originalReversedArray = new byte[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = (byte) (arraySize - counter - 1);
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+
+        try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+		
+		//exception order testing
+		try {
+			Arrays.sort(new byte[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(char[])
+	 */
+	public void test_sort$C() {
+		// Test for method void java.util.Arrays.sort(char [])
+		char[] reversedArray = new char[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = (char) (arraySize - counter - 1);
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == (char) counter);
+
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(char[], int, int)
+	 */
+	public void test_sort$CII() {
+		// Test for method void java.util.Arrays.sort(char [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		char[] reversedArray = new char[arraySize];
+		char[] originalReversedArray = new char[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = (char) (arraySize - counter - 1);
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+
+		try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+        
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+
+		//exception order testing
+		try {
+			Arrays.sort(new char[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(double[])
+	 */
+	public void test_sort$D() {
+		// Test for method void java.util.Arrays.sort(double [])
+		double[] reversedArray = new double[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = (double) (arraySize - counter - 1);
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == (double) counter);
+
+		double[] specials1 = new double[] { Double.NaN, Double.MAX_VALUE,
+				Double.MIN_VALUE, 0d, -0d, Double.POSITIVE_INFINITY,
+				Double.NEGATIVE_INFINITY };
+		double[] specials2 = new double[] { 0d, Double.POSITIVE_INFINITY, -0d,
+				Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Double.NaN,
+				Double.MAX_VALUE };
+        double[] specials3 = new double[] { 0.0, Double.NaN, 1.0, 2.0, Double.NaN,
+                Double.NaN, 1.0, 3.0, -0.0};
+		double[] answer = new double[] { Double.NEGATIVE_INFINITY, -0d, 0d,
+				Double.MIN_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY,
+				Double.NaN };
+        double[] answer3 = new double[] { -0.0, 0.0, 1.0, 1.0, 2.0, 3.0, Double.NaN,
+                Double.NaN, Double.NaN };
+
+		Arrays.sort(specials1);
+		Object[] print1 = new Object[specials1.length];
+		for (int i = 0; i < specials1.length; i++)
+			print1[i] = new Double(specials1[i]);
+		assertTrue("specials sort incorrectly 1: " + Arrays.asList(print1),
+				Arrays.equals(specials1, answer));
+
+		Arrays.sort(specials2);
+		Object[] print2 = new Object[specials2.length];
+		for (int i = 0; i < specials2.length; i++)
+			print2[i] = new Double(specials2[i]);
+		assertTrue("specials sort incorrectly 2: " + Arrays.asList(print2),
+				Arrays.equals(specials2, answer));
+        
+        Arrays.sort(specials3);
+        Object[] print3 = new Object[specials3.length];
+        for (int i = 0; i < specials3.length; i++)
+            print3[i] = new Double(specials3[i]);
+        assertTrue("specials sort incorrectly 3: " + Arrays.asList(print3),
+                Arrays.equals(specials3, answer3));
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(double[], int, int)
+	 */
+	public void test_sort$DII() {
+		// Test for method void java.util.Arrays.sort(double [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		double[] reversedArray = new double[arraySize];
+		double[] originalReversedArray = new double[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = (double) (arraySize - counter - 1);
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+
+		try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+		
+		//exception order testing
+		try {
+			Arrays.sort(new double[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(float[])
+	 */
+	public void test_sort$F() {
+		// Test for method void java.util.Arrays.sort(float [])
+		float[] reversedArray = new float[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = (float) (arraySize - counter - 1);
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == (float) counter);
+
+		float[] specials1 = new float[] { Float.NaN, Float.MAX_VALUE,
+				Float.MIN_VALUE, 0f, -0f, Float.POSITIVE_INFINITY,
+				Float.NEGATIVE_INFINITY };
+		float[] specials2 = new float[] { 0f, Float.POSITIVE_INFINITY, -0f,
+				Float.NEGATIVE_INFINITY, Float.MIN_VALUE, Float.NaN,
+				Float.MAX_VALUE };
+		float[] answer = new float[] { Float.NEGATIVE_INFINITY, -0f, 0f,
+				Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
+				Float.NaN };
+
+		Arrays.sort(specials1);
+		Object[] print1 = new Object[specials1.length];
+		for (int i = 0; i < specials1.length; i++)
+			print1[i] = new Float(specials1[i]);
+		assertTrue("specials sort incorrectly 1: " + Arrays.asList(print1),
+				Arrays.equals(specials1, answer));
+
+		Arrays.sort(specials2);
+		Object[] print2 = new Object[specials2.length];
+		for (int i = 0; i < specials2.length; i++)
+			print2[i] = new Float(specials2[i]);
+		assertTrue("specials sort incorrectly 2: " + Arrays.asList(print2),
+				Arrays.equals(specials2, answer));
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(float[], int, int)
+	 */
+	public void test_sort$FII() {
+		// Test for method void java.util.Arrays.sort(float [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		float[] reversedArray = new float[arraySize];
+		float[] originalReversedArray = new float[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = (float) (arraySize - counter - 1);
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+
+        try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+        
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+		
+		//exception order testing
+		try {
+			Arrays.sort(new float[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(int[])
+	 */
+	public void test_sort$I() {
+		// Test for method void java.util.Arrays.sort(int [])
+		int[] reversedArray = new int[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = arraySize - counter - 1;
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(int[], int, int)
+	 */
+	public void test_sort$III() {
+		// Test for method void java.util.Arrays.sort(int [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		int[] reversedArray = new int[arraySize];
+		int[] originalReversedArray = new int[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = arraySize - counter - 1;
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+
+        try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+        
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+		
+		//exception order testing
+		try {
+			Arrays.sort(new int[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(long[])
+	 */
+	public void test_sort$J() {
+		// Test for method void java.util.Arrays.sort(long [])
+		long[] reversedArray = new long[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = (long) (arraySize - counter - 1);
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == (long) counter);
+
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(long[], int, int)
+	 */
+	public void test_sort$JII() {
+		// Test for method void java.util.Arrays.sort(long [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		long[] reversedArray = new long[arraySize];
+		long[] originalReversedArray = new long[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = (long) (arraySize - counter - 1);
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+
+        try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+        
+		//exception order testing
+		try {
+			Arrays.sort(new long[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(java.lang.Object[])
+	 */
+	public void test_sort$Ljava_lang_Object() {
+		// Test for method void java.util.Arrays.sort(java.lang.Object [])
+		Object[] reversedArray = new Object[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = objectArray[arraySize - counter - 1];
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == objectArray[counter]);
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(java.lang.Object[], int, int)
+	 */
+	public void test_sort$Ljava_lang_ObjectII() {
+		// Test for method void java.util.Arrays.sort(java.lang.Object [], int,
+		// int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		Object[] reversedArray = new Object[arraySize];
+		Object[] originalReversedArray = new Object[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = objectArray[arraySize - counter - 1];
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					((Comparable) reversedArray[counter])
+							.compareTo(reversedArray[counter + 1]) <= 0);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+        
+		try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+
+        try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+		
+		//exception order testing
+		try {
+			Arrays.sort(new Object[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(java.lang.Object[], int, int,
+	 *        java.util.Comparator)
+	 */
+	public void test_sort$Ljava_lang_ObjectIILjava_util_Comparator() {
+		// Test for method void java.util.Arrays.sort(java.lang.Object [], int,
+		// int, java.util.Comparator)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		ReversedIntegerComparator comp = new ReversedIntegerComparator();
+		Object[] originalArray = new Object[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			originalArray[counter] = objectArray[counter];
+		Arrays.sort(objectArray, startIndex, endIndex, comp);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					objectArray[counter] == originalArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds", comp.compare(
+					objectArray[counter], objectArray[counter + 1]) <= 0);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					objectArray[counter] == originalArray[counter]);
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(java.lang.Object[], java.util.Comparator)
+	 */
+	public void test_sort$Ljava_lang_ObjectLjava_util_Comparator() {
+		// Test for method void java.util.Arrays.sort(java.lang.Object [],
+		// java.util.Comparator)
+		ReversedIntegerComparator comp = new ReversedIntegerComparator();
+		Arrays.sort(objectArray, comp);
+		for (int counter = 0; counter < arraySize - 1; counter++)
+			assertTrue("Array not sorted correctly with custom comparator",
+					comp
+							.compare(objectArray[counter],
+									objectArray[counter + 1]) <= 0);
+	}
+
+    // Regression HARMONY-6076
+    public void test_sort$Ljava_lang_ObjectLjava_util_Comparator_stable() {
+        Element[] array = new Element[11];
+        array[0] = new Element(122);
+        array[1] = new Element(146);
+        array[2] = new Element(178);
+        array[3] = new Element(208);
+        array[4] = new Element(117);
+        array[5] = new Element(146);
+        array[6] = new Element(173);
+        array[7] = new Element(203);
+        array[8] = new Element(56);
+        array[9] = new Element(208);
+        array[10] = new Element(96);
+
+        Comparator<Element> comparator = new Comparator<Element>() {
+            public int compare(Element object1, Element object2) {
+                return object1.value - object2.value;
+            }
+        };
+
+        Arrays.sort(array, comparator);
+
+        for (int i = 1; i < array.length; i++) {
+            assertTrue(comparator.compare(array[i - 1], array[i]) <= 0);
+            if (comparator.compare(array[i - 1], array[i]) == 0) {
+                assertTrue(array[i - 1].index < array[i].index);
+            }
+        }
+    }
+
+    public static class Element {
+        public int value;
+
+        public int index;
+
+        private static int count = 0;
+
+        public Element(int value) {
+            this.value = value;
+            index = count++;
+        }
+    }
+
+	/**
+	 * @tests java.util.Arrays#sort(short[])
+	 */
+	public void test_sort$S() {
+		// Test for method void java.util.Arrays.sort(short [])
+		short[] reversedArray = new short[arraySize];
+		for (int counter = 0; counter < arraySize; counter++)
+			reversedArray[counter] = (short) (arraySize - counter - 1);
+		Arrays.sort(reversedArray);
+		for (int counter = 0; counter < arraySize; counter++)
+			assertTrue("Resulting array not sorted",
+					reversedArray[counter] == (short) counter);
+	}
+
+	/**
+	 * @tests java.util.Arrays#sort(short[], int, int)
+	 */
+	public void test_sort$SII() {
+		// Test for method void java.util.Arrays.sort(short [], int, int)
+		int startIndex = arraySize / 4;
+		int endIndex = 3 * arraySize / 4;
+		short[] reversedArray = new short[arraySize];
+		short[] originalReversedArray = new short[arraySize];
+		for (int counter = 0; counter < arraySize; counter++) {
+			reversedArray[counter] = (short) (arraySize - counter - 1);
+			originalReversedArray[counter] = reversedArray[counter];
+		}
+		Arrays.sort(reversedArray, startIndex, endIndex);
+		for (int counter = 0; counter < startIndex; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+		for (int counter = startIndex; counter < endIndex - 1; counter++)
+			assertTrue("Array not sorted within bounds",
+					reversedArray[counter] <= reversedArray[counter + 1]);
+		for (int counter = endIndex; counter < arraySize; counter++)
+			assertTrue("Array modified outside of bounds",
+					reversedArray[counter] == originalReversedArray[counter]);
+	
+		//exception testing
+		try {
+			Arrays.sort(reversedArray, startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+        
+		try {
+			Arrays.sort(reversedArray, -1, startIndex);
+            fail("ArrayIndexOutOfBoundsException expected (1)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+        
+		try {
+			Arrays.sort(reversedArray, startIndex, reversedArray.length + 1);
+            fail("ArrayIndexOutOfBoundsException expected (2)");
+		} catch (ArrayIndexOutOfBoundsException ignore) {
+		}
+		
+		//exception order testing
+		try {
+			Arrays.sort(new short[1], startIndex + 1, startIndex);
+            fail("IllegalArgumentException expected");
+		} catch (IllegalArgumentException ignore) {
+		}
+	}
+
+    /**
+     * @tests java.util.Arrays#sort(byte[], int, int)
+     */
+    public void test_java_util_Arrays_sort_byte_array_NPE() {
+        byte[] byte_array_null = null;
+        try {
+            java.util.Arrays.sort(byte_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(byte_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(char[], int, int)
+     */
+    public void test_java_util_Arrays_sort_char_array_NPE() {
+        char[] char_array_null = null;
+        try {
+            java.util.Arrays.sort(char_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(char_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(double[], int, int)
+     */
+    public void test_java_util_Arrays_sort_double_array_NPE() {
+        double[] double_array_null = null;
+        try {
+            java.util.Arrays.sort(double_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(double_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(float[], int, int)
+     */
+    public void test_java_util_Arrays_sort_float_array_NPE() {
+        float[] float_array_null = null;
+        try {
+            java.util.Arrays.sort(float_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(float_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(int[], int, int)
+     */
+    public void test_java_util_Arrays_sort_int_array_NPE() {
+        int[] int_array_null = null;
+        try {
+            java.util.Arrays.sort(int_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(int_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(Object[], int, int)
+     */
+    public void test_java_util_Arrays_sort_object_array_NPE() {
+        Object[] object_array_null = null;
+        try {
+            java.util.Arrays.sort(object_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(object_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(object_array_null, (int) -1, (int) 1, null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(long[], int, int)
+     */
+    public void test_java_util_Arrays_sort_long_array_NPE() {
+        long[] long_array_null = null;
+        try {
+            java.util.Arrays.sort(long_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(long_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#sort(short[], int, int)
+     */
+    public void test_java_util_Arrays_sort_short_array_NPE() {
+        short[] short_array_null = null;
+        try {
+            java.util.Arrays.sort(short_array_null);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+        try {
+            // Regression for HARMONY-378
+            java.util.Arrays.sort(short_array_null, (int) -1, (int) 1);
+            fail("Should throw java.lang.NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+    
+    /**
+     * @tests java.util.Arrays#deepEquals(Object[], Object[])      
+     */
+    public void test_deepEquals$Ljava_lang_ObjectLjava_lang_Object() {
+       int [] a1 = {1, 2, 3};
+       short [] a2 = {0, 1};
+       Object [] a3 = {new Integer(1), a2};
+       int [] a4 = {6, 5, 4};
+       
+       int [] b1 = {1, 2, 3};
+       short [] b2 = {0, 1};
+       Object [] b3 = {new Integer(1), b2};
+       
+       Object a [] = {a1, a2, a3};
+       Object b [] = {b1, b2, b3};
+       
+       assertFalse(Arrays.equals(a, b));
+       assertTrue(Arrays.deepEquals(a,b));
+       
+       a[2] = a4;
+       
+       assertFalse(Arrays.deepEquals(a, b));
+    }
+    
+    /**
+     * @tests java.util.Arrays#deepHashCode(Object[])
+     */
+    public void test_deepHashCode$Ljava_lang_Object() {
+        int [] a1 = {1, 2, 3};
+        short [] a2 = {0, 1};
+        Object [] a3 = {new Integer(1), a2};
+        
+        int [] b1 = {1, 2, 3};
+        short [] b2 = {0, 1};
+        Object [] b3 = {new Integer(1), b2};
+        
+        Object a [] = {a1, a2, a3};
+        Object b [] = {b1, b2, b3};
+       
+        int deep_hash_a = Arrays.deepHashCode(a);
+        int deep_hash_b = Arrays.deepHashCode(b);
+        
+        assertEquals(deep_hash_a, deep_hash_b);
+     }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(boolean[] a)
+     */
+    public void test_hashCode$LZ() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        boolean [] boolArr = {true, false, false, true, false};    
+        List listOfBoolean = new LinkedList();
+        for (int i = 0; i < boolArr.length; i++) {
+            listOfBoolean.add(new Boolean(boolArr[i]));
+        }
+        listHashCode = listOfBoolean.hashCode();
+        arrayHashCode = Arrays.hashCode(boolArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(int[] a)
+     */
+    public void test_hashCode$LI() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        int [] intArr = {10, 5, 134, 7, 19};    
+        List listOfInteger = new LinkedList();
+         
+        for (int i = 0; i < intArr.length; i++) {
+            listOfInteger.add(new Integer(intArr[i]));           
+        }               
+        listHashCode = listOfInteger.hashCode();
+        arrayHashCode = Arrays.hashCode(intArr);       
+        assertEquals(listHashCode, arrayHashCode);
+        
+        int [] intArr2 = {10, 5, 134, 7, 19};                
+        assertEquals(Arrays.hashCode(intArr2), Arrays.hashCode(intArr));
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(char[] a)
+     */
+    public void test_hashCode$LC() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        char [] charArr = {'a', 'g', 'x', 'c', 'm'};    
+        List listOfCharacter = new LinkedList();
+        for (int i = 0; i < charArr.length; i++) {
+            listOfCharacter.add(new Character(charArr[i]));
+        }
+        listHashCode = listOfCharacter.hashCode();
+        arrayHashCode = Arrays.hashCode(charArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(byte[] a)
+     */
+    public void test_hashCode$LB() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        byte [] byteArr = {5, 9, 7, 6, 17};    
+        List listOfByte = new LinkedList();
+        for (int i = 0; i < byteArr.length; i++) {
+            listOfByte.add(new Byte(byteArr[i]));
+        }
+        listHashCode = listOfByte.hashCode();
+        arrayHashCode = Arrays.hashCode(byteArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(long[] a)
+     */
+    public void test_hashCode$LJ() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        long [] longArr = {67890234512l, 97587236923425l, 257421912912l,
+                6754268100l, 5};    
+        List listOfLong = new LinkedList();
+        for (int i = 0; i < longArr.length; i++) {
+            listOfLong.add(new Long(longArr[i]));
+        }
+        listHashCode = listOfLong.hashCode();
+        arrayHashCode = Arrays.hashCode(longArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(float[] a)
+     */
+    public void test_hashCode$LF() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        float [] floatArr = {0.13497f, 0.268934f, 12e-5f, -3e+2f, 10e-4f};    
+        List listOfFloat = new LinkedList();
+        for (int i = 0; i < floatArr.length; i++) {
+            listOfFloat.add(new Float(floatArr[i]));
+        }
+        listHashCode = listOfFloat.hashCode();
+        arrayHashCode = Arrays.hashCode(floatArr);
+        assertEquals(listHashCode, arrayHashCode);
+           
+        float [] floatArr2 = {0.13497f, 0.268934f, 12e-5f, -3e+2f, 10e-4f};
+        assertEquals(Arrays.hashCode(floatArr2), Arrays.hashCode(floatArr));
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(double[] a)
+     */
+    public void test_hashCode$LD() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        double [] doubleArr = {0.134945657, 0.0038754, 11e-150, -30e-300, 10e-4};    
+        List listOfDouble = new LinkedList();
+        for (int i = 0; i < doubleArr.length; i++) {
+            listOfDouble.add(new Double(doubleArr[i]));
+        }
+        listHashCode = listOfDouble.hashCode();
+        arrayHashCode = Arrays.hashCode(doubleArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(short[] a)
+     */
+    public void test_hashCode$LS() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        short [] shortArr = {35, 13, 45, 2, 91};    
+        List listOfShort = new LinkedList();
+        for (int i = 0; i < shortArr.length; i++) {
+            listOfShort.add(new Short(shortArr[i]));
+        }
+        listHashCode = listOfShort.hashCode();
+        arrayHashCode = Arrays.hashCode(shortArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+    /**
+     * @tests java.util.Arrays#hashCode(Object[] a)
+     */
+    public void test_hashCode$Ljava_lang_Object() {
+        int listHashCode;
+        int arrayHashCode;
+        
+        Object[] objectArr = {new Integer(1), new Float(10e-12f), null};
+        List listOfObject= new LinkedList();
+        for (int i = 0; i < objectArr.length; i++) {
+            listOfObject.add(objectArr[i]);
+        }
+        listHashCode = listOfObject.hashCode();
+        arrayHashCode = Arrays.hashCode(objectArr);
+        assertEquals(listHashCode, arrayHashCode);
+    }
+    
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		booleanArray = new boolean[arraySize];
+		byteArray = new byte[arraySize];
+		charArray = new char[arraySize];
+		doubleArray = new double[arraySize];
+		floatArray = new float[arraySize];
+		intArray = new int[arraySize];
+		longArray = new long[arraySize];
+		objectArray = new Object[arraySize];
+		shortArray = new short[arraySize];
+
+		for (int counter = 0; counter < arraySize; counter++) {
+			byteArray[counter] = (byte) counter;
+			charArray[counter] = (char) (counter + 1);
+			doubleArray[counter] = counter;
+			floatArray[counter] = counter;
+			intArray[counter] = counter;
+			longArray[counter] = counter;
+			objectArray[counter] = objArray[counter];
+			shortArray[counter] = (short) counter;
+		}
+		for (int counter = 0; counter < arraySize; counter += 2) {
+			booleanArray[counter] = false;
+			booleanArray[counter + 1] = true;
+		}
+	}
+	
+    /**
+     * @tests java.util.Arrays#binarySearch(byte[],int,int, byte)
+     */
+    public void test_binarySearch$BIIB() {
+        for (byte counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on byte[] answered incorrect position",
+                    Arrays.binarySearch(byteArray, counter, arraySize, counter) == counter);
+        }
+        assertEquals(
+                "Binary search succeeded for value not present in array 1", -1,
+                Arrays.binarySearch(byteArray, 0, arraySize, (byte) -1));
+        assertTrue(
+                "Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(byteArray, (byte) arraySize) == -(arraySize + 1));
+        for (byte counter = 0; counter < arraySize; counter++) {
+            byteArray[counter] -= 50;
+        }
+        for (byte counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on byte[] involving negative numbers answered incorrect position",
+                    Arrays.binarySearch(byteArray, counter, arraySize,
+                            (byte) (counter - 50)) == counter);
+        }
+        try {
+            Arrays.binarySearch((byte[])null, 2, 1, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((byte[])null, -1, 0, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((byte[])null, -1, -2, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(byteArray, 2, 1, (byte) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays.binarySearch(byteArray, 0, 0, (byte) arraySize));
+        try {
+            Arrays.binarySearch(byteArray, -1, -2, (byte) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(byteArray, arraySize + 2, arraySize + 1,
+                    (byte) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(byteArray, -1, 0, (byte) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(byteArray, 0, arraySize + 1, (byte) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Arrays#binarySearch(char[], char)
+     */
+    public void test_binarySearch$CIIC() {
+        for (char counter = 0; counter < arraySize; counter++) {
+            assertTrue("Binary search on char[] answered incorrect position",
+                    Arrays.binarySearch(charArray, counter, arraySize,
+                            (char) (counter + 1)) == counter);
+        }
+        assertEquals(
+                "Binary search succeeded for value not present in array 1", -1,
+                Arrays.binarySearch(charArray, 0, arraySize, '\u0000'));
+        assertTrue("Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(charArray, 0, arraySize,
+                        (char) (arraySize + 1)) == -(arraySize + 1));
+        try {
+            Arrays.binarySearch(charArray, 2, 1, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((char[])null, 2, 1, (char) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((char[])null, -1, 0, (char) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((char[])null, -1, -2, (char) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays.binarySearch(charArray, 0, 0, (char) arraySize));
+        try {
+            Arrays.binarySearch(charArray, -1, -2, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(charArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(charArray, -1, 0, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(charArray, 0, arraySize + 1, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
 
     /**
      * @tests java.util.Arrays#binarySearch(double[], double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "binarySearch",
-        args = {double[].class, double.class}
-    )
-    public void test_binarySearch$DD() {
+    public void test_binarySearch$DIID() {
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue("Binary search on double[] answered incorrect position",
+                    Arrays.binarySearch(doubleArray, counter, arraySize,
+                            (double) counter) == (double) counter);
+        }
+        assertEquals(
+                "Binary search succeeded for value not present in array 1", -1,
+                Arrays.binarySearch(doubleArray, 0, arraySize, (double) -1));
+        assertTrue("Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(doubleArray, 0, arraySize,
+                        (double) arraySize) == -(arraySize + 1));
+        for (int counter = 0; counter < arraySize; counter++) {
+            doubleArray[counter] -= (double) 50;
+        }
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on double[] involving negative numbers answered incorrect position",
+                    Arrays.binarySearch(doubleArray, counter, arraySize,(double) (counter - 50)) == (double) counter);
+        }
         double[] specials = new double[] { Double.NEGATIVE_INFINITY,
                 -Double.MAX_VALUE, -2d, -Double.MIN_VALUE, -0d, 0d,
                 Double.MIN_VALUE, 2d, Double.MAX_VALUE,
                 Double.POSITIVE_INFINITY, Double.NaN };
-
         for (int i = 0; i < specials.length; i++) {
-            int result = Arrays.binarySearch(specials, specials[i]);
-            assertTrue("Assert 0: " + specials[i] + " invalid: " + result,
-                    result == i);
+            int result = Arrays.binarySearch(specials, i, specials.length,specials[i]);
+            assertTrue(specials[i] + " invalid: " + result, result == i);
         }
-        assertEquals("Assert 1: Invalid search index for -1d",
-                -4, Arrays.binarySearch(specials, -1d));
-        assertEquals("Assert 2: Invalid search index for 1d",
-                -8, Arrays.binarySearch(specials, 1d));
+        assertEquals("-1d", -4, Arrays.binarySearch(specials,0,specials.length, -1d));
+        assertEquals("1d", -8, Arrays.binarySearch(specials,0,specials.length, 1d));
+        try {
+            Arrays.binarySearch((double[])null, 2, 1, (double) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((double[])null, -1, 0, (double) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((double[])null, -1, -2, (double) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(doubleArray, 2, 1, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays.binarySearch(doubleArray, 0, 0, (char) arraySize));
+        try {
+            Arrays.binarySearch(doubleArray, -1, -2, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(doubleArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(doubleArray, -1, 0, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(doubleArray, 0, arraySize + 1, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
     }
-    
+
     /**
      * @tests java.util.Arrays#binarySearch(float[], float)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "binarySearch",
-        args = {float[].class, float.class}
-    )
-    public void test_binarySearch$FF() {
+    public void test_binarySearch$FIIF() {
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue("Binary search on float[] answered incorrect position",
+                    Arrays.binarySearch(floatArray, counter, arraySize,
+                            (float) counter) == (float) counter);
+        }
+        assertEquals(
+                "Binary search succeeded for value not present in array 1", -1,
+                Arrays.binarySearch(floatArray, 0, arraySize, (float) -1));
+        assertTrue("Binary search succeeded for value not present in array 2",
+                Arrays
+                        .binarySearch(floatArray, 0, arraySize,
+                                (float) arraySize) == -(arraySize + 1));
+        for (int counter = 0; counter < arraySize; counter++) {
+            floatArray[counter] -= (float) 50;
+        }
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on float[] involving negative numbers answered incorrect position",
+                    Arrays.binarySearch(floatArray, 0, arraySize,
+                            (float) counter - 50) == (float) counter);
+        }
         float[] specials = new float[] { Float.NEGATIVE_INFINITY,
                 -Float.MAX_VALUE, -2f, -Float.MIN_VALUE, -0f, 0f,
                 Float.MIN_VALUE, 2f, Float.MAX_VALUE, Float.POSITIVE_INFINITY,
                 Float.NaN };
-
         for (int i = 0; i < specials.length; i++) {
-            int result = Arrays.binarySearch(specials, specials[i]);
-            assertTrue("Assert 0: " + specials[i] + " invalid: " + result,
-                    result == i);
+            int result = Arrays.binarySearch(specials,i,specials.length,specials[i]);
+            assertTrue(specials[i] + " invalid: " + result, result == i);
         }
-        assertEquals("Assert 1: Invalid search index for -1f",
-                -4, Arrays.binarySearch(specials, -1f));
-        assertEquals("Assert 2: Invalid search index for 1f",
-                -8, Arrays.binarySearch(specials, 1f));
-    }
-    
-    /**
-     * @tests java.util.Arrays#equals(double[], double[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {double[].class, double[].class}
-    )
-    public void test_equals$D$D() {
-        double d[] = new double[100];
-        double x[] = new double[100];
-        Arrays.fill(d, Double.MAX_VALUE);
-        Arrays.fill(x, Double.MIN_VALUE);
-
-        assertTrue("Assert 0: Inequal arrays returned true", !Arrays.equals(d, x));
-
-        Arrays.fill(x, Double.MAX_VALUE);
-        assertTrue("Assert 1: equal arrays returned false", Arrays.equals(d, x));
-
-        assertTrue("Assert 2: should be false",
-                !Arrays.equals(new double[] { 1.0 }, new double[] { 2.0 }));
-
-        assertTrue("Assert 3: NaN not equals",
-                Arrays.equals(new double[] { Double.NaN }, new double[] { Double.NaN }));
-        assertTrue("Assert 4: 0d equals -0d",
-                !Arrays.equals(new double[] { 0d }, new double[] { -0d }));
-    }
-    
-    /**
-     * @tests java.util.Arrays#equals(float[], float[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {float[].class, float[].class}
-    )
-    public void test_equals$F$F() {
-        float d[] = new float[100];
-        float x[] = new float[100];
-        Arrays.fill(d, Float.MAX_VALUE);
-        Arrays.fill(x, Float.MIN_VALUE);
-
-        assertTrue("Assert 0: Inequal arrays returned true", !Arrays.equals(d, x));
-
-        Arrays.fill(x, Float.MAX_VALUE);
-        assertTrue("Assert 1: equal arrays returned false", Arrays.equals(d, x));
-
-        assertTrue("Assert 2: NaN not equals",
-                Arrays.equals(new float[] { Float.NaN }, new float[] { Float.NaN }));
-        assertTrue("Assert 3: 0f equals -0f",
-                !Arrays.equals(new float[] { 0f }, new float[] { -0f }));
-    }
-    
-    /**
-     * @tests java.util.Arrays#sort(double[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sort",
-        args = {double[].class}
-    )
-    public void test_sort$D() {
-        // Test a basic sort
-        double[] reversedArray = new double[100];
-        for (int counter = 0; counter < reversedArray.length; counter ++) {
-            reversedArray[counter] = (reversedArray.length - counter - 1);
-        }
-        Arrays.sort(reversedArray);
-        for (int counter = 0; counter < reversedArray.length; counter ++) {
-            assertTrue("Assert 0: Resulting array not sorted",
-                    reversedArray[counter] == counter);
-        }
-
-        // These have to sort as per the Double compare ordering
-        double[] specials1 = new double[]{Double.NaN, Double.MAX_VALUE, Double.MIN_VALUE, 0d, -0d, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY};
-        double[] specials2 = new double[]{0d, Double.POSITIVE_INFINITY, -0d, Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Double.NaN, Double.MAX_VALUE};
-        double[] answer = new double[]{Double.NEGATIVE_INFINITY, -0d, 0d, Double.MIN_VALUE, Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN};
-
-        Arrays.sort(specials1);
-        Object[] print1 = new Object[specials1.length];
-        for (int i = 0; i < specials1.length; i++) {
-            print1[i] = new Double(specials1[i]);
-        }
-        assertTrue("Assert 1: specials sort incorrectly" + Arrays.asList(print1),
-                Arrays.equals(specials1, answer));
-
-        Arrays.sort(specials2);
-        Object[] print2 = new Object[specials2.length];
-        for (int i = 0; i < specials2.length; i++) {
-            print2[i] = new Double(specials2[i]);
-        }
-        assertTrue("Assert 2: specials sort incorrectly " + Arrays.asList(print2), 
-                Arrays.equals(specials2, answer));
-    }
-    
-    /**
-     * @tests java.util.Arrays#sort(float[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "sort",
-        args = {float[].class}
-    )
-    public void test_sort$F() {
-        // Test a basic sort
-        float[] reversedArray = new float[100];
-        for (int counter = 0; counter < reversedArray.length; counter ++) {
-            reversedArray[counter] = (reversedArray.length - counter - 1);
-        }
-        Arrays.sort(reversedArray);
-        for (int counter = 0; counter < reversedArray.length; counter ++) {
-            assertTrue("Assert 0: Resulting array not sorted",
-                    reversedArray[counter] == counter);
-        }
-
-        float[] specials1 = new float[]{Float.NaN, Float.MAX_VALUE, Float.MIN_VALUE, 0f, -0f, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY};
-        float[] specials2 = new float[]{0f, Float.POSITIVE_INFINITY, -0f, Float.NEGATIVE_INFINITY, Float.MIN_VALUE, Float.NaN, Float.MAX_VALUE};
-        float[] answer = new float[]{Float.NEGATIVE_INFINITY, -0f, 0f, Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY, Float.NaN};
-
-        Arrays.sort(specials1);
-        Object[] print1 = new Object[specials1.length];
-        for (int i = 0; i < specials1.length; i++) {
-            print1[i] = new Float(specials1[i]);
-        }
-        assertTrue("Assert 1: specials sort incorrectly" + Arrays.asList(print1),
-                Arrays.equals(specials1, answer));
-
-        Arrays.sort(specials2);
-        Object[] print2 = new Object[specials2.length];
-        for (int i = 0; i < specials2.length; i++) {
-            print2[i] = new Float(specials2[i]);
-        }
-        assertTrue("Assert 2: specials sort incorrectly" + Arrays.asList(print2), 
-                Arrays.equals(specials2, answer));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(boolean[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {boolean[].class}
-    )
-    public void test_toString$Z() {
-        assertEquals("null", Arrays.toString((boolean[])null));
-        assertEquals("[]", Arrays.toString(new boolean[] {}));
-        assertEquals("[true]", Arrays.toString(new boolean[] {true}));
-        assertEquals("[true, false]", Arrays.toString(new boolean[] {true,false}));
-        assertEquals("[true, false, true]", Arrays.toString(new boolean[] {true,false,true}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(byte[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {byte[].class}
-    )
-    public void test_toString$B() {
-        assertEquals("null", Arrays.toString((byte[])null));
-        assertEquals("[]", Arrays.toString(new byte[] {}));
-        assertEquals("[0]", Arrays.toString(new byte[] {0}));
-        assertEquals("[-1, 0]", Arrays.toString(new byte[] {-1,0}));
-        assertEquals("[-1, 0, 1]", Arrays.toString(new byte[] {-1,0,1}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(char[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {char[].class}
-    )
-    public void test_toString$C() {
-        assertEquals("null", Arrays.toString((char[])null));
-        assertEquals("[]", Arrays.toString(new char[] {}));
-        assertEquals("[a]", Arrays.toString(new char[] {'a'}));
-        assertEquals("[a, b]", Arrays.toString(new char[] {'a','b'}));
-        assertEquals("[a, b, c]", Arrays.toString(new char[] {'a','b','c'}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(double[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {double[].class}
-    )
-    public void test_toString$D() {
-        assertEquals("null", Arrays.toString((double[])null));
-        assertEquals("[]", Arrays.toString(new double[] {}));
-        assertEquals("[0.0]", Arrays.toString(new double[] {0.0D}));
-        assertEquals("[-1.0, 0.0]", Arrays.toString(new double[] {-1.0D, 0.0D}));
-        assertEquals("[-1.0, 0.0, 1.0]", Arrays.toString(new double[] {-1.0D, 0.0D, 1.0D}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(float[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {float[].class}
-    )
-    public void test_toString$F() {
-        assertEquals("null", Arrays.toString((float[])null));
-        assertEquals("[]", Arrays.toString(new float[] {}));
-        assertEquals("[0.0]", Arrays.toString(new float[] {0.0F}));
-        assertEquals("[-1.0, 0.0]", Arrays.toString(new float[] {-1.0F, 0.0F}));
-        assertEquals("[-1.0, 0.0, 1.0]", Arrays.toString(new float[] {-1.0F, 0.0F, 1.0F}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(int[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {int[].class}
-    )
-    public void test_toString$I() {
-        assertEquals("null", Arrays.toString((int[])null));
-        assertEquals("[]", Arrays.toString(new int[] {}));
-        assertEquals("[0]", Arrays.toString(new int[] {0}));
-        assertEquals("[-1, 0]", Arrays.toString(new int[] {-1, 0}));
-        assertEquals("[-1, 0, 1]", Arrays.toString(new int[] {-1, 0, 1}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(long[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {long[].class}
-    )
-    public void test_toString$J() {
-        assertEquals("null", Arrays.toString((long[])null));
-        assertEquals("[]", Arrays.toString(new long[] {}));
-        assertEquals("[0]", Arrays.toString(new long[] {0}));
-        assertEquals("[-1, 0]", Arrays.toString(new long[] {-1, 0}));
-        assertEquals("[-1, 0, 1]", Arrays.toString(new long[] {-1, 0, 1}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(short[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {short[].class}
-    )
-    public void test_toString$S() {
-        assertEquals("null", Arrays.toString((short[])null));
-        assertEquals("[]", Arrays.toString(new short[] {}));
-        assertEquals("[0]", Arrays.toString(new short[] {0}));
-        assertEquals("[-1, 0]", Arrays.toString(new short[] {-1, 0}));
-        assertEquals("[-1, 0, 1]", Arrays.toString(new short[] {-1, 0, 1}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#toString(Object[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {java.lang.Object[].class}
-    )
-    public void test_toString$Ljava_lang_Object() {
-        assertEquals("null", Arrays.toString((Object[])null));
-        assertEquals("[]", Arrays.toString(new Object[] {}));
-        assertEquals("[fixture]", Arrays.toString(new Object[] {"fixture"}));
-        assertEquals("[fixture, null]", Arrays.toString(new Object[] {"fixture", null}));
-        assertEquals("[fixture, null, fixture]", Arrays.toString(new Object[] {"fixture", null, "fixture"}));
-    }
-    
-    /**
-     * @tests java.util.Arrays#deepToString(Object[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "deepToString",
-        args = {java.lang.Object[].class}
-    )
-    public void test_deepToString$java_lang_Object() {
-        assertEquals("null", Arrays.deepToString((Object[])null));
-        assertEquals("[]", Arrays.deepToString(new Object[] {}));
-        assertEquals("[fixture]", Arrays.deepToString(new Object[] {"fixture"}));
-        assertEquals("[fixture, null]", Arrays.deepToString(new Object[] {"fixture", null}));
-        assertEquals("[fixture, null, fixture]", Arrays.deepToString(new Object[] {"fixture", null, "fixture"}));
-        
-        Object[] fixture = new Object[1];
-        fixture[0] = fixture;
-        assertEquals("[[...]]", Arrays.deepToString(fixture));
-        
-        fixture = new Object[2];
-        fixture[0] = "fixture";
-        fixture[1] = fixture;
-        assertEquals("[fixture, [...]]", Arrays.deepToString(fixture));
-        
-        fixture = new Object[10];
-        fixture[0] = new boolean[] {true, false};
-        fixture[1] = new byte[] {0, 1};
-        fixture[2] = new char[] {'a', 'b'};
-        fixture[3] = new double[] {0.0D, 1.0D};
-        fixture[4] = new float[] {0.0F, 1.0F};
-        fixture[5] = new int[] {0, 1};
-        fixture[6] = new long[] {0L, 1L};
-        fixture[7] = new short[] {0, 1};
-        fixture[8] = fixture[0];
-        fixture[9] = new Object[9];
-        ((Object[])fixture[9])[0] = fixture;
-        ((Object[])fixture[9])[1] = fixture[1];
-        ((Object[])fixture[9])[2] = fixture[2];
-        ((Object[])fixture[9])[3] = fixture[3];
-        ((Object[])fixture[9])[4] = fixture[4];
-        ((Object[])fixture[9])[5] = fixture[5];
-        ((Object[])fixture[9])[6] = fixture[6];
-        ((Object[])fixture[9])[7] = fixture[7];
-        Object[] innerFixture = new Object[4];
-        innerFixture[0] = "innerFixture0";
-        innerFixture[1] = innerFixture;
-        innerFixture[2] = fixture;
-        innerFixture[3] = "innerFixture3";
-        ((Object[])fixture[9])[8] = innerFixture;
-        
-        String expected = "[[true, false], [0, 1], [a, b], [0.0, 1.0], [0.0, 1.0], [0, 1], [0, 1], [0, 1], [true, false], [[...], [0, 1], [a, b], [0.0, 1.0], [0.0, 1.0], [0, 1], [0, 1], [0, 1], [innerFixture0, [...], [...], innerFixture3]]]";
-        
-        assertEquals(expected, Arrays.deepToString(fixture));
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "asList",
-        args = {java.lang.Object[].class}
-    )
-    public void test_asListTvararg() throws Exception {
-        List<String> stringsList = Arrays.asList("0", "1");
-        assertEquals(2, stringsList.size());
-        assertEquals("0", stringsList.get(0));
-        assertEquals("1", stringsList.get(1));
-        assertTrue(stringsList instanceof RandomAccess);
-        assertTrue(stringsList instanceof Serializable);
-        
-        assertEquals(stringsList, SerializationTest
-                .copySerializable((Serializable) stringsList));
-        
-        //test from javadoc
-        List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
-        assertEquals(3, stooges.size());
-        assertEquals("Larry", stooges.get(0));
-        assertEquals("Moe", stooges.get(1));
-        assertEquals("Curly", stooges.get(2));
-        
-        stringsList = Arrays.asList((String)null);
-        assertEquals(1, stringsList.size());
-        assertEquals((String)null, stringsList.get(0));
-        
+        assertEquals("-1f", -4, Arrays.binarySearch(specials,0,specials.length, -1f));
+        assertEquals("1f", -8, Arrays.binarySearch(specials,0,specials.length, 1f));
         try {
-            Arrays.asList((Object[])null);
-            fail("No NPE");
-        } catch (NullPointerException e) {}
+            Arrays.binarySearch((float[])null, 2, 1, (float) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((float[])null, -1, 0, (float) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((float[])null, -1, -2, (float) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(floatArray, 2, 1, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays.binarySearch(floatArray, 0, 0,
+                (char) arraySize));
+        try {
+            Arrays.binarySearch(floatArray, -1, -2, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(floatArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(floatArray, -1, 0, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays
+                    .binarySearch(floatArray, 0, arraySize + 1,
+                            (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
     }
 
     /**
-     * @tests java.util.Arrays#deepToString(Object[])
-     * @bug 1452542
+     * @tests java.util.Arrays#binarySearch(int[], int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Tests fix for Android bug 1452542",
-        method = "deepToString",
-        args = {java.lang.Object[].class}
-    )
-    public void test_deepToStringNestedEmptyArray() {
-        Object[][] foo = new Object[1][];
-        foo[0] = new Object[0];
-        assertEquals("[[]]", Arrays.deepToString(foo));
+    public void test_binarySearch$IIII() {
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on int[] answered incorrect position",
+                    Arrays.binarySearch(intArray, counter, arraySize, counter) == counter);
+        }
+        assertEquals(
+                "Binary search succeeded for value not present in array 1", -1,
+                Arrays.binarySearch(intArray,0, arraySize, -1));
+        assertTrue("Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(intArray,0, arraySize, arraySize) == -(arraySize + 1));
+        for (int counter = 0; counter < arraySize; counter++) {
+            intArray[counter] -= 50;
+        }
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on int[] involving negative numbers answered incorrect position",
+                    Arrays.binarySearch(intArray,0, arraySize, counter - 50) == counter);
+        }
+        try {
+            Arrays.binarySearch((int[])null, 2, 1, (int) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((int[])null, -1, 0, (int) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((int[])null, -1, -2, (int) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(intArray, 2, 1, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays
+                .binarySearch(intArray, 0, 0, (char) arraySize));
+        try {
+            Arrays.binarySearch(intArray, -1, -2, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(intArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(intArray, -1, 0, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(intArray, 0, arraySize + 1, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
     }
 
     /**
-     * @tests java.util.Arrays#deepToString(Object[])
-     * @bug 1452542
+     * @tests java.util.Arrays#binarySearch(long[], long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Tests fix for Android bug 1452542",
-        method = "deepToString",
-        args = {java.lang.Object[].class}
-    )
-    public void test_deepToStringNestedNullArray() {
-        Object[][] foo = new Object[1][];
-        assertEquals("[null]", Arrays.deepToString(foo));
+    public void test_binarySearch$JIIJ() {
+        for (long counter = 0; counter < arraySize; counter++){
+            assertTrue("Binary search on long[] answered incorrect position",
+                    Arrays.binarySearch(longArray,0,arraySize, counter) == counter);
+        }
+        assertEquals("Binary search succeeded for value not present in array 1",
+                -1, Arrays.binarySearch(longArray,0,arraySize, (long) -1));
+        assertTrue(
+                "Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(longArray,0,arraySize, (long) arraySize) == -(arraySize + 1));
+        for (long counter = 0; counter < arraySize; counter++){
+            longArray[(int) counter] -= (long) 50;
+        }
+        for (long counter = 0; counter < arraySize; counter++){
+            assertTrue(
+                    "Binary search on long[] involving negative numbers answered incorrect position",
+                    Arrays.binarySearch(longArray,0,arraySize, counter - (long) 50) == counter);
+        }
+        try {
+            Arrays.binarySearch((long[])null, 2, 1, (long) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((long[])null, -1, 0, (long) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((long[])null, -1, -2, (long) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(longArray, 2, 1, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays
+                .binarySearch(longArray, 0, 0, (char) arraySize));
+        try {
+            Arrays.binarySearch(longArray, -1, -2, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(longArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(longArray, -1, 0, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(longArray, 0, arraySize + 1, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
     }
 
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "binarySearch",
-        args = {java.lang.Object[].class, java.lang.Object.class, java.util.Comparator.class}
-    )
-    public void test_binarySearch$TTLjava_util_ComparatorsuperT() {
-        String[] strings = new String[] { "a", "B", "c", "D" };
-        Arrays.sort(strings, String.CASE_INSENSITIVE_ORDER);
-        assertEquals(0, Arrays.binarySearch(strings, "a",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(0, Arrays.binarySearch(strings, "A",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(1, Arrays.binarySearch(strings, "b",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(1, Arrays.binarySearch(strings, "B",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(2, Arrays.binarySearch(strings, "c",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(2, Arrays.binarySearch(strings, "C",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(3, Arrays.binarySearch(strings, "d",
-                String.CASE_INSENSITIVE_ORDER));
-        assertEquals(3, Arrays.binarySearch(strings, "D",
-                String.CASE_INSENSITIVE_ORDER));
-
-
-        assertTrue(Arrays.binarySearch(strings, "e",
-                String.CASE_INSENSITIVE_ORDER) < 0);
-        assertTrue(Arrays.binarySearch(strings, "" + ('A' - 1),
-                String.CASE_INSENSITIVE_ORDER) < 0);
-
-        //test with null comparator, which switches back to Comparable
-        Arrays.sort(strings, null);
-        //B, D, a, c
-        assertEquals(2, Arrays.binarySearch(strings, "a", (Comparator<String>)null));
-        assertEquals(-1, Arrays.binarySearch(strings, "A", (Comparator<String>)null));
-        assertEquals(-4, Arrays.binarySearch(strings, "b", (Comparator<String>)null));
-        assertEquals(0, Arrays.binarySearch(strings, "B", (Comparator<String>)null));
-        assertEquals(3, Arrays.binarySearch(strings, "c", (Comparator<String>)null));
-        assertEquals(-2, Arrays.binarySearch(strings, "C", (Comparator<String>)null));
-        assertEquals(-5, Arrays.binarySearch(strings, "d", (Comparator<String>)null));
-        assertEquals(1, Arrays.binarySearch(strings, "D", (Comparator<String>)null));       
-
-        assertTrue(Arrays.binarySearch(strings, "e", null) < 0);
-        assertTrue(Arrays.binarySearch(strings, "" + ('A' - 1), null) < 0);
-        
+    /**
+     * @tests java.util.Arrays#binarySearch(java.lang.Object[],
+     *        java.lang.Object)
+     */
+    public void test_binarySearch$Ljava_lang_ObjectIILjava_lang_Object() {
+        assertEquals(
+                "Binary search succeeded for non-comparable value in empty array",
+                -1, Arrays.binarySearch(new Object[] {},0,0, new Object()));
+        assertEquals(
+                "Binary search succeeded for comparable value in empty array",
+                -1, Arrays.binarySearch(new Object[] {},0,0, new Integer(-1)));
+        for (int counter = 0; counter < arraySize; counter++){
+            assertTrue(
+                    "Binary search on Object[] answered incorrect position",
+                    Arrays.binarySearch(objectArray,counter,arraySize, objArray[counter]) == counter);
+        }
+        assertEquals("Binary search succeeded for value not present in array 1",
+                -1, Arrays.binarySearch(objectArray,0,arraySize, new Integer(-1)));
+        assertTrue(
+                "Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(objectArray,0,arraySize, new Integer(arraySize)) == -(arraySize + 1));
         try {
-            Arrays.binarySearch((String[])null, "A", String.CASE_INSENSITIVE_ORDER);
-            fail("No NPE");
-        } catch (NullPointerException e) {}
-        
+            Arrays.binarySearch((Object[])null, 2, 1, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
         try {
-            Arrays.binarySearch(strings, (String)null, String.CASE_INSENSITIVE_ORDER);
-            fail("No NPE");
-        } catch (NullPointerException e) {}
-        
+            Arrays.binarySearch((Object[])null, -1, 0, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
         try {
-            Arrays.binarySearch(strings, (String)null, (Comparator<String>)null);
-            fail("No NPE");
-        } catch (NullPointerException e) {}
-        
+            Arrays.binarySearch((Object[])null, -1, -2, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, 2, 1, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays
+                .binarySearch(objectArray, 0, 0, (char) arraySize));
+        try {
+            Arrays.binarySearch(objectArray, -1, -2, (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, -1, 0, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, 0, arraySize + 1, (char) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify ClassCastException.",
-        method = "sort",
-        args = {java.lang.Object[].class, java.util.Comparator.class}
-    )
-    public void test_sort$TLjava_lang_ComparatorsuperT() {
-        String[] strings = new String[] { "a", "B", "c", "D" };
-        Arrays.sort(strings, String.CASE_INSENSITIVE_ORDER);
-        assertEquals("a", strings[0]);
-        assertEquals("B", strings[1]);
-        assertEquals("c", strings[2]);
-        assertEquals("D", strings[3]);
-        
-        //test with null comparator, which switches back to Comparable
-        Arrays.sort(strings, null);
-        //B, D, a, c
-        assertEquals("B", strings[0]);
-        assertEquals("D", strings[1]);
-        assertEquals("a", strings[2]);
-        assertEquals("c", strings[3]);
-        
+
+    /**
+     * @tests java.util.Arrays#binarySearch(java.lang.Object[],
+     *        java.lang.Object, java.util.Comparator)
+     */
+    public void test_binarySearch$Ljava_lang_ObjectIILjava_lang_ObjectLjava_util_Comparator() {
+        Comparator comp = new ReversedIntegerComparator();
+        for (int counter = 0; counter < arraySize; counter++) {
+            objectArray[counter] = objArray[arraySize - counter - 1];
+        }
+        assertTrue("Binary search succeeded for value not present in array 1",
+                Arrays.binarySearch(objectArray, 0, arraySize, new Integer(-1),
+                        comp) == -(arraySize + 1));
+        assertEquals(
+                "Binary search succeeded for value not present in array 2", -1,
+                Arrays.binarySearch(objectArray, 0, arraySize, new Integer(
+                        arraySize), comp));
+        for (int counter = 0; counter < arraySize; counter++) {
+            assertTrue(
+                    "Binary search on Object[] with custom comparator answered incorrect position",
+                    Arrays.binarySearch(objectArray, objArray[counter], comp) == arraySize
+                            - counter - 1);
+        }
         try {
-            Arrays.sort((String[])null, String.CASE_INSENSITIVE_ORDER);
-            fail("No NPE");
-        } catch (NullPointerException e) {}
-    }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify IllegalArgumentException, ArrayIndexOutOfBoundsException, ClassCastException.",
-        method = "sort",
-        args = {java.lang.Object[].class, int.class, int.class}
-    )
-    public void test_sort$TIILjava_lang_ComparatorsuperT() {
-        String[] strings = new String[] { "a", "B", "c", "D" };
-        Arrays.sort(strings, 0, strings.length, String.CASE_INSENSITIVE_ORDER);
-        assertEquals("a", strings[0]);
-        assertEquals("B", strings[1]);
-        assertEquals("c", strings[2]);
-        assertEquals("D", strings[3]);
-        
-        //test with null comparator, which switches back to Comparable
-        Arrays.sort(strings, 0, strings.length, null);
-        //B, D, a, c
-        assertEquals("B", strings[0]);
-        assertEquals("D", strings[1]);
-        assertEquals("a", strings[2]);
-        assertEquals("c", strings[3]);
-        
+            Arrays.binarySearch((Object[])null, 2, 1, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
         try {
-            Arrays.sort((String[])null, String.CASE_INSENSITIVE_ORDER);
-            fail("No NPE");
-        } catch (NullPointerException e) {}
+            Arrays.binarySearch((Object[])null, -1, 0, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((Object[])null, -1, -2, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, 2, 1, (char) arraySize, comp);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays.binarySearch(objectArray, 0, 0,
+                (char) arraySize, comp));
+        try {
+            Arrays.binarySearch(objectArray, -1, -2, (char) arraySize, comp);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, arraySize + 2, arraySize + 1,
+                    (char) arraySize, comp);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, -1, 0, (char) arraySize, comp);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, 0, arraySize + 1,
+                    (char) arraySize, comp);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(objectArray, 0, arraySize ,
+                    new LinkedList(), comp);
+            fail("should throw ClassCastException");
+        } catch (ClassCastException e) {
+            // expected
+        }
     }
+
+    /**
+     * @tests java.util.Arrays#binarySearch(short[], short)
+     */
+    public void test_binarySearch$SIIS() {
+        for (short counter = 0; counter < arraySize; counter++){
+            assertTrue("Binary search on short[] answered incorrect position",
+                    Arrays.binarySearch(shortArray,counter,arraySize, counter) == counter);
+        }
+        assertEquals("Binary search succeeded for value not present in array 1",
+                -1, Arrays.binarySearch(shortArray,0,arraySize, (short) -1));
+        assertTrue(
+                "Binary search succeeded for value not present in array 2",
+                Arrays.binarySearch(shortArray,0,arraySize, (short) arraySize) == -(arraySize + 1));
+        for (short counter = 0; counter < arraySize; counter++){
+            shortArray[counter] -= 50;
+        }
+        for (short counter = 0; counter < arraySize; counter++){
+            assertTrue(
+                    "Binary search on short[] involving negative numbers answered incorrect position",
+                    Arrays.binarySearch(shortArray,counter,arraySize, (short) (counter - 50)) == counter);
+        }
+        try {
+            Arrays.binarySearch((String[])null, 2, 1, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((String[])null, -1, 0, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch((String[])null, -1, -2, (byte) arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(shortArray, 2, 1, (short) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(-1, Arrays
+                .binarySearch(shortArray, 0, 0, (short) arraySize));
+        try {
+            Arrays.binarySearch(shortArray, -1, -2, (short) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(shortArray, arraySize + 2, arraySize + 1,
+                    (short) arraySize);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(shortArray, -1, 0, (short) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.binarySearch(shortArray, 0, arraySize + 1, (short) arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        String[] array = {"a" , "b" , "c"};
+        assertEquals(-2,Arrays.binarySearch(array, 1, 2, "a", null));
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(byte[],int)
+     */
+    public void test_copyOf_$BI() throws Exception {
+        byte[] result = Arrays.copyOf(byteArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOf(byteArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        try {
+            Arrays.copyOf((byte[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(byteArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((byte[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(short[],int)
+     */
+    public void test_copyOf_$SI() throws Exception {
+        short[] result = Arrays.copyOf(shortArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOf(shortArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        try {
+            Arrays.copyOf((short[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(shortArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((short[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(int[],int)
+     */
+    public void test_copyOf_$II() throws Exception {
+        int[] result = Arrays.copyOf(intArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOf(intArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        try {
+            Arrays.copyOf((int[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(intArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((int[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(boolean[],int)
+     */
+    public void test_copyOf_$ZI() throws Exception {
+        boolean[] result = Arrays.copyOf(booleanArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(booleanArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(false, result[i]);
+        }
+        result = Arrays.copyOf(booleanArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(booleanArray[i], result[i]);
+        }
+        try {
+            Arrays.copyOf((boolean[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(booleanArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((boolean[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(char[],int)
+     */
+    public void test_copyOf_$CI() throws Exception {
+        char[] result = Arrays.copyOf(charArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i+1, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOf(charArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i+1, result[i]);
+        }
+        try {
+            Arrays.copyOf((char[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(charArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((char[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(float[],int)
+     */
+    public void test_copyOf_$FI() throws Exception {
+        float[] result = Arrays.copyOf(floatArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(floatArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0.0f, result[i]);
+        }
+        result = Arrays.copyOf(floatArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(floatArray[i], result[i]);
+        }
+        try {
+            Arrays.copyOf((float[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(floatArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((float[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(double[],int)
+     */
+    public void test_copyOf_$DI() throws Exception {
+        double[] result = Arrays.copyOf(doubleArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(doubleArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0.0, result[i]);
+        }
+        result = Arrays.copyOf(doubleArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(doubleArray[i], result[i]);
+        }
+        try {
+            Arrays.copyOf((double[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(doubleArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((double[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(long[],int)
+     */
+    public void test_copyOf_$JI() throws Exception {
+        long[] result = Arrays.copyOf(longArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(longArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOf(longArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(longArray[i], result[i]);
+        }
+        try {
+            Arrays.copyOf((long[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(longArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((long[])null, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(T[],int)
+     */
+    public void test_copyOf_$TI() throws Exception {
+        Object[] result = Arrays.copyOf(objArray, arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertNull(result[i]);
+        }
+        result = Arrays.copyOf(objArray, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        try {
+            Arrays.copyOf((String[])null, arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(objArray, -1);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((String[])null, -1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        
+        Date[] component = new Date[0];
+        Object object[] = new Date[0];
+        
+        object = Arrays.copyOf(component,2);
+        assertNotNull(object);
+        component = Arrays.copyOf(component,2);
+        assertNotNull(component);
+        assertEquals(2, component.length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOf(T[],int,Class<? extends Object[]>))
+     */
+    public void test_copyOf_$TILClass() throws Exception {
+        Object[] result = Arrays.copyOf(objArray, arraySize*2,Object[].class);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertNull(result[i]);
+        }
+        result = Arrays.copyOf(objArray, arraySize/2,Object[].class);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        result = Arrays.copyOf(objArray, arraySize/2,Integer[].class);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        try {
+            Arrays.copyOf((Object[])null, arraySize,LinkedList[].class);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(objArray, arraySize,LinkedList[].class);
+            fail("should throw ArrayStoreException ");
+        } catch (ArrayStoreException  e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((Object[])null, arraySize,Object[].class);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf(objArray, -1,Object[].class);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((Object[])null, -1,Object[].class);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((Object[])null, -1,LinkedList[].class);
+            fail("should throw NegativeArraySizeException");
+        } catch (NegativeArraySizeException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOf((Object[])null, 0,LinkedList[].class);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        assertEquals(0,Arrays.copyOf(objArray, 0,LinkedList[].class).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(byte[],int,int)
+     */
+    public void test_copyOfRange_$BII() throws Exception {
+        byte[] result = Arrays.copyOfRange(byteArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOfRange(byteArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        result = Arrays.copyOfRange(byteArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((byte[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((byte[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((byte[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(byteArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(byteArray, 0, -1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(byteArray.length + 1, Arrays.copyOfRange(byteArray, 0,
+                byteArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(short[],int,int)
+     */
+    public void test_copyOfRange_$SII() throws Exception {
+        short[] result = Arrays.copyOfRange(shortArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOfRange(shortArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        result = Arrays.copyOfRange(shortArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((short[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((short[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((short[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(shortArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(shortArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(shortArray.length + 1, Arrays.copyOfRange(shortArray, 0,
+                shortArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(int[],int,int)
+     */
+    public void test_copyOfRange_$III() throws Exception {
+        int[] result = Arrays.copyOfRange(intArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOfRange(intArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        result = Arrays.copyOfRange(intArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((int[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((int[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((int[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(intArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(intArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(intArray.length + 1, Arrays.copyOfRange(intArray, 0,
+                intArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(long[],int,int)
+     */
+    public void test_copyOfRange_$JII() throws Exception {
+        long[] result = Arrays.copyOfRange(longArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOfRange(longArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i, result[i]);
+        }
+        result = Arrays.copyOfRange(longArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((long[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((long[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((long[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(longArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(longArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(longArray.length + 1, Arrays.copyOfRange(longArray, 0,
+                longArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(char[],int,int)
+     */
+    public void test_copyOfRange_$CII() throws Exception {
+        char[] result = Arrays.copyOfRange(charArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(i+1, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0, result[i]);
+        }
+        result = Arrays.copyOfRange(charArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(i+1, result[i]);
+        }
+        result = Arrays.copyOfRange(charArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((char[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((char[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((char[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(charArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(charArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(charArray.length + 1, Arrays.copyOfRange(charArray, 0,
+                charArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(float[],int,int)
+     */
+    public void test_copyOfRange_$FII() throws Exception {
+        float[] result = Arrays.copyOfRange(floatArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals((float)i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0.0f, result[i]);
+        }
+        result = Arrays.copyOfRange(floatArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals((float)i, result[i]);
+        }
+        result = Arrays.copyOfRange(floatArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((float[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((float[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((float[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(floatArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(floatArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(floatArray.length + 1, Arrays.copyOfRange(floatArray, 0,
+                floatArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(double[],int,int)
+     */
+    public void test_copyOfRange_$DII() throws Exception {
+        double[] result = Arrays.copyOfRange(doubleArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals((double)i, result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(0.0, result[i]);
+        }
+        result = Arrays.copyOfRange(doubleArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals((double)i, result[i]);
+        }
+        result = Arrays.copyOfRange(doubleArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((double[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((double[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((double[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(doubleArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(doubleArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(doubleArray.length + 1, Arrays.copyOfRange(doubleArray, 0,
+                doubleArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(boolean[],int,int)
+     */
+    public void test_copyOfRange_$ZII() throws Exception {
+        boolean[] result = Arrays.copyOfRange(booleanArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(booleanArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(false, result[i]);
+        }
+        result = Arrays.copyOfRange(booleanArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(booleanArray[i], result[i]);
+        }
+        result = Arrays.copyOfRange(booleanArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((boolean[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((boolean[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((boolean[])null, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(booleanArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(booleanArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(booleanArray.length + 1, Arrays.copyOfRange(booleanArray, 0,
+                booleanArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(Object[],int,int)
+     */
+    public void test_copyOfRange_$TII() throws Exception {
+        Object[] result = Arrays.copyOfRange(objArray, 0,arraySize*2);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(null, result[i]);
+        }
+        result = Arrays.copyOfRange(objArray,0, arraySize/2);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        result = Arrays.copyOfRange(objArray,0, 0);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange((Object[])null, 0,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((Object[])null, -1,arraySize);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((Object[])null, 0,-1);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((Object[])objArray, -1,arraySize);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange((Object[])objArray, 0,-1);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        assertEquals(objArray.length + 1, Arrays.copyOfRange(objArray, 0,
+                objArray.length + 1).length);
+    }
+    
+    /**
+     * @tests {@link java.util.Arrays#copyOfRange(Object[], int, int, Class)
+     */
+    public void test_copyOfRange_$TIILClass() throws Exception {
+        Object[] result = Arrays.copyOfRange(objArray, 0,arraySize*2,Integer[].class);
+        int i = 0;
+        for (; i < arraySize; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        for (; i < result.length; i++) {
+            assertEquals(null, result[i]);
+        }
+        result = Arrays.copyOfRange(objArray,0, arraySize/2,Integer[].class);
+        i = 0;
+        for (; i < result.length; i++) {
+            assertEquals(objArray[i], result[i]);
+        }
+        result = Arrays.copyOfRange(objArray,0, 0,Integer[].class);
+        assertEquals(0, result.length);
+        try {
+            Arrays.copyOfRange(null, 0,arraySize,Integer[].class);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(null, -1,arraySize,Integer[].class);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(null, 0,-1,Integer[].class);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(objArray, -1,arraySize,Integer[].class);
+            fail("should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(objArray, 0,-1,Integer[].class);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(objArray, 0,-1,LinkedList[].class);
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(objArray, 0,1,LinkedList[].class);
+            fail("should throw ArrayStoreException");
+        } catch (ArrayStoreException e) {
+            // expected
+        }
+        try {
+            Arrays.copyOfRange(null, 0,1,LinkedList[].class);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        try {
+            assertEquals(objArray.length + 1, Arrays.copyOfRange(objArray, 0,
+                    objArray.length + 1, LinkedList[].class).length);
+            fail("should throw ArrayStoreException");
+        } catch (ArrayStoreException e) {
+            // expected
+        }
+        assertEquals(0,
+                Arrays.copyOfRange(objArray, 0, 0, LinkedList[].class).length);
+    }
+    
+    /**
+     * @tests java.util.Arrays#swap(int, int, Object[])
+     */
+    /* BEGIN android-removed: tests private implementation detail we don't share.
+    public void test_swap_I_I_$Ljava_lang_Object() throws Exception {
+    	Method m = Arrays.class.getDeclaredMethod("swap", int.class, int.class, Object[].class);
+    	m.setAccessible(true);
+    	Integer[] arr = {new Integer(0), new Integer(1), new Integer(2)};
+    	m.invoke(null,0, 1, arr);
+    	assertEquals("should be equal to 1",1, arr[0].intValue());
+    	assertEquals("should be equal to 0",0, arr[1].intValue());
+    }
+    */
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/BitSetTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/BitSetTest.java
index 769e31f..7126321 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/BitSetTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/BitSetTest.java
@@ -17,78 +17,1386 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.util.BitSet;
 
 import junit.framework.TestCase;
 
-import java.util.BitSet;
-
-@TestTargetClass(BitSet.class) 
 public class BitSetTest extends TestCase {
 
+    BitSet eightbs;
+
+    /**
+     * @tests java.util.BitSet#BitSet()
+     */
+    public void test_Constructor() {
+        BitSet bs = new BitSet();
+        assertEquals("Create BitSet of incorrect size", 64, bs.size());
+        assertEquals("New BitSet had invalid string representation", "{}",
+                     bs.toString());
+    }
+
+    /**
+     * @tests java.util.BitSet#BitSet(int)
+     */
+    public void test_ConstructorI() {
+        BitSet bs = new BitSet(128);
+        assertEquals("Create BitSet of incorrect size", 128, bs.size());
+        assertEquals("New BitSet had invalid string representation: "
+                + bs.toString(), "{}", bs.toString());
+        // All BitSets are created with elements of multiples of 64
+        bs = new BitSet(89);
+        assertEquals("Failed to round BitSet element size", 128, bs.size());
+
+        try {
+            bs = new BitSet(-9);
+            fail("Failed to throw exception when creating a new BitSet with negative element value");
+        } catch (NegativeArraySizeException e) {
+            // Correct behaviour
+        }
+    }
+
+    /**
+     * tests java.util.BitSet#clone()
+     */
+    public void test_clone() {
+        BitSet bs;
+        bs = (BitSet) eightbs.clone();
+        assertEquals("clone failed to return equal BitSet", bs, eightbs);
+    }
+
+    /**
+     * @tests java.util.BitSet#equals(java.lang.Object)
+     */
+    public void test_equalsLjava_lang_Object() {
+        BitSet bs;
+        bs = (BitSet) eightbs.clone();
+        assertEquals("Same BitSet returned false", eightbs, eightbs);
+        assertEquals("Identical BitSet returned false", bs, eightbs);
+        bs.clear(6);
+        assertFalse("Different BitSets returned true", eightbs.equals(bs));
+
+        bs = (BitSet) eightbs.clone();
+        bs.set(128);
+        assertFalse("Different sized BitSet with higher bit set returned true",
+                eightbs.equals(bs));
+        bs.clear(128);
+        assertTrue(
+                "Different sized BitSet with higher bits not set returned false",
+                eightbs.equals(bs));
+    }
+
+    /**
+     * @tests java.util.BitSet#hashCode()
+     */
+    public void test_hashCode() {
+        // Test for method int java.util.BitSet.hashCode()
+        BitSet bs = (BitSet) eightbs.clone();
+        bs.clear(2);
+        bs.clear(6);
+        assertEquals("BitSet returns wrong hash value", 1129, bs.hashCode());
+        bs.set(10);
+        bs.clear(3);
+        assertEquals("BitSet returns wrong hash value", 97, bs.hashCode());
+    }
+
+    /**
+     * @tests java.util.BitSet#clear()
+     */
+    public void test_clear() {
+        eightbs.clear();
+        for (int i = 0; i < 8; i++) {
+            assertFalse("Clear didn't clear bit " + i, eightbs.get(i));
+        }
+        assertEquals("Test1: Wrong length", 0, eightbs.length());
+
+        BitSet bs = new BitSet(3400);
+        bs.set(0, bs.size() - 1); // ensure all bits are 1's
+        bs.set(bs.size() - 1);
+        bs.clear();
+        assertEquals("Test2: Wrong length", 0, bs.length());
+        assertTrue("Test2: isEmpty() returned incorrect value", bs.isEmpty());
+        assertEquals("Test2: cardinality() returned incorrect value", 0, bs
+                .cardinality());
+    }
+
+    /**
+     * @tests java.util.BitSet#clear(int)
+     */
+    public void test_clearI() {
+        // Test for method void java.util.BitSet.clear(int)
+
+        eightbs.clear(7);
+        assertFalse("Failed to clear bit", eightbs.get(7));
+
+        // Check to see all other bits are still set
+        for (int i = 0; i < 7; i++)
+            assertTrue("Clear cleared incorrect bits", eightbs.get(i));
+
+        eightbs.clear(165);
+        assertFalse("Failed to clear bit", eightbs.get(165));
+        // Try out of range
+        try {
+            eightbs.clear(-1);
+            fail("Failed to throw out of bounds exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behaviour
+        }
+
+        BitSet bs = new BitSet(0);
+        assertEquals("Test1: Wrong length,", 0, bs.length());
+        assertEquals("Test1: Wrong size,", 0, bs.size());
+
+        bs.clear(0);
+        assertEquals("Test2: Wrong length,", 0, bs.length());
+        assertEquals("Test2: Wrong size,", 0, bs.size());
+
+        bs.clear(60);
+        assertEquals("Test3: Wrong length,", 0, bs.length());
+        assertEquals("Test3: Wrong size,", 0, bs.size());
+
+        bs.clear(120);
+        assertEquals("Test4: Wrong size,", 0, bs.size());
+        assertEquals("Test4: Wrong length,", 0, bs.length());
+
+        bs.set(25);
+        assertEquals("Test5: Wrong size,", 64, bs.size());
+        assertEquals("Test5: Wrong length,", 26, bs.length());
+
+        bs.clear(80);
+        assertEquals("Test6: Wrong size,", 64, bs.size());
+        assertEquals("Test6: Wrong length,", 26, bs.length());
+
+        bs.clear(25);
+        assertEquals("Test7: Wrong size,", 64, bs.size());
+        assertEquals("Test7: Wrong length,", 0, bs.length());
+    }
+
     /**
      * @tests java.util.BitSet#clear(int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IndexOutOfBoundsException is not verified.",
-        method = "clear",
-        args = {int.class, int.class}
-    )
-    public void test_clearII() {
+    public void test_clearII() throws IndexOutOfBoundsException {
         // Regression for HARMONY-98
         BitSet bitset = new BitSet();
         for (int i = 0; i < 20; i++) {
             bitset.set(i);
         }
         bitset.clear(10, 10);
+
+        // Test for method void java.util.BitSet.clear(int, int)
+        // pos1 and pos2 are in the same bitset element
+        BitSet bs = new BitSet(16);
+        int initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(5);
+        bs.clear(15);
+        bs.clear(7, 11);
+        for (int i = 0; i < 7; i++) {
+            if (i == 5)
+                assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+        }
+        for (int i = 7; i < 11; i++)
+            assertFalse("Failed to clear bit " + i, bs.get(i));
+
+        for (int i = 11; i < initialSize; i++) {
+            if (i == 15)
+                assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+        }
+
+        for (int i = initialSize; i < bs.size(); i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = new BitSet(16);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(7, 64);
+        assertEquals("Failed to grow BitSet", 64, bs.size());
+        for (int i = 0; i < 7; i++)
+            assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+        for (int i = 7; i < 64; i++)
+            assertFalse("Failed to clear bit " + i, bs.get(i));
+        for (int i = 64; i < bs.size(); i++) {
+            assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+        }
+        // more boundary testing
+        bs = new BitSet(32);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(0, 64);
+        for (int i = 0; i < 64; i++)
+            assertFalse("Failed to clear bit " + i, bs.get(i));
+        for (int i = 64; i < bs.size(); i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+
+        bs = new BitSet(32);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(0, 65);
+        for (int i = 0; i < 65; i++)
+            assertFalse("Failed to clear bit " + i, bs.get(i));
+        for (int i = 65; i < bs.size(); i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = new BitSet(128);
+        initialSize = bs.size();
+        bs.set(0, initialSize);
+        bs.clear(7);
+        bs.clear(110);
+        bs.clear(9, 74);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7)
+                assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+        }
+        for (int i = 9; i < 74; i++)
+            assertFalse("Failed to clear bit " + i, bs.get(i));
+        for (int i = 74; i < initialSize; i++) {
+            if (i == 110)
+                assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+        }
+        for (int i = initialSize; i < bs.size(); i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = new BitSet(256);
+        bs.set(0, 256);
+        bs.clear(7);
+        bs.clear(255);
+        bs.clear(9, 219);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7)
+                assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+        }
+
+        for (int i = 9; i < 219; i++)
+            assertFalse("failed to clear bit " + i, bs.get(i));
+
+        for (int i = 219; i < 255; i++)
+            assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
+
+        for (int i = 255; i < bs.size(); i++)
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+
+        // test illegal args
+        bs = new BitSet(10);
+        try {
+            bs.clear(-1, 3);
+            fail("Test1: Attempt to flip with  negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // excepted
+        }
+
+        try {
+            bs.clear(2, -1);
+            fail("Test2: Attempt to flip with negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // excepted
+        }
+
+        bs.set(2, 4);
+        bs.clear(2, 2);
+        assertTrue("Bit got cleared incorrectly ", bs.get(2));
+
+        try {
+            bs.clear(4, 2);
+            fail("Test4: Attempt to flip with illegal args failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // excepted
+        }
+
+        bs = new BitSet(0);
+        assertEquals("Test1: Wrong length,", 0, bs.length());
+        assertEquals("Test1: Wrong size,", 0, bs.size());
+
+        bs.clear(0, 2);
+        assertEquals("Test2: Wrong length,", 0, bs.length());
+        assertEquals("Test2: Wrong size,", 0, bs.size());
+
+        bs.clear(60, 64);
+        assertEquals("Test3: Wrong length,", 0, bs.length());
+        assertEquals("Test3: Wrong size,", 0, bs.size());
+
+        bs.clear(64, 120);
+        assertEquals("Test4: Wrong length,", 0, bs.length());
+        assertEquals("Test4: Wrong size,", 0, bs.size());
+
+        bs.set(25);
+        assertEquals("Test5: Wrong length,", 26, bs.length());
+        assertEquals("Test5: Wrong size,", 64, bs.size());
+
+        bs.clear(60, 64);
+        assertEquals("Test6: Wrong length,", 26, bs.length());
+        assertEquals("Test6: Wrong size,", 64, bs.size());
+
+        bs.clear(64, 120);
+        assertEquals("Test7: Wrong size,", 64, bs.size());
+        assertEquals("Test7: Wrong length,", 26, bs.length());
+
+        bs.clear(80);
+        assertEquals("Test8: Wrong size,", 64, bs.size());
+        assertEquals("Test8: Wrong length,", 26, bs.length());
+
+        bs.clear(25);
+        assertEquals("Test9: Wrong size,", 64, bs.size());
+        assertEquals("Test9: Wrong length,", 0, bs.length());
     }
 
     /**
-     * @tests java.util.BitSet#flip(int, int)
+     * @tests java.util.BitSet#get(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IndexOutOfBoundsException is not verified.",
-        method = "flip",
-        args = {int.class, int.class}
-    )
+    public void test_getI() {
+        // Test for method boolean java.util.BitSet.get(int)
+
+        BitSet bs = new BitSet();
+        bs.set(8);
+        assertFalse("Get returned true for index out of range", eightbs.get(99));
+        assertTrue("Get returned false for set value", eightbs.get(3));
+        assertFalse("Get returned true for a non set value", bs.get(0));
+
+        try {
+            bs.get(-1);
+            fail("Attempt to get at negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behaviour
+        }
+
+        bs = new BitSet(1);
+        assertFalse("Access greater than size", bs.get(64));
+
+        bs = new BitSet();
+        bs.set(63);
+        assertTrue("Test highest bit", bs.get(63));
+
+        bs = new BitSet(0);
+        assertEquals("Test1: Wrong length,", 0, bs.length());
+        assertEquals("Test1: Wrong size,", 0, bs.size());
+
+        bs.get(2);
+        assertEquals("Test2: Wrong length,", 0, bs.length());
+        assertEquals("Test2: Wrong size,", 0, bs.size());
+
+        bs.get(70);
+        assertEquals("Test3: Wrong length,", 0, bs.length());
+        assertEquals("Test3: Wrong size,", 0, bs.size());
+
+    }
+
+    /**
+     * @tests java.util.BitSet#get(int, int)
+     */
+    public void test_getII() {
+        BitSet bitset = new BitSet(30);
+        bitset.get(3, 3);
+               
+        // Test for method boolean java.util.BitSet.get(int, int)
+        BitSet bs, resultbs, correctbs;
+        bs = new BitSet(512);
+        bs.set(3, 9);
+        bs.set(10, 20);
+        bs.set(60, 75);
+        bs.set(121);
+        bs.set(130, 140);
+
+        // pos1 and pos2 are in the same bitset element, at index0
+        resultbs = bs.get(3, 6);
+        correctbs = new BitSet(3);
+        correctbs.set(0, 3);
+        assertEquals("Test1: Returned incorrect BitSet", correctbs, resultbs);
+
+        // pos1 and pos2 are in the same bitset element, at index 1
+        resultbs = bs.get(100, 125);
+        correctbs = new BitSet(25);
+        correctbs.set(21);
+        assertEquals("Test2: Returned incorrect BitSet", correctbs, resultbs);
+
+        // pos1 in bitset element at index 0, and pos2 in bitset element at
+        // index 1
+        resultbs = bs.get(15, 125);
+        correctbs = new BitSet(25);
+        correctbs.set(0, 5);
+        correctbs.set(45, 60);
+        correctbs.set(121 - 15);
+        assertEquals("Test3: Returned incorrect BitSet", correctbs, resultbs);
+
+        // pos1 in bitset element at index 1, and pos2 in bitset element at
+        // index 2
+        resultbs = bs.get(70, 145);
+        correctbs = new BitSet(75);
+        correctbs.set(0, 5);
+        correctbs.set(51);
+        correctbs.set(60, 70);
+        assertEquals("Test4: Returned incorrect BitSet", correctbs, resultbs);
+
+        // pos1 in bitset element at index 0, and pos2 in bitset element at
+        // index 2
+        resultbs = bs.get(5, 145);
+        correctbs = new BitSet(140);
+        correctbs.set(0, 4);
+        correctbs.set(5, 15);
+        correctbs.set(55, 70);
+        correctbs.set(116);
+        correctbs.set(125, 135);
+        assertEquals("Test5: Returned incorrect BitSet", correctbs, resultbs);
+
+        // pos1 in bitset element at index 0, and pos2 in bitset element at
+        // index 3
+        resultbs = bs.get(5, 250);
+        correctbs = new BitSet(200);
+        correctbs.set(0, 4);
+        correctbs.set(5, 15);
+        correctbs.set(55, 70);
+        correctbs.set(116);
+        correctbs.set(125, 135);
+        assertEquals("Test6: Returned incorrect BitSet", correctbs, resultbs);
+
+        assertEquals("equality principle 1 ", bs.get(0, bs.size()), bs);
+
+        // more tests
+        BitSet bs2 = new BitSet(129);
+        bs2.set(0, 20);
+        bs2.set(62, 65);
+        bs2.set(121, 123);
+        resultbs = bs2.get(1, 124);
+        correctbs = new BitSet(129);
+        correctbs.set(0, 19);
+        correctbs.set(61, 64);
+        correctbs.set(120, 122);
+        assertEquals("Test7: Returned incorrect BitSet", correctbs, resultbs);
+
+        // equality principle with some boundary conditions
+        bs2 = new BitSet(128);
+        bs2.set(2, 20);
+        bs2.set(62);
+        bs2.set(121, 123);
+        bs2.set(127);
+        resultbs = bs2.get(0, bs2.size());
+        assertEquals("equality principle 2 ", resultbs, bs2);
+
+        bs2 = new BitSet(128);
+        bs2.set(2, 20);
+        bs2.set(62);
+        bs2.set(121, 123);
+        bs2.set(127);
+        bs2.flip(0, 128);
+        resultbs = bs2.get(0, bs.size());
+        assertEquals("equality principle 3 ", resultbs, bs2);
+
+        bs = new BitSet(0);
+        assertEquals("Test1: Wrong length,", 0, bs.length());
+        assertEquals("Test1: Wrong size,", 0, bs.size());
+
+        bs.get(0, 2);
+        assertEquals("Test2: Wrong length,", 0, bs.length());
+        assertEquals("Test2: Wrong size,", 0, bs.size());
+
+        bs.get(60, 64);
+        assertEquals("Test3: Wrong length,", 0, bs.length());
+        assertEquals("Test3: Wrong size,", 0, bs.size());
+
+        bs.get(64, 120);
+        assertEquals("Test4: Wrong length,", 0, bs.length());
+        assertEquals("Test4: Wrong size,", 0, bs.size());
+
+        bs.set(25);
+        assertEquals("Test5: Wrong length,", 26, bs.length());
+        assertEquals("Test5: Wrong size,", 64, bs.size());
+
+        bs.get(60, 64);
+        assertEquals("Test6: Wrong length,", 26, bs.length());
+        assertEquals("Test6: Wrong size,", 64, bs.size());
+
+        bs.get(64, 120);
+        assertEquals("Test7: Wrong size,", 64, bs.size());
+        assertEquals("Test7: Wrong length,", 26, bs.length());
+
+        bs.get(80);
+        assertEquals("Test8: Wrong size,", 64, bs.size());
+        assertEquals("Test8: Wrong length,", 26, bs.length());
+
+        bs.get(25);
+        assertEquals("Test9: Wrong size,", 64, bs.size());
+        assertEquals("Test9: Wrong length,", 26, bs.length());
+
+    }
+
+    /**
+     * @tests java.util.BitSet#flip(int)
+     */
+    public void test_flipI() {
+        // Test for method void java.util.BitSet.flip(int)
+        BitSet bs = new BitSet();
+        bs.clear(8);
+        bs.clear(9);
+        bs.set(10);
+        bs.flip(9);
+        assertFalse("Failed to flip bit", bs.get(8));
+        assertTrue("Failed to flip bit", bs.get(9));
+        assertTrue("Failed to flip bit", bs.get(10));
+
+        bs.set(8);
+        bs.set(9);
+        bs.clear(10);
+        bs.flip(9);
+        assertTrue("Failed to flip bit", bs.get(8));
+        assertFalse("Failed to flip bit", bs.get(9));
+        assertFalse("Failed to flip bit", bs.get(10));
+
+        try {
+            bs.flip(-1);
+            fail("Attempt to flip at negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behaviour
+        }
+
+        // Try setting a bit on a 64 boundary
+        bs.flip(128);
+        assertEquals("Failed to grow BitSet", 192, bs.size());
+        assertTrue("Failed to flip bit", bs.get(128));
+
+        bs = new BitSet(64);
+        for (int i = bs.size(); --i >= 0;) {
+            bs.flip(i);
+            assertTrue("Test1: Incorrectly flipped bit" + i, bs.get(i));
+            assertEquals("Incorrect length", i+1, bs.length());
+            for (int j = bs.size(); --j > i;) {
+                assertTrue("Test2: Incorrectly flipped bit" + j, !bs.get(j));
+            }
+            for (int j = i; --j >= 0;) {
+                assertTrue("Test3: Incorrectly flipped bit" + j, !bs.get(j));
+            }
+            bs.flip(i);
+        }
+
+        BitSet bs0 = new BitSet(0);
+        assertEquals("Test1: Wrong size", 0, bs0.size());
+        assertEquals("Test1: Wrong length", 0, bs0.length());
+
+        bs0.flip(0);
+        assertEquals("Test2: Wrong size", 64, bs0.size());
+        assertEquals("Test2: Wrong length", 1, bs0.length());
+
+        bs0.flip(63);
+        assertEquals("Test3: Wrong size", 64, bs0.size());
+        assertEquals("Test3: Wrong length", 64, bs0.length());
+
+        eightbs.flip(7);
+        assertTrue("Failed to flip bit 7", !eightbs.get(7));
+
+        // Check to see all other bits are still set
+        for (int i = 0; i < 7; i++)
+            assertTrue("Flip flipped incorrect bits", eightbs.get(i));
+
+        eightbs.flip(127);
+        assertTrue("Failed to flip bit 127", eightbs.get(127));
+
+        eightbs.flip(127);
+        assertTrue("Failed to flip bit 127", !eightbs.get(127));
+    }
+
+    /**
+     * @tests java.util.BitSet#clear(int, int)
+     */
     public void test_flipII() {
         BitSet bitset = new BitSet();
         for (int i = 0; i < 20; i++) {
             bitset.set(i);
         }
         bitset.flip(10, 10);
+               
+        // Test for method void java.util.BitSet.flip(int, int)
+        // pos1 and pos2 are in the same bitset element
+        BitSet bs = new BitSet(16);
+        bs.set(7);
+        bs.set(10);
+        bs.flip(7, 11);
+        for (int i = 0; i < 7; i++) {
+            assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+        }
+        assertFalse("Failed to flip bit 7", bs.get(7));
+        assertTrue("Failed to flip bit 8", bs.get(8));
+        assertTrue("Failed to flip bit 9", bs.get(9));
+        assertFalse("Failed to flip bit 10", bs.get(10));
+        for (int i = 11; i < bs.size(); i++) {
+            assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = new BitSet(16);
+        bs.set(7);
+        bs.set(10);
+        bs.flip(7, 64);
+        assertEquals("Failed to grow BitSet", 64, bs.size());
+        for (int i = 0; i < 7; i++) {
+            assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+        }
+        assertFalse("Failed to flip bit 7", bs.get(7));
+        assertTrue("Failed to flip bit 8", bs.get(8));
+        assertTrue("Failed to flip bit 9", bs.get(9));
+        assertFalse("Failed to flip bit 10", bs.get(10));
+        for (int i = 11; i < 64; i++) {
+            assertTrue("failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have flipped bit 64", bs.get(64));
+
+        // more boundary testing
+        bs = new BitSet(32);
+        bs.flip(0, 64);
+        for (int i = 0; i < 64; i++) {
+            assertTrue("Failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have flipped bit 64", bs.get(64));
+
+        bs = new BitSet(32);
+        bs.flip(0, 65);
+        for (int i = 0; i < 65; i++) {
+            assertTrue("Failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have flipped bit 65", bs.get(65));
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = new BitSet(128);
+        bs.set(7);
+        bs.set(10);
+        bs.set(72);
+        bs.set(110);
+        bs.flip(9, 74);
+        for (int i = 0; i < 7; i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+        assertTrue("Shouldn't have flipped bit 7", bs.get(7));
+        assertFalse("Shouldn't have flipped bit 8", bs.get(8));
+        assertTrue("Failed to flip bit 9", bs.get(9));
+        assertFalse("Failed to flip bit 10", bs.get(10));
+        for (int i = 11; i < 72; i++) {
+            assertTrue("failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Failed to flip bit 72", bs.get(72));
+        assertTrue("Failed to flip bit 73", bs.get(73));
+        for (int i = 74; i < 110; i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+        assertTrue("Shouldn't have flipped bit 110", bs.get(110));
+        for (int i = 111; i < bs.size(); i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = new BitSet(256);
+        bs.set(7);
+        bs.set(10);
+        bs.set(72);
+        bs.set(110);
+        bs.set(181);
+        bs.set(220);
+        bs.flip(9, 219);
+        for (int i = 0; i < 7; i++) {
+            assertFalse("Shouldn't have flipped bit " + i, bs.get(i));
+        }
+        assertTrue("Shouldn't have flipped bit 7", bs.get(7));
+        assertFalse("Shouldn't have flipped bit 8", bs.get(8));
+        assertTrue("Failed to flip bit 9", bs.get(9));
+        assertFalse("Failed to flip bit 10", bs.get(10));
+        for (int i = 11; i < 72; i++) {
+            assertTrue("failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Failed to flip bit 72", bs.get(72));
+        for (int i = 73; i < 110; i++) {
+            assertTrue("failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Failed to flip bit 110", bs.get(110));
+        for (int i = 111; i < 181; i++) {
+            assertTrue("failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Failed to flip bit 181", bs.get(181));
+        for (int i = 182; i < 219; i++) {
+            assertTrue("failed to flip bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have flipped bit 219", bs.get(219));
+        assertTrue("Shouldn't have flipped bit 220", bs.get(220));
+        for (int i = 221; i < bs.size(); i++) {
+            assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
+        }
+
+        // test illegal args
+        bs = new BitSet(10);
+        try {
+            bs.flip(-1, 3);
+            fail("Test1: Attempt to flip with  negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+
+        try {
+            bs.flip(2, -1);
+            fail("Test2: Attempt to flip with negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+
+        try {
+            bs.flip(4, 2);
+            fail("Test4: Attempt to flip with illegal args failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // correct behavior
+        }
     }
 
     /**
-     * @tests java.util.BitSet#get(int, int)
+     * @tests java.util.BitSet#set(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IndexOutOfBoundsException is not verified.",
-        method = "get",
-        args = {int.class, int.class}
-    )
-    public void test_getII() {
-        BitSet bitset = new BitSet(30);
-        bitset.get(3, 3);
+    public void test_setI() {
+        // Test for method void java.util.BitSet.set(int)
+
+        BitSet bs = new BitSet();
+        bs.set(8);
+        assertTrue("Failed to set bit", bs.get(8));
+
+        try {
+            bs.set(-1);
+            fail("Attempt to set at negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behaviour
+        }
+
+        // Try setting a bit on a 64 boundary
+        bs.set(128);
+        assertEquals("Failed to grow BitSet", 192, bs.size());
+        assertTrue("Failed to set bit", bs.get(128));
+
+        bs = new BitSet(64);
+        for (int i = bs.size(); --i >= 0;) {
+            bs.set(i);
+            assertTrue("Incorrectly set", bs.get(i));
+            assertEquals("Incorrect length", i+1, bs.length());
+            for (int j = bs.size(); --j > i;)
+                assertFalse("Incorrectly set bit " + j, bs.get(j));
+            for (int j = i; --j >= 0;)
+                assertFalse("Incorrectly set bit " + j, bs.get(j));
+            bs.clear(i);
+        }
+
+        bs = new BitSet(0);
+        assertEquals("Test1: Wrong length", 0, bs.length());
+        bs.set(0);
+        assertEquals("Test2: Wrong length", 1, bs.length());
+    }
+
+    /**
+     * @tests java.util.BitSet#set(int, boolean)
+     */
+    public void test_setIZ() {
+        // Test for method void java.util.BitSet.set(int, boolean)
+        eightbs.set(5, false);
+        assertFalse("Should have set bit 5 to true", eightbs.get(5));
+
+        eightbs.set(5, true);
+        assertTrue("Should have set bit 5 to false", eightbs.get(5));
     }
 
     /**
      * @tests java.util.BitSet#set(int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IndexOutOfBoundsException is not verified.",
-        method = "set",
-        args = {int.class, int.class}
-    )
-    public void test_setII() {
+    public void test_setII() throws IndexOutOfBoundsException {
         BitSet bitset = new BitSet(30);
         bitset.set(29, 29);
+        
+        // Test for method void java.util.BitSet.set(int, int)
+        // pos1 and pos2 are in the same bitset element
+        BitSet bs = new BitSet(16);
+        bs.set(5);
+        bs.set(15);
+        bs.set(7, 11);
+        for (int i = 0; i < 7; i++) {
+            if (i == 5)
+                assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+        for (int i = 7; i < 11; i++)
+            assertTrue("Failed to set bit " + i, bs.get(i));
+        for (int i = 11; i < bs.size(); i++) {
+            if (i == 15)
+                assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+
+        // pos1 and pos2 is in the same bitset element, boundry testing
+        bs = new BitSet(16);
+        bs.set(7, 64);
+        assertEquals("Failed to grow BitSet", 64, bs.size());
+        for (int i = 0; i < 7; i++) {
+            assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+        for (int i = 7; i < 64; i++) {
+            assertTrue("Failed to set bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have set bit 64", bs.get(64));
+
+        // more boundary testing
+        bs = new BitSet(32);
+        bs.set(0, 64);
+        for (int i = 0; i < 64; i++) {
+            assertTrue("Failed to set bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have set bit 64", bs.get(64));
+
+        bs = new BitSet(32);
+        bs.set(0, 65);
+        for (int i = 0; i < 65; i++) {
+            assertTrue("Failed to set bit " + i, bs.get(i));
+        }
+        assertFalse("Shouldn't have set bit 65", bs.get(65));
+
+        // pos1 and pos2 are in two sequential bitset elements
+        bs = new BitSet(128);
+        bs.set(7);
+        bs.set(110);
+        bs.set(9, 74);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7)
+                assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+        for (int i = 9; i < 74; i++) {
+            assertTrue("Failed to set bit " + i, bs.get(i));
+        }
+        for (int i = 74; i < bs.size(); i++) {
+            if (i == 110)
+                assertTrue("Shouldn't have flipped bit " + i, bs.get(i));
+            else
+                assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+
+        // pos1 and pos2 are in two non-sequential bitset elements
+        bs = new BitSet(256);
+        bs.set(7);
+        bs.set(255);
+        bs.set(9, 219);
+        for (int i = 0; i < 9; i++) {
+            if (i == 7)
+                assertTrue("Shouldn't have set flipped " + i, bs.get(i));
+            else
+                assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+
+        for (int i = 9; i < 219; i++) {
+            assertTrue("failed to set bit " + i, bs.get(i));
+        }
+
+        for (int i = 219; i < 255; i++) {
+            assertFalse("Shouldn't have set bit " + i, bs.get(i));
+        }
+
+        assertTrue("Shouldn't have flipped bit 255", bs.get(255));
+
+        // test illegal args
+        bs = new BitSet(10);
+        try {
+            bs.set(-1, 3);
+            fail("Test1: Attempt to flip with  negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        try {
+            bs.set(2, -1);
+            fail("Test2: Attempt to flip with negative index failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
+
+        bs.set(2, 2);
+        assertFalse("Bit got set incorrectly ", bs.get(2));
+
+        try {
+            bs.set(4, 2);
+            fail("Test4: Attempt to flip with illegal args failed to generate exception");
+        } catch (IndexOutOfBoundsException e) {
+            // Correct behavior
+        }
     }
+
+    /**
+     * @tests java.util.BitSet#set(int, int, boolean)
+     */
+    public void test_setIIZ() {
+        // Test for method void java.util.BitSet.set(int, int, boolean)
+        eightbs.set(3, 6, false);
+        assertTrue("Should have set bits 3, 4, and 5 to false", !eightbs.get(3)
+                && !eightbs.get(4) && !eightbs.get(5));
+
+        eightbs.set(3, 6, true);
+        assertTrue("Should have set bits 3, 4, and 5 to true", eightbs.get(3)
+                && eightbs.get(4) && eightbs.get(5));
+
+    }
+
+    /**
+     * @tests java.util.BitSet#intersects(java.util.BitSet)
+     */
+    public void test_intersectsLjava_util_BitSet() {
+        // Test for method boolean java.util.BitSet.intersects(java.util.BitSet)
+        BitSet bs = new BitSet(500);
+        bs.set(5);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(192);
+        bs.set(450);
+
+        BitSet bs2 = new BitSet(8);
+        assertFalse("Test1: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertFalse("Test1: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.set(4);
+        assertFalse("Test2: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertFalse("Test2: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(5);
+        assertTrue("Test3: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertTrue("Test3: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(63);
+        assertTrue("Test4: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertTrue("Test4: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(80);
+        assertTrue("Test5: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertTrue("Test5: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(127);
+        assertTrue("Test6: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertTrue("Test6: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(192);
+        assertTrue("Test7: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertTrue("Test7: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(450);
+        assertTrue("Test8: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertTrue("Test8: intersects() returned incorrect value", bs2
+                .intersects(bs));
+
+        bs2.clear();
+        bs2.set(500);
+        assertFalse("Test9: intersects() returned incorrect value", bs
+                .intersects(bs2));
+        assertFalse("Test9: intersects() returned incorrect value", bs2
+                .intersects(bs));
+    }
+
+    /**
+     * @tests java.util.BitSet#and(java.util.BitSet)
+     */
+    public void test_andLjava_util_BitSet() {
+        // Test for method void java.util.BitSet.and(java.util.BitSet)
+        BitSet bs = new BitSet(128);
+        // Initialize the bottom half of the BitSet
+
+        for (int i = 64; i < 128; i++)
+            bs.set(i);
+        eightbs.and(bs);
+        assertFalse("AND failed to clear bits", eightbs.equals(bs));
+        eightbs.set(3);
+        bs.set(3);
+        eightbs.and(bs);
+        assertTrue("AND failed to maintain set bits", bs.get(3));
+        bs.and(eightbs);
+        for (int i = 64; i < 128; i++) {
+            assertFalse("Failed to clear extra bits in the receiver BitSet", bs
+                    .get(i));
+        }
+    }
+
+    /**
+     * @tests java.util.BitSet#andNot(java.util.BitSet)
+     */
+    public void test_andNotLjava_util_BitSet() {
+        BitSet bs = (BitSet) eightbs.clone();
+        bs.clear(5);
+        BitSet bs2 = new BitSet();
+        bs2.set(2);
+        bs2.set(3);
+        bs.andNot(bs2);
+        assertEquals("Incorrect bitset after andNot",
+                     "{0, 1, 4, 6, 7}", bs.toString());
+
+        bs = new BitSet(0);
+        bs.andNot(bs2);
+        assertEquals("Incorrect size", 0, bs.size());
+    }
+
+    /**
+     * @tests java.util.BitSet#or(java.util.BitSet)
+     */
+    public void test_orLjava_util_BitSet() {
+        // Test for method void java.util.BitSet.or(java.util.BitSet)
+        BitSet bs = new BitSet(128);
+        bs.or(eightbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue("OR failed to set bits", bs.get(i));
+        }
+
+        bs = new BitSet(0);
+        bs.or(eightbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue("OR(0) failed to set bits", bs.get(i));
+        }
+
+        eightbs.clear(5);
+        bs = new BitSet(128);
+        bs.or(eightbs);
+        assertFalse("OR set a bit which should be off", bs.get(5));
+    }
+
+    /**
+     * @tests java.util.BitSet#xor(java.util.BitSet)
+     */
+    public void test_xorLjava_util_BitSet() {
+        // Test for method void java.util.BitSet.xor(java.util.BitSet)
+
+        BitSet bs = (BitSet) eightbs.clone();
+        bs.xor(eightbs);
+        for (int i = 0; i < 8; i++) {
+            assertFalse("XOR failed to clear bits", bs.get(i));
+        }
+
+        bs.xor(eightbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue("XOR failed to set bits", bs.get(i));
+        }
+
+        bs = new BitSet(0);
+        bs.xor(eightbs);
+        for (int i = 0; i < 8; i++) {
+            assertTrue("XOR(0) failed to set bits", bs.get(i));
+        }
+
+        bs = new BitSet();
+        bs.set(63);
+        assertEquals("Test highest bit", "{63}", bs.toString());
+    }
+
+    /**
+     * @tests java.util.BitSet#size()
+     */
+    public void test_size() {
+        // Test for method int java.util.BitSet.size()
+        assertEquals("Returned incorrect size", 64, eightbs.size());
+        eightbs.set(129);
+        assertTrue("Returned incorrect size", eightbs.size() >= 129);
+
+    }
+
+    /**
+     * @tests java.util.BitSet#toString()
+     */
+    public void test_toString() {
+        // Test for method java.lang.String java.util.BitSet.toString()
+        assertEquals("Returned incorrect string representation",
+                     "{0, 1, 2, 3, 4, 5, 6, 7}", eightbs.toString());
+        eightbs.clear(2);
+        assertEquals("Returned incorrect string representation",
+                     "{0, 1, 3, 4, 5, 6, 7}", eightbs.toString());
+    }
+
+    /**
+     * @tests java.util.BitSet#length()
+     */
+    public void test_length() {
+        BitSet bs = new BitSet();
+        assertEquals("BitSet returned wrong length", 0, bs.length());
+        bs.set(5);
+        assertEquals("BitSet returned wrong length", 6, bs.length());
+        bs.set(10);
+        assertEquals("BitSet returned wrong length", 11, bs.length());
+        bs.set(432);
+        assertEquals("BitSet returned wrong length", 433, bs.length());
+        bs.set(300);
+        assertEquals("BitSet returned wrong length", 433, bs.length());
+    }
+
+    /**
+     * @tests java.util.BitSet#nextSetBit(int)
+     */
+    public void test_nextSetBitI() {
+        // Test for method int java.util.BitSet.nextSetBit()
+        BitSet bs = new BitSet(500);
+        bs.set(5);
+        bs.set(32);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(193);
+        bs.set(450);
+        try {
+            bs.nextSetBit(-1);
+            fail("Expected IndexOutOfBoundsException for negative index");
+        } catch (IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+        assertEquals("nextSetBit() returned the wrong value", 5, bs
+                .nextSetBit(0));
+        assertEquals("nextSetBit() returned the wrong value", 5, bs
+                .nextSetBit(5));
+        assertEquals("nextSetBit() returned the wrong value", 32, bs
+                .nextSetBit(6));
+        assertEquals("nextSetBit() returned the wrong value", 32, bs
+                .nextSetBit(32));
+        assertEquals("nextSetBit() returned the wrong value", 63, bs
+                .nextSetBit(33));
+
+        // boundary tests
+        assertEquals("nextSetBit() returned the wrong value", 63, bs
+                .nextSetBit(63));
+        assertEquals("nextSetBit() returned the wrong value", 64, bs
+                .nextSetBit(64));
+
+        // at bitset element 1
+        assertEquals("nextSetBit() returned the wrong value", 71, bs
+                .nextSetBit(65));
+        assertEquals("nextSetBit() returned the wrong value", 71, bs
+                .nextSetBit(71));
+        assertEquals("nextSetBit() returned the wrong value", 72, bs
+                .nextSetBit(72));
+        assertEquals("nextSetBit() returned the wrong value", 127, bs
+                .nextSetBit(110));
+
+        // boundary tests
+        assertEquals("nextSetBit() returned the wrong value", 127, bs
+                .nextSetBit(127));
+        assertEquals("nextSetBit() returned the wrong value", 128, bs
+                .nextSetBit(128));
+
+        // at bitset element 2
+        assertEquals("nextSetBit() returned the wrong value", 193, bs
+                .nextSetBit(130));
+
+        assertEquals("nextSetBit() returned the wrong value", 193, bs
+                .nextSetBit(191));
+        assertEquals("nextSetBit() returned the wrong value", 193, bs
+                .nextSetBit(192));
+        assertEquals("nextSetBit() returned the wrong value", 193, bs
+                .nextSetBit(193));
+        assertEquals("nextSetBit() returned the wrong value", 450, bs
+                .nextSetBit(194));
+        assertEquals("nextSetBit() returned the wrong value", 450, bs
+                .nextSetBit(255));
+        assertEquals("nextSetBit() returned the wrong value", 450, bs
+                .nextSetBit(256));
+        assertEquals("nextSetBit() returned the wrong value", 450, bs
+                .nextSetBit(450));
+
+        assertEquals("nextSetBit() returned the wrong value", -1, bs
+                .nextSetBit(451));
+        assertEquals("nextSetBit() returned the wrong value", -1, bs
+                .nextSetBit(511));
+        assertEquals("nextSetBit() returned the wrong value", -1, bs
+                .nextSetBit(512));
+        assertEquals("nextSetBit() returned the wrong value", -1, bs
+                .nextSetBit(800));
+    }
+
+    /**
+     * @tests java.util.BitSet#nextClearBit(int)
+     */
+    public void test_nextClearBitI() {
+        // Test for method int java.util.BitSet.nextSetBit()
+        BitSet bs = new BitSet(500);
+        bs.set(0, bs.size() - 1); // ensure all the bits from 0 to bs.size()
+                                    // -1
+        bs.set(bs.size() - 1); // are set to true
+        bs.clear(5);
+        bs.clear(32);
+        bs.clear(63);
+        bs.clear(64);
+        bs.clear(71, 110);
+        bs.clear(127, 130);
+        bs.clear(193);
+        bs.clear(450);
+        try {
+            bs.nextClearBit(-1);
+            fail("Expected IndexOutOfBoundsException for negative index");
+        } catch (IndexOutOfBoundsException e) {
+            // correct behavior
+        }
+        assertEquals("nextClearBit() returned the wrong value", 5, bs
+                .nextClearBit(0));
+        assertEquals("nextClearBit() returned the wrong value", 5, bs
+                .nextClearBit(5));
+        assertEquals("nextClearBit() returned the wrong value", 32, bs
+                .nextClearBit(6));
+        assertEquals("nextClearBit() returned the wrong value", 32, bs
+                .nextClearBit(32));
+        assertEquals("nextClearBit() returned the wrong value", 63, bs
+                .nextClearBit(33));
+
+        // boundary tests
+        assertEquals("nextClearBit() returned the wrong value", 63, bs
+                .nextClearBit(63));
+        assertEquals("nextClearBit() returned the wrong value", 64, bs
+                .nextClearBit(64));
+
+        // at bitset element 1
+        assertEquals("nextClearBit() returned the wrong value", 71, bs
+                .nextClearBit(65));
+        assertEquals("nextClearBit() returned the wrong value", 71, bs
+                .nextClearBit(71));
+        assertEquals("nextClearBit() returned the wrong value", 72, bs
+                .nextClearBit(72));
+        assertEquals("nextClearBit() returned the wrong value", 127, bs
+                .nextClearBit(110));
+
+        // boundary tests
+        assertEquals("nextClearBit() returned the wrong value", 127, bs
+                .nextClearBit(127));
+        assertEquals("nextClearBit() returned the wrong value", 128, bs
+                .nextClearBit(128));
+
+        // at bitset element 2
+        assertEquals("nextClearBit() returned the wrong value", 193, bs
+                .nextClearBit(130));
+        assertEquals("nextClearBit() returned the wrong value", 193, bs
+                .nextClearBit(191));
+
+        assertEquals("nextClearBit() returned the wrong value", 193, bs
+                .nextClearBit(192));
+        assertEquals("nextClearBit() returned the wrong value", 193, bs
+                .nextClearBit(193));
+        assertEquals("nextClearBit() returned the wrong value", 450, bs
+                .nextClearBit(194));
+        assertEquals("nextClearBit() returned the wrong value", 450, bs
+                .nextClearBit(255));
+        assertEquals("nextClearBit() returned the wrong value", 450, bs
+                .nextClearBit(256));
+        assertEquals("nextClearBit() returned the wrong value", 450, bs
+                .nextClearBit(450));
+
+        // bitset has 1 still the end of bs.size() -1, but calling nextClearBit
+        // with any index value
+        // after the last true bit should return bs.size(),
+        assertEquals("nextClearBit() returned the wrong value", 512, bs
+                .nextClearBit(451));
+        assertEquals("nextClearBit() returned the wrong value", 512, bs
+                .nextClearBit(511));
+        assertEquals("nextClearBit() returned the wrong value", 512, bs
+                .nextClearBit(512));
+
+        // if the index is larger than bs.size(), nextClearBit should return
+        // index;
+        assertEquals("nextClearBit() returned the wrong value", 513, bs
+                .nextClearBit(513));
+        assertEquals("nextClearBit() returned the wrong value", 800, bs
+                .nextClearBit(800));
+    }
+
+    /**
+     * @tests java.util.BitSet#isEmpty()
+     */
+    public void test_isEmpty() {
+        BitSet bs = new BitSet(500);
+        assertTrue("Test: isEmpty() returned wrong value", bs.isEmpty());
+
+        // at bitset element 0
+        bs.set(3);
+        assertFalse("Test0: isEmpty() returned wrong value", bs.isEmpty());
+
+        // at bitset element 1
+        bs.clear();
+        bs.set(12);
+        assertFalse("Test1: isEmpty() returned wrong value", bs.isEmpty());
+
+        // at bitset element 2
+        bs.clear();
+        bs.set(128);
+        assertFalse("Test2: isEmpty() returned wrong value", bs.isEmpty());
+
+        // boundary testing
+        bs.clear();
+        bs.set(459);
+        assertFalse("Test3: isEmpty() returned wrong value", bs.isEmpty());
+
+        bs.clear();
+        bs.set(511);
+        assertFalse("Test4: isEmpty() returned wrong value", bs.isEmpty());
+    }
+
+    /**
+     * @tests java.util.BitSet#cardinality()
+     */
+    public void test_cardinality() {
+        // test for method int java.util.BitSet.cardinality()
+        BitSet bs = new BitSet(500);
+        bs.set(5);
+        bs.set(32);
+        bs.set(63);
+        bs.set(64);
+        bs.set(71, 110);
+        bs.set(127, 130);
+        bs.set(193);
+        bs.set(450);
+        assertEquals("cardinality() returned wrong value", 48, bs.cardinality());
+
+        bs.flip(0, 500);
+        assertEquals("cardinality() returned wrong value", 452, bs
+                .cardinality());
+
+        bs.clear();
+        assertEquals("cardinality() returned wrong value", 0, bs.cardinality());
+
+        bs.set(0, 500);
+        assertEquals("cardinality() returned wrong value", 500, bs
+                .cardinality());
+    }
+
+    protected void setUp() {
+
+        eightbs = new BitSet();
+
+        for (int i = 0; i < 8; i++)
+            eightbs.set(i);
+    }
+
+    protected void tearDown() {
+    }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DateTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DateTest.java
index cb4097b..e11d5a3 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DateTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DateTest.java
@@ -1,49 +1,505 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
+import java.util.Calendar;
 import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
 
-@TestTargetClass(Date.class) 
-public class DateTest extends TestCase {
+public class DateTest extends junit.framework.TestCase {
+    
+    static class MockDate extends Date{
+        private String holiday;
 
-    /**
-     * @tests java.util.Date#parse(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Special regression test. Doesn't verify all cases according to the specification.",
-        method = "parse",
-        args = {java.lang.String.class}
-    )
-    @SuppressWarnings("deprecation")
-    public void test_parseLjava_lang_String() {
+        public MockDate(long theTime) {
+            super(theTime);
+            holiday = "Christmas";
+        }
+        
+        // Constructor should not call this public API,
+        // since it may be overrided to use variables uninitialized.
+        public void setTime(long theTime){
+            super.setTime(theTime);
+            holiday.hashCode();
+        }
+    }
+    
+	/**
+	 * @tests java.util.Date#Date()
+	 */
+	public void test_Constructor() {
+		// Test for method java.util.Date()
+		GregorianCalendar gc = new GregorianCalendar(1998, Calendar.OCTOBER,
+				13, 19, 9);
+		long oldTime = gc.getTime().getTime();
+		long now = new Date().getTime();
+		assertTrue("Created incorrect date: " + oldTime + " now: " + now,
+				oldTime < now);
+	}
+
+	/**
+	 * @tests java.util.Date#Date(int, int, int)
+	 */
+	public void test_ConstructorIII() {
+		// Test for method java.util.Date(int, int, int)
+		Date d1 = new Date(70, 0, 1); // the epoch + local time
+		
+		// the epoch + local time
+		Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000);
+		
+		assertTrue("Created incorrect date", d1.equals(d2));
+
+		Date date = new Date(99, 5, 22);
+		Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 22);
+		assertTrue("Wrong time zone", date.equals(cal.getTime()));
+	}
+
+	/**
+	 * @tests java.util.Date#Date(int, int, int, int, int)
+	 */
+	public void test_ConstructorIIIII() {
+		// Test for method java.util.Date(int, int, int, int, int)
+		
+		// the epoch + local time + (1 hour and 1 minute)
+		Date d1 = new Date(70, 0, 1, 1, 1); 
+
+		// the epoch + local time + (1 hour and 1 minute)
+		Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000 + 60 * 60
+				* 1000 + 60 * 1000);
+
+		assertTrue("Created incorrect date", d1.equals(d2));
+	}
+
+	/**
+	 * @tests java.util.Date#Date(int, int, int, int, int, int)
+	 */
+	public void test_ConstructorIIIIII() {
+		// Test for method java.util.Date(int, int, int, int, int, int)
+		
+		// the epoch + local time + (1 hour and 1 minute + 1 second)
+		Date d1 = new Date(70, 0, 1, 1, 1, 1); 
+		
+		// the epoch + local time + (1 hour and 1 minute + 1 second)
+		Date d2 = new Date(0 + d1.getTimezoneOffset() * 60 * 1000 + 60 * 60
+				* 1000 + 60 * 1000 + 1000);
+		
+		assertTrue("Created incorrect date", d1.equals(d2));
+	}
+
+	/**
+	 * @tests java.util.Date#Date(long)
+	 */
+	public void test_ConstructorJ() {
+		// Test for method java.util.Date(long)
+        Date date = new MockDate(1000L);
+        assertNotNull(date);
+	}
+
+	/**
+	 * @tests java.util.Date#Date(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
+		// Test for method java.util.Date(java.lang.String)
+		Date d1 = new Date("January 1, 1970, 00:00:00 GMT"); // the epoch
+		Date d2 = new Date(0); // the epoch
+		assertTrue("Created incorrect date", d1.equals(d2));
+        
+		try {
+			// Regression for HARMONY-238
+			new Date(null);
+			fail("Constructor Date((String)null) should "
+				+ "throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+	}
+
+	/**
+	 * @tests java.util.Date#after(java.util.Date)
+	 */
+	public void test_afterLjava_util_Date() {
+		// Test for method boolean java.util.Date.after(java.util.Date)
+		Date d1 = new Date(0);
+		Date d2 = new Date(1900000);
+		assertTrue("Older was returned as newer", d2.after(d1));
+		assertTrue("Newer was returned as older", !d1.after(d2));
+	}
+
+	/**
+	 * @tests java.util.Date#before(java.util.Date)
+	 */
+	public void test_beforeLjava_util_Date() {
+		// Test for method boolean java.util.Date.before(java.util.Date)
+		Date d1 = new Date(0);
+		Date d2 = new Date(1900000);
+		assertTrue("Older was returned as newer", !d2.before(d1));
+		assertTrue("Newer was returned as older", d1.before(d2));
+	}
+
+	/**
+	 * @tests java.util.Date#clone()
+	 */
+	public void test_clone() {
+		// Test for method java.lang.Object java.util.Date.clone()
+		Date d1 = new Date(100000);
+		Date d2 = (Date) d1.clone();
+		assertTrue(
+				"Cloning date results in same reference--new date is equivalent",
+				d1 != d2);
+		assertTrue("Cloning date results unequal date", d1.equals(d2));
+	}
+
+	/**
+	 * @tests java.util.Date#compareTo(java.util.Date)
+	 */
+	public void test_compareToLjava_util_Date() {
+		// Test for method int java.util.Date.compareTo(java.util.Date)
+		final int someNumber = 10000;
+		Date d1 = new Date(someNumber);
+		Date d2 = new Date(someNumber);
+		Date d3 = new Date(someNumber + 1);
+		Date d4 = new Date(someNumber - 1);
+		assertEquals("Comparing a date to itself did not answer zero", 0, d1
+				.compareTo(d1));
+		assertEquals("Comparing equal dates did not answer zero", 0, d1
+				.compareTo(d2));
+		assertEquals("date1.compareTo(date2), where date1 > date2, did not result in 1",
+				1, d1.compareTo(d4));
+		assertEquals("date1.compareTo(date2), where date1 < date2, did not result in -1",
+				-1, d1.compareTo(d3));
+
+	}
+
+	/**
+	 * @tests java.util.Date#equals(java.lang.Object)
+	 */
+	public void test_equalsLjava_lang_Object() {
+		// Test for method boolean java.util.Date.equals(java.lang.Object)
+		Date d1 = new Date(0);
+		Date d2 = new Date(1900000);
+		Date d3 = new Date(1900000);
+		assertTrue("Equality test failed", d2.equals(d3));
+		assertTrue("Equality test failed", !d1.equals(d2));
+	}
+
+	/**
+	 * @tests java.util.Date#getDate()
+	 */
+	public void test_getDate() {
+		// Test for method int java.util.Date.getDate()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect date", 13, d.getDate());
+	}
+
+	/**
+	 * @tests java.util.Date#getDay()
+	 */
+	public void test_getDay() {
+		// Test for method int java.util.Date.getDay()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect day", 2, d.getDay());
+	}
+
+	/**
+	 * @tests java.util.Date#getHours()
+	 */
+	public void test_getHours() {
+		// Test for method int java.util.Date.getHours()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect hours", 19, d.getHours());
+	}
+
+	/**
+	 * @tests java.util.Date#getMinutes()
+	 */
+	public void test_getMinutes() {
+		// Test for method int java.util.Date.getMinutes()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect minutes", 9, d.getMinutes());
+	}
+
+	/**
+	 * @tests java.util.Date#getMonth()
+	 */
+	public void test_getMonth() {
+		// Test for method int java.util.Date.getMonth()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect month", 9, d.getMonth());
+	}
+
+	/**
+	 * @tests java.util.Date#getSeconds()
+	 */
+	public void test_getSeconds() {
+		// Test for method int java.util.Date.getSeconds()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect seconds", 0, d.getSeconds());
+	}
+
+	/**
+	 * @tests java.util.Date#getTime()
+	 */
+	public void test_getTime() {
+		// Test for method long java.util.Date.getTime()
+		Date d1 = new Date(0);
+		Date d2 = new Date(1900000);
+		assertEquals("Returned incorrect time", 1900000, d2.getTime());
+		assertEquals("Returned incorrect time", 0, d1.getTime());
+	}
+
+	/**
+	 * @tests java.util.Date#getTimezoneOffset()
+	 */
+	public void test_getTimezoneOffset() {
+		// Test for method int java.util.Date.getTimezoneOffset()
+		assertTrue("Used to test", true);
+	}
+
+	/**
+	 * @tests java.util.Date#getYear()
+	 */
+	public void test_getYear() {
+		// Test for method int java.util.Date.getYear()
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		assertEquals("Returned incorrect year", 98, d.getYear());
+	}
+
+	/**
+	 * @tests java.util.Date#hashCode()
+	 */
+	public void test_hashCode() {
+		// Test for method int java.util.Date.hashCode()
+		Date d1 = new Date(0);
+		Date d2 = new Date(1900000);
+		assertEquals("Returned incorrect hash", 1900000, d2.hashCode());
+		assertEquals("Returned incorrect hash", 0, d1.hashCode());
+	}
+
+	/**
+	 * @tests java.util.Date#parse(java.lang.String)
+	 */
+	public void test_parseLjava_lang_String() {
+		// Test for method long java.util.Date.parse(java.lang.String)
+		Date d = new Date(Date.parse("13 October 1998"));
+		GregorianCalendar cal = new GregorianCalendar();
+		cal.setTime(d);
+		assertEquals("Parsed incorrect month", 9, cal.get(Calendar.MONTH));
+		assertEquals("Parsed incorrect year", 1998, cal.get(Calendar.YEAR));
+		assertEquals("Parsed incorrect date", 13, cal.get(Calendar.DATE));
+
+		d = new Date(Date.parse("Jan-12 1999"));
+		assertTrue("Wrong parsed date 1", d.equals(new GregorianCalendar(1999,
+				0, 12).getTime()));
+		d = new Date(Date.parse("Jan12-1999"));
+		assertTrue("Wrong parsed date 2", d.equals(new GregorianCalendar(1999,
+				0, 12).getTime()));
+		d = new Date(Date.parse("Jan12 69-1"));
+		cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+		cal.clear();
+		cal.set(1969, Calendar.JANUARY, 12, 1, 0);
+		assertTrue("Wrong parsed date 3", d.equals(cal.getTime()));
+		d = new Date(Date.parse("6:45:13 3/2/1200 MST"));
+		cal.setTimeZone(TimeZone.getTimeZone("MST"));
+		cal.clear();
+		cal.set(1200, 2, 2, 6, 45, 13);
+		assertTrue("Wrong parsed date 4", d.equals(cal.getTime()));
+		d = new Date(Date.parse("Mon, 22 Nov 1999 12:52:06 GMT"));
+		cal.setTimeZone(TimeZone.getTimeZone("GMT"));
+		cal.clear();
+		cal.set(1999, Calendar.NOVEMBER, 22, 12, 52, 06);
+		assertTrue("Wrong parsed date 5", d.equals(cal.getTime()));
+        
+		try {
+			// Regression for HARMONY-259
+			Date.parse(null);
+			fail("Date.parse(null) should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		
         // Regression for HARMONY-102
         assertEquals("Assert 0: parse failure",
                 -5400000, Date.parse("Sat, 1 Jan 1970 +0130 00:00:00"));
         assertEquals("Assert 1: parse failure",
                 858600000, Date.parse("00:00:00 GMT +0130 Sat, 11 Jan 1970"));
-    }
+	}
 
+	/**
+	 * @tests java.util.Date#setDate(int)
+	 */
+	public void test_setDateI() {
+		// Test for method void java.util.Date.setDate(int)
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		d.setDate(23);
+		assertEquals("Set incorrect date", 23, d.getDate());
+	}
+
+	/**
+	 * @tests java.util.Date#setHours(int)
+	 */
+	public void test_setHoursI() {
+		// Test for method void java.util.Date.setHours(int)
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		d.setHours(23);
+		assertEquals("Set incorrect hours", 23, d.getHours());
+	}
+
+	/**
+	 * @tests java.util.Date#setMinutes(int)
+	 */
+	public void test_setMinutesI() {
+		// Test for method void java.util.Date.setMinutes(int)
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		d.setMinutes(45);
+		assertEquals("Set incorrect mins", 45, d.getMinutes());
+	}
+
+	/**
+	 * @tests java.util.Date#setMonth(int)
+	 */
+	public void test_setMonthI() {
+		// Test for method void java.util.Date.setMonth(int)
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		d.setMonth(0);
+		assertEquals("Set incorrect month", 0, d.getMonth());
+	}
+
+	/**
+	 * @tests java.util.Date#setSeconds(int)
+	 */
+	public void test_setSecondsI() {
+		// Test for method void java.util.Date.setSeconds(int)
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		d.setSeconds(13);
+		assertEquals("Set incorrect seconds", 13, d.getSeconds());
+	}
+
+	/**
+	 * @tests java.util.Date#setTime(long)
+	 */
+	public void test_setTimeJ() {
+		// Test for method void java.util.Date.setTime(long)
+		Date d1 = new Date(0);
+		Date d2 = new Date(1900000);
+		d1.setTime(900);
+		d2.setTime(890000);
+		assertEquals("Returned incorrect time", 890000, d2.getTime());
+		assertEquals("Returned incorrect time", 900, d1.getTime());
+	}
+
+	/**
+	 * @tests java.util.Date#setYear(int)
+	 */
+	public void test_setYearI() {
+		// Test for method void java.util.Date.setYear(int)
+		Date d = new GregorianCalendar(1998, Calendar.OCTOBER, 13, 19, 9)
+				.getTime();
+		d.setYear(8);
+		assertEquals("Set incorrect year", 8, d.getYear());
+	}
+
+	/**
+	 * @tests java.util.Date#toGMTString()
+	 */
+	public void test_toGMTString() {
+		// Test for method java.lang.String java.util.Date.toGMTString()
+		assertEquals("Did not convert epoch to GMT string correctly", "1 Jan 1970 00:00:00 GMT", new Date(0)
+				.toGMTString());
+		assertEquals("Did not convert epoch + 1yr to GMT string correctly",
+				"1 Jan 1971 00:00:00 GMT", new Date((long) 365 * 24 * 60 * 60 * 1000).toGMTString()
+						);
+	}
+
+	/**
+	 * @tests java.util.Date#toString()
+	 */
+	public void test_toString() {
+		// Test for method java.lang.String java.util.Date.toString()
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.DATE, 1);
+		cal.set(Calendar.MONTH, Calendar.JANUARY);
+		cal.set(Calendar.YEAR, 1970);
+		cal.set(Calendar.HOUR_OF_DAY, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		Date d = cal.getTime();
+		String result = d.toString();
+		assertTrue("Incorrect result: " + d, result
+				.startsWith("Thu Jan 01 00:00:00")
+				&& result.endsWith("1970"));
+
+		TimeZone tz = TimeZone.getDefault();
+		TimeZone.setDefault(TimeZone.getTimeZone("EST"));
+		try {
+			Date d1 = new Date(0);
+            assertTrue("Returned incorrect string: " + d1, d1.toString()
+                    .startsWith("Wed Dec 31 19:00:00")
+                    && d1.toString().endsWith("1969"));
+		} finally {
+			TimeZone.setDefault(tz);
+		}
+        
+        // Test for HARMONY-5468
+        TimeZone.setDefault(TimeZone.getTimeZone("MST"));
+        Date d2 = new Date(108, 7, 27);
+        assertTrue("Returned incorrect string: " + d2, d2.toString()
+                .startsWith("Wed Aug 27 00:00:00 MST")
+                && d2.toString().endsWith("2008"));
+	}
+
+	/**
+	 * @tests java.util.Date#UTC(int, int, int, int, int, int)
+	 */
+	public void test_UTCIIIIII() {
+		// Test for method long java.util.Date.UTC(int, int, int, int, int, int)
+		assertTrue("Returned incorrect UTC value for epoch", Date.UTC(70, 0, 1,
+				0, 0, 0) == (long) 0);
+		assertTrue("Returned incorrect UTC value for epoch +1yr", Date.UTC(71,
+				0, 1, 0, 0, 0) == (long) 365 * 24 * 60 * 60 * 1000);
+	}
+	
+	static TimeZone defaultTimeZone = TimeZone.getDefault();
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+		TimeZone.setDefault(defaultTimeZone);
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DuplicateFormatFlagsExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DuplicateFormatFlagsExceptionTest.java
index e700fff..ff6c08f 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DuplicateFormatFlagsExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/DuplicateFormatFlagsExceptionTest.java
@@ -16,31 +16,19 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.DuplicateFormatFlagsException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(DuplicateFormatFlagsException.class) 
 public class DuplicateFormatFlagsExceptionTest extends TestCase {
 
     /**
      * @tests java.util.DuplicateFormatFlagsException#DuplicateFormatFlagsException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "DuplicateFormatFlagsException",
-        args = {java.lang.String.class}
-    )
     public void test_duplicateFormatFlagsException() {
         try {
             new DuplicateFormatFlagsException(null);
@@ -48,19 +36,11 @@
         } catch (NullPointerException e) {
             // desired
         }
-        
-        assertNotNull(new DuplicateFormatFlagsException("String"));
     }
 
     /**
      * @tests java.util.DuplicateFormatFlagsException#getFlags()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFlags",
-        args = {}
-    )
     public void test_getFlags() {
         String strFlags = "MYTESTFLAGS";
         DuplicateFormatFlagsException duplicateFormatException = new DuplicateFormatFlagsException(
@@ -71,12 +51,6 @@
     /**
      * @tests java.util.DuplicateFormatFlagsException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String strFlags = "MYTESTFLAGS";
         DuplicateFormatFlagsException duplicateFormatException = new DuplicateFormatFlagsException(
@@ -103,12 +77,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new DuplicateFormatFlagsException(
@@ -118,12 +86,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new DuplicateFormatFlagsException(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java
index a76ff54..2ead734 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatFlagsConversionMismatchExceptionTest.java
@@ -16,32 +16,20 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.FormatFlagsConversionMismatchException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(FormatFlagsConversionMismatchException.class)     
 public class FormatFlagsConversionMismatchExceptionTest extends TestCase {
 
     /**
      * @tests java.util.FormatFlagsConversionMismatchException#FormatFlagsConversionMismatchException(String,
      *        char)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies NullPointerException.",
-        method = "FormatFlagsConversionMismatchException",
-        args = {java.lang.String.class, char.class}
-    )
     public void test_formatFlagsConversionMismatchException() {
         try {
             new FormatFlagsConversionMismatchException(null, ' ');
@@ -50,18 +38,11 @@
             // expected
         }
 
-        assertNotNull(new FormatFlagsConversionMismatchException("String", ' '));
     }
 
     /**
      * @tests java.util.FormatFlagsConversionMismatchException#getFlags()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFlags",
-        args = {}
-    )
     public void test_getFlags() {
         String flags = "MYTESTFLAGS";
         char conversion = 'T';
@@ -73,18 +54,10 @@
     /**
      * @tests java.util.FormatFlagsConversionMismatchException#getConversion()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getConversion",
-        args = {}
-    )
     public void test_getConversion() {
         String flags = "MYTESTFLAGS";
         char conversion = 'T';
-        FormatFlagsConversionMismatchException 
-                formatFlagsConversionMismatchException = 
-                                    new FormatFlagsConversionMismatchException(
+        FormatFlagsConversionMismatchException formatFlagsConversionMismatchException = new FormatFlagsConversionMismatchException(
                 flags, conversion);
         assertEquals(conversion, formatFlagsConversionMismatchException
                 .getConversion());
@@ -94,12 +67,6 @@
     /**
      * @tests java.util.FormatFlagsConversionMismatchException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String flags = "MYTESTFLAGS";
         char conversion = 'T';
@@ -129,12 +96,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(
@@ -145,12 +106,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterClosedExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterClosedExceptionTest.java
index 97273f4..1f7e2e9 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterClosedExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterClosedExceptionTest.java
@@ -16,30 +16,17 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.util.FormatterClosedException;
 
 import junit.framework.TestCase;
 
-import java.util.FormatterClosedException;
-
 import org.apache.harmony.testframework.serialization.SerializationTest;
-import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(FormatterClosedException.class) 
 public class FormatterClosedExceptionTest extends TestCase {
 
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new FormatterClosedException());
@@ -48,24 +35,8 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new FormatterClosedException());
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "FormatterClosedException",
-        args = {}
-    )
-    public void test_constructor() {
-        assertNotNull(new FormatterClosedException());
-    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterTest.java
index 5a2ec99..5468914 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/FormatterTest.java
@@ -13,60 +13,4321 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
+import java.io.BufferedOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilePermission;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.nio.charset.Charset;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.DuplicateFormatFlagsException;
+import java.util.FormatFlagsConversionMismatchException;
+import java.util.Formattable;
+import java.util.FormattableFlags;
+import java.util.Formatter;
+import java.util.FormatterClosedException;
+import java.util.IllegalFormatCodePointException;
+import java.util.IllegalFormatConversionException;
+import java.util.IllegalFormatException;
+import java.util.IllegalFormatFlagsException;
+import java.util.IllegalFormatPrecisionException;
+import java.util.IllegalFormatWidthException;
+import java.util.Locale;
+import java.util.MissingFormatArgumentException;
+import java.util.MissingFormatWidthException;
+import java.util.TimeZone;
+import java.util.UnknownFormatConversionException;
+import java.util.Formatter.BigDecimalLayoutForm;
 
 import junit.framework.TestCase;
 
-import java.util.Formatter.BigDecimalLayoutForm;
-
-@TestTargetClass(java.util.    Formatter.BigDecimalLayoutForm.class) 
 public class FormatterTest extends TestCase {
+	private boolean root;
 
+    class MockAppendable implements Appendable {
+        public Appendable append(CharSequence arg0) throws IOException {
+            return null;
+        }
+
+        public Appendable append(char arg0) throws IOException {
+            return null;
+        }
+
+        public Appendable append(CharSequence arg0, int arg1, int arg2)
+                throws IOException {
+            return null;
+        }
+    }
+
+    class MockSecurityManager extends SecurityManager {
+        public void checkPermission(Permission p) {
+            if (p.getActions().equals("write") && p instanceof FilePermission) {
+                throw new SecurityException("Always throw security exception");
+            }
+        }
+
+        public void checkPermission(Permission p, Object ctx) {
+            checkPermission(p);
+        }
+    }
+
+    class MockFormattable implements Formattable {
+        public void formatTo(Formatter formatter, int flags, int width,
+                int precision) throws IllegalFormatException {
+            if ((flags & FormattableFlags.UPPERCASE) != 0) {
+                formatter.format("CUSTOMIZED FORMAT FUNCTION" + " WIDTH: "
+                        + width + " PRECISION: " + precision);
+            } else {
+                formatter.format("customized format function" + " width: "
+                        + width + " precision: " + precision);
+            }
+        }
+
+        public String toString() {
+            return "formattable object";
+        }
+
+        public int hashCode() {
+            return 0xf;
+        }
+    }
+
+    class MockDestination implements Appendable, Flushable {
+
+        private StringBuilder data = new StringBuilder();
+
+        private boolean enabled = false;
+
+        public Appendable append(char c) throws IOException {
+            if (enabled) {
+                data.append(c);
+                enabled = true; // enable it after the first append
+            } else {
+                throw new IOException();
+            }
+            return this;
+        }
+
+        public Appendable append(CharSequence csq) throws IOException {
+            if (enabled) {
+                data.append(csq);
+                enabled = true; // enable it after the first append
+            } else {
+                throw new IOException();
+            }
+            return this;
+        }
+
+        public Appendable append(CharSequence csq, int start, int end)
+                throws IOException {
+            if (enabled) {
+                data.append(csq, start, end);
+                enabled = true; // enable it after the first append
+            } else {
+                throw new IOException();
+            }
+            return this;
+        }
+
+        public void flush() throws IOException {
+            throw new IOException("Always throw IOException");
+        }
+
+        public String toString() {
+            return data.toString();
+        }
+    }
+
+    private File notExist;
+
+    private File fileWithContent;
+
+    private File readOnly;
+
+    private File secret;
+    
+    private TimeZone defaultTimeZone;
+
+    /**
+     * @tests java.util.Formatter#Formatter()
+     */
+    public void test_Constructor() {
+        Formatter f = new Formatter();
+        assertNotNull(f);
+        assertTrue(f.out() instanceof StringBuilder);
+        assertEquals(f.locale(), Locale.getDefault());
+        assertNotNull(f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(Appendable)
+     */
+    public void test_ConstructorLjava_lang_Appendable() {
+        MockAppendable ma = new MockAppendable();
+        Formatter f1 = new Formatter(ma);
+        assertEquals(ma, f1.out());
+        assertEquals(f1.locale(), Locale.getDefault());
+        assertNotNull(f1.toString());
+
+        Formatter f2 = new Formatter((Appendable) null);
+        /*
+         * If a(the input param) is null then a StringBuilder will be created
+         * and the output can be attained by invoking the out() method. But RI
+         * raises an error of FormatterClosedException when invoking out() or
+         * toString().
+         */
+        Appendable sb = f2.out();
+        assertTrue(sb instanceof StringBuilder);
+        assertNotNull(f2.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(Locale)
+     */
+    public void test_ConstructorLjava_util_Locale() {
+        Formatter f1 = new Formatter(Locale.FRANCE);
+        assertTrue(f1.out() instanceof StringBuilder);
+        assertEquals(f1.locale(), Locale.FRANCE);
+        assertNotNull(f1.toString());
+
+        Formatter f2 = new Formatter((Locale) null);
+        assertNull(f2.locale());
+        assertTrue(f2.out() instanceof StringBuilder);
+        assertNotNull(f2.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(Appendable, Locale)
+     */
+    public void test_ConstructorLjava_lang_AppendableLjava_util_Locale() {
+        MockAppendable ma = new MockAppendable();
+        Formatter f1 = new Formatter(ma, Locale.CANADA);
+        assertEquals(ma, f1.out());
+        assertEquals(f1.locale(), Locale.CANADA);
+
+        Formatter f2 = new Formatter(ma, null);
+        assertNull(f2.locale());
+        assertEquals(ma, f1.out());
+
+        Formatter f3 = new Formatter(null, Locale.GERMAN);
+        assertEquals(f3.locale(), Locale.GERMAN);
+        assertTrue(f3.out() instanceof StringBuilder);
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(String)
+     */
+    public void test_ConstructorLjava_lang_String() throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((String) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        f = new Formatter(notExist.getPath());
+        assertEquals(f.locale(), Locale.getDefault());
+        f.close();
+
+        f = new Formatter(fileWithContent.getPath());
+        assertEquals(0, fileWithContent.length());
+        f.close();
+
+        if(!root){
+        	try {
+                f = new Formatter(readOnly.getPath());
+                fail("should throw FileNotFoundException");
+            } catch (FileNotFoundException e) {
+                // expected
+            }
+        }
+
+        SecurityManager oldsm = System.getSecurityManager();
+        System.setSecurityManager(new MockSecurityManager());
+        try {
+            f = new Formatter(secret.getPath());
+            fail("should throw SecurityException");
+        } catch (SecurityException se) {
+            // expected
+        } finally {
+            System.setSecurityManager(oldsm);
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(String, String)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_String()
+            throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((String) null, Charset.defaultCharset().name());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        try {
+            f = new Formatter(notExist.getPath(), null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e2) {
+            // expected
+        }
+
+        f = new Formatter(notExist.getPath(), Charset.defaultCharset().name());
+        assertEquals(f.locale(), Locale.getDefault());
+        f.close();
+
+        try {
+            f = new Formatter(notExist.getPath(), "ISO 1111-1");
+            fail("should throw UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e1) {
+            // expected
+        }
+
+        f = new Formatter(fileWithContent.getPath(), "UTF-16BE");
+        assertEquals(0, fileWithContent.length());
+        f.close();
+
+        if(!root){
+        	try {
+                f = new Formatter(readOnly.getPath(), "UTF-16BE");
+                fail("should throw FileNotFoundException");
+            } catch (FileNotFoundException e) {
+                // expected
+            }
+        }
+
+        SecurityManager oldsm = System.getSecurityManager();
+        System.setSecurityManager(new MockSecurityManager());
+        try {
+            f = new Formatter(secret.getPath(), "UTF-16BE");
+            fail("should throw SecurityException");
+        } catch (SecurityException se) {
+            // expected
+        } finally {
+            System.setSecurityManager(oldsm);
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(String, String, Locale)
+     */
+    public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_util_Locale()
+            throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((String) null, Charset.defaultCharset().name(),
+                    Locale.KOREA);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        try {
+            f = new Formatter(notExist.getPath(), null, Locale.KOREA);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e2) {
+            // expected
+        }
+
+        f = new Formatter(notExist.getPath(), Charset.defaultCharset().name(),
+                null);
+        assertNotNull(f);
+        f.close();
+
+        f = new Formatter(notExist.getPath(), Charset.defaultCharset().name(),
+                Locale.KOREA);
+        assertEquals(f.locale(), Locale.KOREA);
+        f.close();
+
+        try {
+            f = new Formatter(notExist.getPath(), "ISO 1111-1", Locale.CHINA);
+            fail("should throw UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e1) {
+            // expected
+        }
+
+        f = new Formatter(fileWithContent.getPath(), "UTF-16BE",
+                Locale.CANADA_FRENCH);
+        assertEquals(0, fileWithContent.length());
+        f.close();
+
+        if(!root){
+        	try {
+                f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
+                        .name(), Locale.ITALY);
+                fail("should throw FileNotFoundException");
+            } catch (FileNotFoundException e) {
+                // expected
+            }
+        }
+        
+        SecurityManager oldsm = System.getSecurityManager();
+        System.setSecurityManager(new MockSecurityManager());
+        try {
+            f = new Formatter(secret.getPath(),
+                    Charset.defaultCharset().name(), Locale.SIMPLIFIED_CHINESE);
+            fail("should throw SecurityException");
+        } catch (SecurityException se) {
+            // expected
+        } finally {
+            System.setSecurityManager(oldsm);
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(File)
+     */
+    public void test_ConstructorLjava_io_File() throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((File) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        f = new Formatter(notExist);
+        assertEquals(f.locale(), Locale.getDefault());
+        f.close();
+
+        f = new Formatter(fileWithContent);
+        assertEquals(0, fileWithContent.length());
+        f.close();
+
+        if(!root){
+        	try {
+                f = new Formatter(readOnly);
+                fail("should throw FileNotFoundException");
+            } catch (FileNotFoundException e) {
+                // expected
+            }
+        }
+        
+        SecurityManager oldsm = System.getSecurityManager();
+        System.setSecurityManager(new MockSecurityManager());
+        try {
+            f = new Formatter(secret);
+            fail("should throw SecurityException");
+        } catch (SecurityException se) {
+            // expected
+        } finally {
+            System.setSecurityManager(oldsm);
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(File, String)
+     */
+    public void test_ConstructorLjava_io_FileLjava_lang_String()
+            throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((File) null, Charset.defaultCharset().name());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        f = new Formatter(notExist, Charset.defaultCharset().name());
+        assertEquals(f.locale(), Locale.getDefault());
+        f.close();
+
+        f = new Formatter(fileWithContent, "UTF-16BE");
+        assertEquals(0, fileWithContent.length());
+        f.close();
+
+        if(!root){
+        	try {
+                f = new Formatter(readOnly, Charset.defaultCharset().name());
+                fail("should throw FileNotFoundException");
+            } catch (FileNotFoundException e) {
+                // expected
+            }
+        }
+
+        SecurityManager oldsm = System.getSecurityManager();
+        System.setSecurityManager(new MockSecurityManager());
+        try {
+            f = new Formatter(secret, Charset.defaultCharset().name());
+            fail("should throw SecurityException");
+        } catch (SecurityException se) {
+            // expected
+        } finally {
+            System.setSecurityManager(oldsm);
+        }
+
+        try {
+            f = new Formatter(notExist, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e2) {
+            // expected
+        } finally {
+            if (notExist.exists()) {
+                // Fail on RI on Windows, because output stream is created and
+                // not closed when exception thrown
+                assertTrue(notExist.delete());
+            }
+        }
+
+        try {
+            f = new Formatter(notExist, "ISO 1111-1");
+            fail("should throw UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e1) {
+            // expected
+        } finally {
+            if (notExist.exists()) {
+                // Fail on RI on Windows, because output stream is created and
+                // not closed when exception thrown
+                assertTrue(notExist.delete());
+            }
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(File, String, Locale)
+     */
+    public void test_ConstructorLjava_io_FileLjava_lang_StringLjava_util_Locale()
+            throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((File) null, Charset.defaultCharset().name(),
+                    Locale.KOREA);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        try {
+            f = new Formatter(notExist, null, Locale.KOREA);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e2) {
+            // expected
+        }
+
+        f = new Formatter(notExist, Charset.defaultCharset().name(), null);
+        assertNotNull(f);
+        f.close();
+
+        f = new Formatter(notExist, Charset.defaultCharset().name(),
+                Locale.KOREA);
+        assertEquals(f.locale(), Locale.KOREA);
+        f.close();
+
+        try {
+            f = new Formatter(notExist, "ISO 1111-1", Locale.CHINA);
+            fail("should throw UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e1) {
+            // expected
+        }
+        f = new Formatter(fileWithContent.getPath(), "UTF-16BE",
+                Locale.CANADA_FRENCH);
+        assertEquals(0, fileWithContent.length());
+        f.close();
+
+        if(!root){
+        	try {
+                f = new Formatter(readOnly.getPath(), Charset.defaultCharset()
+                        .name(), Locale.ITALY);
+                fail("should throw FileNotFoundException");
+            } catch (FileNotFoundException e) {
+                // expected
+            }
+        }
+
+        SecurityManager oldsm = System.getSecurityManager();
+        System.setSecurityManager(new MockSecurityManager());
+        try {
+            f = new Formatter(secret.getPath(),
+                    Charset.defaultCharset().name(), Locale.SIMPLIFIED_CHINESE);
+            fail("should throw SecurityException");
+        } catch (SecurityException se) {
+            // expected
+        } finally {
+            System.setSecurityManager(oldsm);
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(PrintStream)
+     */
+    public void test_ConstructorLjava_io_PrintStream() throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((PrintStream) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        PrintStream ps = new PrintStream(notExist, "UTF-16BE");
+        f = new Formatter(ps);
+        assertEquals(Locale.getDefault(), f.locale());
+        f.close();
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(OutputStream)
+     */
+    public void test_ConstructorLjava_io_OutputStream() throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((OutputStream) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        OutputStream os = new FileOutputStream(notExist);
+        f = new Formatter(os);
+        assertEquals(Locale.getDefault(), f.locale());
+        f.close();
+    }
+
+    /**
+     * @tests java.util.Formatter#Formatter(OutputStream, String)
+     */
+    public void test_ConstructorLjava_io_OutputStreamLjava_lang_String()
+            throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((OutputStream) null, Charset.defaultCharset()
+                    .name());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        OutputStream os = null;
+        try {
+            os = new FileOutputStream(notExist);
+            f = new Formatter(os, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e2) {
+            // expected
+        } finally {
+            os.close();
+        }
+
+        try {
+            os = new PipedOutputStream();
+            f = new Formatter(os, "TMP-1111");
+            fail("should throw UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e1) {
+            // expected
+        } finally {
+            os.close();
+        }
+
+        os = new FileOutputStream(fileWithContent);
+        f = new Formatter(os, "UTF-16BE");
+        assertEquals(Locale.getDefault(), f.locale());
+        f.close();
+    }
+
+    /**
+     * Test method for 'java.util.Formatter.Formatter(OutputStream, String,
+     * Locale)
+     */
+    public void test_ConstructorLjava_io_OutputStreamLjava_lang_StringLjava_util_Locale()
+            throws IOException {
+        Formatter f = null;
+        try {
+            f = new Formatter((OutputStream) null, Charset.defaultCharset()
+                    .name(), Locale.getDefault());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        OutputStream os = null;
+        try {
+            os = new FileOutputStream(notExist);
+            f = new Formatter(os, null, Locale.getDefault());
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e2) {
+            // expected
+        } finally {
+            os.close();
+        }
+
+        os = new FileOutputStream(notExist);
+        f = new Formatter(os, Charset.defaultCharset().name(), null);
+        f.close();
+
+        try {
+            os = new PipedOutputStream();
+            f = new Formatter(os, "TMP-1111", Locale.getDefault());
+            fail("should throw UnsupportedEncodingException");
+        } catch (UnsupportedEncodingException e1) {
+            // expected
+        }
+
+        os = new FileOutputStream(fileWithContent);
+        f = new Formatter(os, "UTF-16BE", Locale.ENGLISH);
+        assertEquals(Locale.ENGLISH, f.locale());
+        f.close();
+    }
+
+    /**
+     * @tests java.util.Formatter#locale()
+     */
+    public void test_locale() {
+        Formatter f = null;
+        f = new Formatter((Locale) null);
+        assertNull(f.locale());
+
+        f.close();
+        try {
+            f.locale();
+            fail("should throw FormatterClosedException");
+        } catch (FormatterClosedException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#out()
+     */
+    public void test_out() {
+        Formatter f = null;
+        f = new Formatter();
+        assertNotNull(f.out());
+        assertTrue(f.out() instanceof StringBuilder);
+        f.close();
+        try {
+            f.out();
+            fail("should throw FormatterClosedException");
+        } catch (FormatterClosedException e) {
+            // expected
+        }
+
+    }
+
+    /**
+     * @tests java.util.Formatter#flush()
+     */
+    public void test_flush() throws IOException {
+        Formatter f = null;
+        f = new Formatter(notExist);
+        assertTrue(f instanceof Flushable);
+        f.close();
+        try {
+            f.flush();
+            fail("should throw FormatterClosedException");
+        } catch (FormatterClosedException e) {
+            // expected
+        }
+
+        f = new Formatter();
+        // For destination that does not implement Flushable
+        // No exception should be thrown
+        f.flush();
+    }
+
+    /**
+     * @tests java.util.Formatter#close()
+     */
+    public void test_close() throws IOException {
+        Formatter f = new Formatter(notExist);
+        assertTrue(f instanceof Closeable);
+        f.close();
+        // close next time will not throw exception
+        f.close();
+        assertNull(f.ioException());
+    }
+
+    /**
+     * @tests java.util.Formatter#toString()
+     */
+    public void test_toString() {
+        Formatter f = new Formatter();
+        assertNotNull(f.toString());
+        assertEquals(f.out().toString(), f.toString());
+        f.close();
+        try {
+            f.toString();
+            fail("should throw FormatterClosedException");
+        } catch (FormatterClosedException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#ioException()
+     */
+    public void test_ioException() throws IOException {
+        Formatter f = null;
+        f = new Formatter(new MockDestination());
+        assertNull(f.ioException());
+        f.flush();
+        assertNotNull(f.ioException());
+        f.close();
+
+        MockDestination md = new MockDestination();
+        f = new Formatter(md);
+        f.format("%s%s", "1", "2");
+        // format stop working after IOException
+        assertNotNull(f.ioException());
+        assertEquals("", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for null parameter
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_null() {
+        Formatter f = new Formatter();
+        try {
+            f.format((String) null, "parameter");
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        f = new Formatter();
+        f.format("hello", (Object[]) null);
+        assertEquals("hello", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for argument index
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_ArgIndex() {
+        Formatter formatter = new Formatter(Locale.US);
+        formatter.format("%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%9$s%11$s%10$s", "1",
+                "2", "3", "4", "5", "6", "7", "8", "9", "10", "11");
+        assertEquals("1234567891110", formatter.toString());
+
+        formatter = new Formatter(Locale.JAPAN);
+        formatter.format("%0$s", "hello");
+        assertEquals("hello", formatter.toString());
+
+        try {
+            formatter = new Formatter(Locale.US);
+            formatter.format("%-1$s", "1", "2");
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+
+        try {
+            formatter = new Formatter(Locale.US);
+            formatter.format("%$s", "hello", "2");
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+        
+        try {
+            Formatter f = new Formatter(Locale.US);
+            f.format("%", "string");
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }       
+
+        formatter = new Formatter(Locale.FRANCE);
+        formatter.format("%1$s%2$s%3$s%4$s%5$s%6$s%7$s%8$s%<s%s%s%<s", "1",
+                "2", "3", "4", "5", "6", "7", "8", "9", "10", "11");
+        assertEquals("123456788122", formatter.toString());
+
+        formatter = new Formatter(Locale.FRANCE);
+        formatter.format(
+                "xx%1$s22%2$s%s%<s%5$s%<s&%7$h%2$s%8$s%<s%s%s%<ssuffix", "1",
+                "2", "3", "4", "5", "6", 7, "8", "9", "10", "11");
+        assertEquals("xx12221155&7288233suffix", formatter.toString());
+
+        try {
+            formatter.format("%<s", "hello");
+            fail("should throw MissingFormatArgumentException");
+        } catch (MissingFormatArgumentException e) {
+            // expected
+        }
+
+        formatter = new Formatter(Locale.US);
+        try {
+            formatter.format("%123$s", "hello");
+            fail("should throw MissingFormatArgumentException");
+        } catch (MissingFormatArgumentException e) {
+            // expected
+        }
+
+        formatter = new Formatter(Locale.US);
+        try {
+            // 2147483648 is the value of Integer.MAX_VALUE + 1
+            formatter.format("%2147483648$s", "hello");
+            fail("should throw MissingFormatArgumentException");
+        } catch (MissingFormatArgumentException e) {
+            // expected
+        }
+
+        try {
+            // 2147483647 is the value of Integer.MAX_VALUE
+            formatter.format("%2147483647$s", "hello");
+            fail("should throw MissingFormatArgumentException");
+        } catch (MissingFormatArgumentException e) {
+            // expected
+        }
+
+        formatter = new Formatter(Locale.US);
+        try {
+            formatter.format("%s%s", "hello");
+            fail("should throw MissingFormatArgumentException");
+        } catch (MissingFormatArgumentException e) {
+            // expected
+        }
+
+        formatter = new Formatter(Locale.US);
+        formatter.format("$100", 100);
+        assertEquals("$100", formatter.toString());
+
+        formatter = new Formatter(Locale.UK);
+        formatter.format("%01$s", "string");
+        assertEquals("string", formatter.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for width
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_Width() {
+        Formatter f = new Formatter(Locale.US);
+        f.format("%1$8s", "1");
+        assertEquals("       1", f.toString());
+
+        f = new Formatter(Locale.US);
+        f.format("%1$-1%", "string");
+        assertEquals("%", f.toString());
+
+        f = new Formatter(Locale.ITALY);
+        // 2147483648 is the value of Integer.MAX_VALUE + 1
+        f.format("%2147483648s", "string");
+        assertEquals("string", f.toString());
+
+        // the value of Integer.MAX_VALUE will allocate about 4G bytes of
+        // memory.
+        // It may cause OutOfMemoryError, so this value is not tested
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for precision
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_Precision() {
+        Formatter f = new Formatter(Locale.US);
+        f.format("%.5s", "123456");
+        assertEquals("12345", f.toString());
+
+        f = new Formatter(Locale.US);
+        // 2147483648 is the value of Integer.MAX_VALUE + 1
+        f.format("%.2147483648s", "...");
+        assertEquals("...", f.toString());
+
+        // the value of Integer.MAX_VALUE will allocate about 4G bytes of
+        // memory.
+        // It may cause OutOfMemoryError, so this value is not tested
+
+        f = new Formatter(Locale.US);
+        f.format("%10.0b", Boolean.TRUE);
+        assertEquals("          ", f.toString());
+
+        f = new Formatter(Locale.US);
+        f.format("%10.01s", "hello");
+        assertEquals("         h", f.toString());
+
+        try {
+            f = new Formatter(Locale.US);
+            f.format("%.s", "hello", "2");
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+
+        try {
+            f = new Formatter(Locale.US);
+            f.format("%.-5s", "123456");
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+
+        try {
+            f = new Formatter(Locale.US);
+            f.format("%1.s", "hello", "2");
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        f.format("%5.1s", "hello");
+        assertEquals("    h", f.toString());
+
+        f = new Formatter(Locale.FRANCE);
+        f.format("%.0s", "hello", "2");
+        assertEquals("", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for line sperator
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_LineSeparator() {
+        Formatter f = null;
+
+        String oldSeparator = System.getProperty("line.separator");
+        System.setProperty("line.separator", "!\n");
+
+        f = new Formatter(Locale.US);
+        f.format("%1$n", 1);
+        assertEquals("!\n", f.toString());
+
+        f = new Formatter(Locale.KOREAN);
+        f.format("head%1$n%2$n", 1, new Date());
+        assertEquals("head!\n!\n", f.toString());
+
+        f = new Formatter(Locale.US);
+        f.format("%n%s", "hello");
+        assertEquals("!\nhello", f.toString());
+
+        System.setProperty("line.separator", oldSeparator);
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%-n");
+            fail("should throw IllegalFormatFlagsException: %-n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+        try {
+            f.format("%+n");
+            fail("should throw IllegalFormatFlagsException: %+n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+        try {
+            f.format("%#n");
+            fail("should throw IllegalFormatFlagsException: %#n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+        try {
+            f.format("% n");
+            fail("should throw IllegalFormatFlagsException: % n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+        try {
+            f.format("%0n");
+            fail("should throw IllegalFormatFlagsException: %0n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+        try {
+            f.format("%,n");
+            fail("should throw IllegalFormatFlagsException: %,n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+        try {
+            f.format("%(n");
+            fail("should throw IllegalFormatFlagsException: %(n");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%4n");
+            fail("should throw IllegalFormatWidthException");
+        } catch (IllegalFormatWidthException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%-4n");
+            fail("should throw IllegalFormatWidthException");
+        } catch (IllegalFormatWidthException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%.9n");
+            fail("should throw IllegalFormatPrecisionException");
+        } catch (IllegalFormatPrecisionException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%5.9n");
+            fail("should throw IllegalFormatPrecisionException");
+        } catch (IllegalFormatPrecisionException e) {
+            // expected
+        }
+        
+        System.setProperty("line.separator", oldSeparator);
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for percent
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_Percent() {
+        Formatter f = null;
+
+        f = new Formatter(Locale.ENGLISH);
+        f.format("%1$%", 100);
+        assertEquals("%", f.toString());
+
+        f = new Formatter(Locale.CHINA);
+        f.format("%1$%%%", "hello", new Object());
+        assertEquals("%%", f.toString());
+
+        f = new Formatter(Locale.CHINA);
+        f.format("%%%s", "hello");
+        assertEquals("%hello", f.toString());
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%.9%");
+            fail("should throw IllegalFormatPrecisionException");
+        } catch (IllegalFormatPrecisionException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%5.9%");
+            fail("should throw IllegalFormatPrecisionException");
+        } catch (IllegalFormatPrecisionException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        assertFormatFlagsConversionMismatchException(f, "%+%");
+        assertFormatFlagsConversionMismatchException(f, "%#%");
+        assertFormatFlagsConversionMismatchException(f, "% %");
+        assertFormatFlagsConversionMismatchException(f, "%0%");
+        assertFormatFlagsConversionMismatchException(f, "%,%");
+        assertFormatFlagsConversionMismatchException(f, "%(%");
+        
+
+        f = new Formatter(Locale.KOREAN);
+        f.format("%4%", 1);
+        /*
+         * fail on RI the output string should be right justified by appending
+         * spaces till the whole string is 4 chars width.
+         */
+        assertEquals("   %", f.toString());
+
+        f = new Formatter(Locale.US);
+        f.format("%-4%", 100);
+        /*
+         * fail on RI, throw UnknownFormatConversionException the output string
+         * should be left justified by appending spaces till the whole string is
+         * 4 chars width.
+         */
+        assertEquals("%   ", f.toString());
+    }
+
+    private void assertFormatFlagsConversionMismatchException(Formatter f, String str) {
+        try {
+            f.format(str);
+            fail("should throw FormatFlagsConversionMismatchException: "
+                    + str);
+             /*
+             * error on RI, throw IllegalFormatFlagsException specification
+             * says FormatFlagsConversionMismatchException should be thrown
+             */
+        } catch (FormatFlagsConversionMismatchException e) {
+           // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for flag
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_Flag() {
+        Formatter f = new Formatter(Locale.US);
+        try {
+            f.format("%1$-#-8s", "something");
+            fail("should throw DuplicateFormatFlagsException");
+        } catch (DuplicateFormatFlagsException e) {
+            // expected
+        }
+
+        final char[] chars = { '-', '#', '+', ' ', '0', ',', '(', '%', '<' };
+        Arrays.sort(chars);
+        f = new Formatter(Locale.US);
+        for (char i = 0; i <= 256; i++) {
+            // test 8 bit character
+            if (Arrays.binarySearch(chars, i) >= 0 || Character.isDigit(i)
+                    || Character.isLetter(i)) {
+                // Do not test 0-9, a-z, A-Z and characters in the chars array.
+                // They are characters used as flags, width or conversions
+                continue;
+            }
+            try {
+                f.format("%" + i + "s", 1);
+                fail("should throw UnknownFormatConversionException");
+            } catch (UnknownFormatConversionException e) {
+                // expected
+            }
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for general
+     *        conversion b/B
+     */
+    public void test_format_LString$LObject_GeneralConversionB() {
+        final Object[][] triple = { 
+                { Boolean.FALSE,                "%3.2b",  " fa", },
+                { Boolean.FALSE,                "%-4.6b", "false", },
+                { Boolean.FALSE,                "%.2b",   "fa", }, 
+                { Boolean.TRUE,                 "%3.2b",  " tr", },
+                { Boolean.TRUE,                 "%-4.6b", "true", },
+                { Boolean.TRUE,                 "%.2b",   "tr", },
+                { new Character('c'),           "%3.2b",  " tr", },
+                { new Character('c'),           "%-4.6b", "true", },
+                { new Character('c'),           "%.2b",   "tr", },
+                { new Byte((byte) 0x01),        "%3.2b",  " tr", },
+                { new Byte((byte) 0x01),        "%-4.6b", "true", },
+                { new Byte((byte) 0x01),        "%.2b",   "tr", },
+                { new Short((short) 0x0001),    "%3.2b",  " tr", },
+                { new Short((short) 0x0001),    "%-4.6b", "true", },
+                { new Short((short) 0x0001),    "%.2b",   "tr", },
+                { new Integer(1),               "%3.2b",  " tr", },
+                { new Integer(1),               "%-4.6b", "true", },
+                { new Integer(1),               "%.2b",   "tr", },
+                { new Float(1.1f),              "%3.2b",  " tr", },
+                { new Float(1.1f),              "%-4.6b", "true", },
+                { new Float(1.1f),              "%.2b",   "tr", },
+                { new Double(1.1d),             "%3.2b",  " tr", },
+                { new Double(1.1d),             "%-4.6b", "true", },
+                { new Double(1.1d),             "%.2b",   "tr", },
+                { "",                           "%3.2b",  " tr", },
+                { "",                           "%-4.6b", "true", },
+                { "",                           "%.2b",   "tr", },
+                { "string content",             "%3.2b",  " tr", },
+                { "string content",             "%-4.6b", "true", },
+                { "string content",             "%.2b",   "tr", },
+                { new MockFormattable(),        "%3.2b",  " tr", },
+                { new MockFormattable(),        "%-4.6b", "true", },
+                { new MockFormattable(),        "%.2b",   "tr", },
+                { (Object) null,                "%3.2b",  " fa", },
+                { (Object) null,                "%-4.6b", "false", },
+                { (Object) null,                "%.2b",   "fa", },
+                };
+
+
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2; 
+        Formatter f = null;
+        for (int i = 0; i < triple.length; i++) {
+            f = new Formatter(Locale.FRANCE);
+            f.format((String)triple[i][pattern], triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input]
+                          + ",pattern[" + i + "]:" + triple[i][pattern], triple[i][output], f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format(((String)triple[i][pattern]).toUpperCase(Locale.US), triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input]
+                          + ",pattern[" + i + "]:" + triple[i][pattern], ((String)triple[i][output])
+                    .toUpperCase(Locale.US), f.toString());
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for general
+     *        conversion type 's' and 'S'
+     */
+    public void test_format_LString$LObject_GeneralConversionS() {
+
+        final Object[][] triple = { 
+                { Boolean.FALSE,                "%2.3s",  "fal", },
+                { Boolean.FALSE,                "%-6.4s", "fals  ", },
+                { Boolean.FALSE,                "%.5s",   "false", }, 
+                { Boolean.TRUE,                 "%2.3s",  "tru", },
+                { Boolean.TRUE,                 "%-6.4s", "true  ", },
+                { Boolean.TRUE,                 "%.5s",   "true", },
+                { new Character('c'),           "%2.3s",  " c", },
+                { new Character('c'),           "%-6.4s", "c     ", },
+                { new Character('c'),           "%.5s",   "c", },
+                { new Byte((byte) 0x01),        "%2.3s",  " 1", },
+                { new Byte((byte) 0x01),        "%-6.4s", "1     ", },
+                { new Byte((byte) 0x01),        "%.5s",   "1", },
+                { new Short((short) 0x0001),    "%2.3s",  " 1", },
+                { new Short((short) 0x0001),    "%-6.4s", "1     ", },
+                { new Short((short) 0x0001),    "%.5s",   "1", },
+                { new Integer(1),               "%2.3s",  " 1", },
+                { new Integer(1),               "%-6.4s", "1     ", },
+                { new Integer(1),               "%.5s",   "1", },
+                { new Float(1.1f),              "%2.3s",  "1.1", },
+                { new Float(1.1f),              "%-6.4s", "1.1   ", },
+                { new Float(1.1f),              "%.5s",   "1.1", },
+                { new Double(1.1d),             "%2.3s",  "1.1", },
+                { new Double(1.1d),             "%-6.4s", "1.1   ", },
+                { new Double(1.1d),             "%.5s",   "1.1", },
+                { "",                           "%2.3s",  "  ", },
+                { "",                           "%-6.4s", "      ", },
+                { "",                           "%.5s",   "", },
+                { "string content",             "%2.3s",  "str", },
+                { "string content",             "%-6.4s", "stri  ", },
+                { "string content",             "%.5s",   "strin", },
+                { new MockFormattable(),        "%2.3s",  "customized format function width: 2 precision: 3", },
+                { new MockFormattable(),        "%-6.4s", "customized format function width: 6 precision: 4", },
+                { new MockFormattable(),        "%.5s",   "customized format function width: -1 precision: 5", },
+                { (Object) null,                "%2.3s",  "nul", },
+                { (Object) null,                "%-6.4s", "null  ", },
+                { (Object) null,                "%.5s",   "null", },
+                };
+
+
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+        Formatter f = null;
+        for (int i = 0; i < triple.length; i++) {
+            f = new Formatter(Locale.FRANCE);
+            f.format((String)triple[i][pattern], triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input]
+                          + ",pattern[" + i + "]:" + triple[i][pattern], triple[i][output], f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format(((String)triple[i][pattern]).toUpperCase(Locale.US), triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input]
+                          + ",pattern[" + i + "]:" + triple[i][pattern], ((String)triple[i][output])
+                    .toUpperCase(Locale.US), f.toString());
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for general
+     *        conversion type 'h' and 'H'
+     */
+    public void test_format_LString$LObject_GeneralConversionH() {
+
+        final Object[] input = { 
+                 Boolean.FALSE,                 
+                 Boolean.TRUE,                  
+                 new Character('c'),            
+                 new Byte((byte) 0x01),         
+                 new Short((short) 0x0001),     
+                 new Integer(1),                
+                 new Float(1.1f),               
+                 new Double(1.1d),              
+                 "",                            
+                 "string content",              
+                 new MockFormattable(),         
+                 (Object) null,                 
+                };
+
+        Formatter f = null;
+        for (int i = 0; i < input.length - 1; i++) {
+            f = new Formatter(Locale.FRANCE);
+            f.format("%h", input[i]);
+            assertEquals("triple[" + i + "]:" + input[i], 
+                    Integer.toHexString(input[i].hashCode()), f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format("%H", input[i]);
+            assertEquals("triple[" + i + "]:" + input[i], 
+                    Integer.toHexString(input[i].hashCode()).toUpperCase(Locale.US), f.toString());
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for general
+     *        conversion other cases
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionOther() {
+        /*
+         * In Turkish locale, the upper case of '\u0069' is '\u0130'. The
+         * following test indicate that '\u0069' is coverted to upper case
+         * without using the turkish locale.
+         */
+        Formatter f = new Formatter(new Locale("tr"));
+        f.format("%S", "\u0069");
+        assertEquals("\u0049", f.toString());
+
+        final Object[] input = { 
+                Boolean.FALSE,                 
+                Boolean.TRUE,                  
+                new Character('c'),            
+                new Byte((byte) 0x01),         
+                new Short((short) 0x0001),     
+                new Integer(1),                
+                new Float(1.1f),               
+                new Double(1.1d),              
+                "",                            
+                "string content",              
+                new MockFormattable(),         
+                (Object) null,                 
+               };
+        f = new Formatter(Locale.GERMAN);
+        for (int i = 0; i < input.length; i++) {
+            if (!(input[i] instanceof Formattable)) {
+                try {
+                    f.format("%#s", input[i]);
+                    /*
+                     * fail on RI, spec says if the '#' flag is present and the
+                     * argument is not a Formattable , then a
+                     * FormatFlagsConversionMismatchException will be thrown.
+                     */
+                    fail("should throw FormatFlagsConversionMismatchException");
+                } catch (FormatFlagsConversionMismatchException e) {
+                    // expected
+                }
+            } else {
+                f.format("%#s%<-#8s", input[i]);
+                assertEquals(
+                        "customized format function width: -1 precision: -1customized format function width: 8 precision: -1",
+                        f.toString());
+            }
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for general
+     *        conversion exception
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_GeneralConversionException() {
+        final String[] flagMismatch = { "%#b", "%+b", "% b", "%0b", "%,b",
+                "%(b", "%#B", "%+B", "% B", "%0B", "%,B", "%(B", "%#h", "%+h",
+                "% h", "%0h", "%,h", "%(h", "%#H", "%+H", "% H", "%0H", "%,H",
+                "%(H", "%+s", "% s", "%0s", "%,s", "%(s", "%+S", "% S", "%0S",
+                "%,S", "%(S" };
+
+        Formatter f = new Formatter(Locale.US);
+
+        for (int i = 0; i < flagMismatch.length; i++) {
+            try {
+                f.format(flagMismatch[i], "something");
+                fail("should throw FormatFlagsConversionMismatchException");
+            } catch (FormatFlagsConversionMismatchException e) {
+                // expected
+            }
+        }
+
+        final String[] missingWidth = { "%-b", "%-B", "%-h", "%-H", "%-s",
+                "%-S", };
+        for (int i = 0; i < missingWidth.length; i++) {
+            try {
+                f.format(missingWidth[i], "something");
+                fail("should throw MissingFormatWidthException");
+            } catch (MissingFormatWidthException e) {
+                // expected
+            }
+        }
+        
+        // Regression test
+        f = new Formatter();
+        try {
+            f.format("%c", (byte)-0x0001);
+            fail("Should throw IllegalFormatCodePointException");
+        } catch (IllegalFormatCodePointException e) {
+            // expected
+        }
+        
+        f = new Formatter();
+        try {
+            f.format("%c", (short)-0x0001);
+            fail("Should throw IllegalFormatCodePointException");
+        } catch (IllegalFormatCodePointException e) {
+            // expected
+        }
+        
+        f = new Formatter();
+        try {
+            f.format("%c", -0x0001);
+            fail("Should throw IllegalFormatCodePointException");
+        } catch (IllegalFormatCodePointException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Character
+     *        conversion
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_CharacterConversion() {
+        Formatter f = new Formatter(Locale.US);
+        final Object[] illArgs = { Boolean.TRUE, new Float(1.1f),
+                new Double(1.1d), "string content", new Float(1.1f), new Date() };
+        for (int i = 0; i < illArgs.length; i++) {
+            try {
+                f.format("%c", illArgs[i]);
+                fail("should throw IllegalFormatConversionException");
+            } catch (IllegalFormatConversionException e) {
+                // expected
+            }
+        }
+
+        try {
+            f.format("%c", Integer.MAX_VALUE);
+            fail("should throw IllegalFormatCodePointException");
+        } catch (IllegalFormatCodePointException e) {
+            // expected
+        }
+
+        try {
+            f.format("%#c", 'c');
+            fail("should throw FormatFlagsConversionMismatchException");
+        } catch (FormatFlagsConversionMismatchException e) {
+            // expected
+        }
+
+        final Object[][] triple = {
+                {'c',               "%c",   "c"},
+                {'c',               "%-2c", "c "},
+                {'\u0123',          "%c",   "\u0123"},
+                {'\u0123',          "%-2c", "\u0123 "},
+                {(byte) 0x11,       "%c",   "\u0011"},
+                {(byte) 0x11,       "%-2c", "\u0011 "},
+                {(short) 0x1111,    "%c",   "\u1111"},
+                {(short) 0x1111,    "%-2c", "\u1111 "},
+                {0x11,              "%c",   "\u0011"},
+                {0x11,              "%-2c", "\u0011 "},
+        };
+
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+        for (int i = 0; i < triple.length; i++) {
+                f = new Formatter(Locale.US);
+                f.format((String)triple[i][pattern], triple[i][input]);
+                assertEquals(triple[i][output], f.toString());
+        }
+
+        f = new Formatter(Locale.US);
+        f.format("%c", 0x10000);
+        assertEquals(0x10000, f.toString().codePointAt(0));
+
+        try {
+            f.format("%2.2c", 'c');
+            fail("should throw IllegalFormatPrecisionException");
+        } catch (IllegalFormatPrecisionException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        f.format("%C", 'w');
+        // error on RI, throw UnknownFormatConversionException
+        // RI do not support converter 'C'
+        assertEquals("W", f.toString());
+
+        f = new Formatter(Locale.JAPAN);
+        f.format("%Ced", 0x1111);
+        // error on RI, throw UnknownFormatConversionException
+        // RI do not support converter 'C'
+        assertEquals("\u1111ed", f.toString());
+    }
+    
+    
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for legal
+     *        Byte/Short/Integer/Long conversion type 'd'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionD() {
+        final Object[][] triple = { 
+                { 0,                "%d",                  "0" }, 
+                { 0,                "%10d",       "         0" }, 
+                { 0,                "%-1d",                "0" }, 
+                { 0,                "%+d",                "+0" }, 
+                { 0,                "% d",                " 0" }, 
+                { 0,                "%,d",                 "0" }, 
+                { 0,                "%(d",                 "0" }, 
+                { 0,                "%08d",         "00000000" }, 
+                { 0,                "%-+,(11d",  "+0         " }, 
+                { 0,                "%0 ,(11d",  " 0000000000" }, 
+
+                { (byte) 0xff,      "%d",                 "-1" }, 
+                { (byte) 0xff,      "%10d",       "        -1" }, 
+                { (byte) 0xff,      "%-1d",               "-1" }, 
+                { (byte) 0xff,      "%+d",                "-1" }, 
+                { (byte) 0xff,      "% d",                "-1" }, 
+                { (byte) 0xff,      "%,d",                "-1" }, 
+                { (byte) 0xff,      "%(d",               "(1)" }, 
+                { (byte) 0xff,      "%08d",         "-0000001" }, 
+                { (byte) 0xff,      "%-+,(11d",  "(1)        " }, 
+                { (byte) 0xff,      "%0 ,(11d",  "(000000001)" }, 
+                
+                { (short) 0xf123,   "%d",              "-3805" }, 
+                { (short) 0xf123,   "%10d",       "     -3805" }, 
+                { (short) 0xf123,   "%-1d",            "-3805" }, 
+                { (short) 0xf123,   "%+d",             "-3805" }, 
+                { (short) 0xf123,   "% d",             "-3805" }, 
+                { (short) 0xf123,   "%,d",            "-3.805" }, 
+                { (short) 0xf123,   "%(d",            "(3805)" }, 
+                { (short) 0xf123,   "%08d",         "-0003805" }, 
+                { (short) 0xf123,   "%-+,(11d",  "(3.805)    " }, 
+                { (short) 0xf123,   "%0 ,(11d",  "(00003.805)" }, 
+                
+                {  0x123456,        "%d",            "1193046" }, 
+                {  0x123456,        "%10d",       "   1193046" }, 
+                {  0x123456,        "%-1d",          "1193046" }, 
+                {  0x123456,        "%+d",          "+1193046" }, 
+                {  0x123456,        "% d",          " 1193046" }, 
+                {  0x123456,        "%,d",         "1.193.046" }, 
+                {  0x123456,        "%(d",           "1193046" }, 
+                {  0x123456,        "%08d",         "01193046" }, 
+                {  0x123456,        "%-+,(11d",  "+1.193.046 " }, 
+                {  0x123456,        "%0 ,(11d",  " 01.193.046" }, 
+                
+                { -3,               "%d",                 "-3" }, 
+                { -3,               "%10d",       "        -3" }, 
+                { -3,               "%-1d",               "-3" }, 
+                { -3,               "%+d",                "-3" }, 
+                { -3,               "% d",                "-3" }, 
+                { -3,               "%,d",                "-3" }, 
+                { -3,               "%(d",               "(3)" }, 
+                { -3,               "%08d",         "-0000003" }, 
+                { -3,               "%-+,(11d",  "(3)        " }, 
+                { -3,               "%0 ,(11d",  "(000000003)" },
+                
+                { 0x7654321L,       "%d",          "124076833" }, 
+                { 0x7654321L,       "%10d",       " 124076833" }, 
+                { 0x7654321L,       "%-1d",        "124076833" }, 
+                { 0x7654321L,       "%+d",        "+124076833" }, 
+                { 0x7654321L,       "% d",        " 124076833" }, 
+                { 0x7654321L,       "%,d",       "124.076.833" }, 
+                { 0x7654321L,       "%(d",         "124076833" }, 
+                { 0x7654321L,       "%08d",        "124076833" }, 
+                { 0x7654321L,       "%-+,(11d", "+124.076.833" }, 
+                { 0x7654321L,       "%0 ,(11d", " 124.076.833" }, 
+                
+                { -1L,              "%d",                 "-1" }, 
+                { -1L,              "%10d",       "        -1" }, 
+                { -1L,              "%-1d",               "-1" }, 
+                { -1L,              "%+d",                "-1" }, 
+                { -1L,              "% d",                "-1" }, 
+                { -1L,              "%,d",                "-1" }, 
+                { -1L,              "%(d",               "(1)" }, 
+                { -1L,              "%08d",         "-0000001" }, 
+                { -1L,              "%-+,(11d",  "(1)        " }, 
+                { -1L,              "%0 ,(11d",  "(000000001)" }, 
+                };
+
+        final int input = 0;
+        final int pattern = 1;
+        final int output = 2;
+        Formatter f;
+        for (int i = 0; i < triple.length; i++) {
+            f = new Formatter(Locale.GERMAN);
+            f.format((String) triple[i][pattern],
+                    triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+                    + i + "]:" + triple[i][pattern], triple[i][output], f
+                    .toString());
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for legal
+     *        Byte/Short/Integer/Long conversion type 'o'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionO() {
+        final Object[][] triple = { 
+                { 0,                "%o",                 "0" }, 
+                { 0,                "%-6o",          "0     " }, 
+                { 0,                "%08o",        "00000000" }, 
+                { 0,                "%#o",               "00" }, 
+                { 0,                "%0#11o",   "00000000000" }, 
+                { 0,                "%-#9o",      "00       " }, 
+
+                { (byte) 0xff,      "%o",               "377" }, 
+                { (byte) 0xff,      "%-6o",          "377   " }, 
+                { (byte) 0xff,      "%08o",        "00000377" }, 
+                { (byte) 0xff,      "%#o",             "0377" }, 
+                { (byte) 0xff,      "%0#11o",   "00000000377" }, 
+                { (byte) 0xff,      "%-#9o",      "0377     " }, 
+                
+                { (short) 0xf123,   "%o",            "170443" }, 
+                { (short) 0xf123,   "%-6o",          "170443" }, 
+                { (short) 0xf123,   "%08o",        "00170443" }, 
+                { (short) 0xf123,   "%#o",          "0170443" }, 
+                { (short) 0xf123,   "%0#11o",   "00000170443" }, 
+                { (short) 0xf123,   "%-#9o",      "0170443  " }, 
+                
+                {  0x123456,        "%o",           "4432126" }, 
+                {  0x123456,        "%-6o",         "4432126" }, 
+                {  0x123456,        "%08o",        "04432126" }, 
+                {  0x123456,        "%#o",         "04432126" }, 
+                {  0x123456,        "%0#11o",   "00004432126" }, 
+                {  0x123456,        "%-#9o",      "04432126 " }, 
+                
+                { -3,               "%o",       "37777777775" }, 
+                { -3,               "%-6o",     "37777777775" }, 
+                { -3,               "%08o",     "37777777775" }, 
+                { -3,               "%#o",     "037777777775" }, 
+                { -3,               "%0#11o",  "037777777775" }, 
+                { -3,               "%-#9o",   "037777777775" }, 
+                
+                { 0x7654321L,       "%o",          "731241441" }, 
+                { 0x7654321L,       "%-6o",        "731241441" }, 
+                { 0x7654321L,       "%08o",        "731241441" }, 
+                { 0x7654321L,       "%#o",        "0731241441" }, 
+                { 0x7654321L,       "%0#11o",    "00731241441" }, 
+                { 0x7654321L,       "%-#9o",      "0731241441" }, 
+                
+                { -1L,              "%o",       "1777777777777777777777" }, 
+                { -1L,              "%-6o",     "1777777777777777777777" }, 
+                { -1L,              "%08o",     "1777777777777777777777" }, 
+                { -1L,              "%#o",     "01777777777777777777777" }, 
+                { -1L,              "%0#11o",  "01777777777777777777777" }, 
+                { -1L,              "%-#9o",   "01777777777777777777777" }, 
+                };
+
+        final int input = 0;
+        final int pattern = 1;
+        final int output = 2;
+        Formatter f;
+        for (int i = 0; i < triple.length; i++) {
+            f = new Formatter(Locale.ITALY);
+            f.format((String) triple[i][pattern],
+                    triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+                    + i + "]:" + triple[i][pattern], triple[i][output], f
+                    .toString());
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for legal
+     *        Byte/Short/Integer/Long conversion type 'x' and 'X'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongConversionX() {
+        final Object[][] triple = { 
+                { 0,                "%x",                 "0" }, 
+                { 0,                "%-8x",        "0       " }, 
+                { 0,                "%06x",          "000000" }, 
+                { 0,                "%#x",              "0x0" }, 
+                { 0,                "%0#12x",  "0x0000000000" }, 
+                { 0,                "%-#9x",      "0x0      " }, 
+
+                { (byte) 0xff,      "%x",                "ff" }, 
+                { (byte) 0xff,      "%-8x",        "ff      " }, 
+                { (byte) 0xff,      "%06x",          "0000ff" }, 
+                { (byte) 0xff,      "%#x",             "0xff" }, 
+                { (byte) 0xff,      "%0#12x",  "0x00000000ff" }, 
+                { (byte) 0xff,      "%-#9x",      "0xff     " }, 
+                
+                { (short) 0xf123,   "%x",              "f123" }, 
+                { (short) 0xf123,   "%-8x",        "f123    " }, 
+                { (short) 0xf123,   "%06x",          "00f123" }, 
+                { (short) 0xf123,   "%#x",           "0xf123" }, 
+                { (short) 0xf123,   "%0#12x",  "0x000000f123" }, 
+                { (short) 0xf123,   "%-#9x",      "0xf123   " }, 
+                
+                {  0x123456,        "%x",            "123456" }, 
+                {  0x123456,        "%-8x",        "123456  " }, 
+                {  0x123456,        "%06x",          "123456" }, 
+                {  0x123456,        "%#x",         "0x123456" }, 
+                {  0x123456,        "%0#12x",  "0x0000123456" }, 
+                {  0x123456,        "%-#9x",      "0x123456 " }, 
+                
+                { -3,               "%x",          "fffffffd" }, 
+                { -3,               "%-8x",        "fffffffd" }, 
+                { -3,               "%06x",        "fffffffd" }, 
+                { -3,               "%#x",       "0xfffffffd" }, 
+                { -3,               "%0#12x",  "0x00fffffffd" }, 
+                { -3,               "%-#9x",     "0xfffffffd" }, 
+                
+                { 0x7654321L,       "%x",          "7654321" }, 
+                { 0x7654321L,       "%-8x",       "7654321 " }, 
+                { 0x7654321L,       "%06x",        "7654321" }, 
+                { 0x7654321L,       "%#x",       "0x7654321" }, 
+                { 0x7654321L,       "%0#12x", "0x0007654321" }, 
+                { 0x7654321L,       "%-#9x",     "0x7654321" }, 
+                
+                { -1L,              "%x",       "ffffffffffffffff" }, 
+                { -1L,              "%-8x",     "ffffffffffffffff" }, 
+                { -1L,              "%06x",     "ffffffffffffffff" }, 
+                { -1L,              "%#x",    "0xffffffffffffffff" }, 
+                { -1L,              "%0#12x", "0xffffffffffffffff" }, 
+                { -1L,              "%-#9x",  "0xffffffffffffffff" }, 
+                };
+
+        final int input = 0;
+        final int pattern = 1;
+        final int output = 2;
+        Formatter f;
+        for (int i = 0; i < triple.length; i++) {
+            f = new Formatter(Locale.FRANCE);
+            f.format((String) triple[i][pattern],
+                    triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+                    + i + "]:" + triple[i][pattern], triple[i][output], f
+                    .toString());
+            
+            f = new Formatter(Locale.FRANCE);
+            f.format((String) triple[i][pattern],
+                    triple[i][input]);
+            assertEquals("triple[" + i + "]:" + triple[i][input] + ",pattern["
+                    + i + "]:" + triple[i][pattern], triple[i][output], f
+                    .toString());
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Date/Time
+     *        conversion
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion() {
+        Formatter f = null;
+        Date now = new Date(1147327147578L);
+
+        Calendar paris = Calendar.getInstance(TimeZone
+                .getTimeZone("Europe/Paris"), Locale.FRANCE);
+        paris.set(2006, 4, 8, 12, 0, 0);
+        paris.set(Calendar.MILLISECOND, 453);
+        Calendar china = Calendar.getInstance(
+                TimeZone.getTimeZone("GMT-08:00"), Locale.CHINA);
+        china.set(2006, 4, 8, 12, 0, 0);
+        china.set(Calendar.MILLISECOND, 609);
+
+        final Object[][] lowerCaseGermanTriple = {
+                {0L,                        'a', "Do."},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'a', "So."},  //$NON-NLS-2$
+                {-1000L,                    'a', "Do."},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'a', "Do."},  //$NON-NLS-2$
+                {paris,                     'a', "Mo."},  //$NON-NLS-2$
+                {china,                     'a', "Mo."},  //$NON-NLS-2$
+                {0L,                        'b', "Jan"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'b', "Aug"},  //$NON-NLS-2$
+                {-1000L,                    'b', "Jan"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'b', "Mai"},  //$NON-NLS-2$
+                {paris,                     'b', "Mai"},  //$NON-NLS-2$
+                {china,                     'b', "Mai"},  //$NON-NLS-2$
+                {0L,                        'c', "Do. Jan 01 08:00:00 GMT+08:00 1970"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'c', "So. Aug 17 15:18:47 GMT+08:00 292278994"},  //$NON-NLS-2$
+                {-1000L,                    'c', "Do. Jan 01 07:59:59 GMT+08:00 1970"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'c', "Do. Mai 11 13:59:07 GMT+08:00 2006"},  //$NON-NLS-2$
+                {paris,                     'c', "Mo. Mai 08 12:00:00 MESZ 2006"},  //$NON-NLS-2$
+                {china,                     'c', "Mo. Mai 08 12:00:00 GMT-08:00 2006"},  //$NON-NLS-2$
+                {0L,                        'd', "01"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'd', "17"},  //$NON-NLS-2$
+                {-1000L,                    'd', "01"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'd', "11"},  //$NON-NLS-2$
+                {paris,                     'd', "08"},  //$NON-NLS-2$
+                {china,                     'd', "08"},  //$NON-NLS-2$
+                {0L,                        'e', "1"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'e', "17"},  //$NON-NLS-2$
+                {-1000L,                    'e', "1"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'e', "11"},  //$NON-NLS-2$
+                {paris,                     'e', "8"},  //$NON-NLS-2$
+                {china,                     'e', "8"},  //$NON-NLS-2$
+                {0L,                        'h', "Jan"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'h', "Aug"},  //$NON-NLS-2$
+                {-1000L,                    'h', "Jan"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'h', "Mai"},  //$NON-NLS-2$
+                {paris,                     'h', "Mai"},  //$NON-NLS-2$
+                {china,                     'h', "Mai"},  //$NON-NLS-2$
+                {0L,                        'j', "001"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'j', "229"},  //$NON-NLS-2$
+                {-1000L,                    'j', "001"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'j', "131"},  //$NON-NLS-2$
+                {paris,                     'j', "128"},  //$NON-NLS-2$
+                {china,                     'j', "128"},  //$NON-NLS-2$
+                {0L,                        'k', "8"},  //$NON-NLS-2$
+                {Long.MAX_VALUE,            'k', "15"},  //$NON-NLS-2$
+                {-1000L,                    'k', "7"},  //$NON-NLS-2$
+                {new Date(1147327147578L),  'k', "13"},  //$NON-NLS-2$
+                {paris,                     'k', "12"},  //$NON-NLS-2$
+                {china,                     'k', "12"},  //$NON-NLS-2$
+                {0L,                        'l', "8"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'l', "3"}, //$NON-NLS-2$
+                {-1000L,                    'l', "7"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'l', "1"}, //$NON-NLS-2$
+                {paris,                     'l', "12"}, //$NON-NLS-2$
+                {china,                     'l', "12"}, //$NON-NLS-2$
+                {0L,                        'm', "01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'm', "08"}, //$NON-NLS-2$
+                {-1000L,                    'm', "01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'm', "05"}, //$NON-NLS-2$
+                {paris,                     'm', "05"}, //$NON-NLS-2$
+                {china,                     'm', "05"}, //$NON-NLS-2$
+                {0L,                        'p', "vorm."}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'p', "nachm."}, //$NON-NLS-2$
+                {-1000L,                    'p', "vorm."}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'p', "nachm."}, //$NON-NLS-2$
+                {paris,                     'p', "nachm."}, //$NON-NLS-2$
+                {china,                     'p', "nachm."}, //$NON-NLS-2$
+                {0L,                        'r', "08:00:00 vorm."}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'r', "03:18:47 nachm."}, //$NON-NLS-2$
+                {-1000L,                    'r', "07:59:59 vorm."}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'r', "01:59:07 nachm."}, //$NON-NLS-2$
+                {paris,                     'r', "12:00:00 nachm."}, //$NON-NLS-2$
+                {china,                     'r', "12:00:00 nachm."}, //$NON-NLS-2$
+                {0L,                        's', "0"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            's', "9223372036854775"}, //$NON-NLS-2$
+                {-1000L,                    's', "-1"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  's', "1147327147"}, //$NON-NLS-2$
+                {paris,                     's', "1147082400"}, //$NON-NLS-2$
+                {china,                     's', "1147118400"}, //$NON-NLS-2$
+                {0L,                        'y', "70"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'y', "94"}, //$NON-NLS-2$
+                {-1000L,                    'y', "70"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'y', "06"}, //$NON-NLS-2$
+                {paris,                     'y', "06"}, //$NON-NLS-2$
+                {china,                     'y', "06"}, //$NON-NLS-2$
+                {0L,                        'z', "+0800"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'z', "+0800"}, //$NON-NLS-2$
+                {-1000L,                    'z', "+0800"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'z', "+0800"}, //$NON-NLS-2$
+                {paris,                     'z', "+0100"}, //$NON-NLS-2$
+                {china,                     'z', "-0800"}, //$NON-NLS-2$
+                
+        };
+        
+        final Object[][] lowerCaseFranceTriple = {
+                {0L,                        'a', "jeu."}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'a', "dim."}, //$NON-NLS-2$
+                {-1000L,                    'a', "jeu."}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'a', "jeu."}, //$NON-NLS-2$
+                {paris,                     'a', "lun."}, //$NON-NLS-2$
+                {china,                     'a', "lun."}, //$NON-NLS-2$
+                {0L,                        'b', "janv."}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'b', "ao\u00fbt"}, //$NON-NLS-2$
+                {-1000L,                    'b', "janv."}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'b', "mai"}, //$NON-NLS-2$
+                {paris,                     'b', "mai"}, //$NON-NLS-2$
+                {china,                     'b', "mai"}, //$NON-NLS-2$
+                {0L,                        'c', "jeu. janv. 01 08:00:00 UTC+08:00 1970"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'c', "dim. ao\u00fbt 17 15:18:47 UTC+08:00 292278994"}, //$NON-NLS-2$
+                {-1000L,                    'c', "jeu. janv. 01 07:59:59 UTC+08:00 1970"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'c', "jeu. mai 11 13:59:07 UTC+08:00 2006"}, //$NON-NLS-2$
+                {paris,                     'c', "lun. mai 08 12:00:00 HAEC 2006"}, //$NON-NLS-2$
+                {china,                     'c', "lun. mai 08 12:00:00 UTC-08:00 2006"}, //$NON-NLS-2$
+                {0L,                        'd', "01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'd', "17"}, //$NON-NLS-2$
+                {-1000L,                    'd', "01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'd', "11"}, //$NON-NLS-2$
+                {paris,                     'd', "08"}, //$NON-NLS-2$
+                {china,                     'd', "08"}, //$NON-NLS-2$
+                {0L,                        'e', "1"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'e', "17"}, //$NON-NLS-2$
+                {-1000L,                    'e', "1"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'e', "11"}, //$NON-NLS-2$
+                {paris,                     'e', "8"}, //$NON-NLS-2$
+                {china,                     'e', "8"}, //$NON-NLS-2$
+                {0L,                        'h', "janv."}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'h', "ao\u00fbt"}, //$NON-NLS-2$
+                {-1000L,                    'h', "janv."}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'h', "mai"}, //$NON-NLS-2$
+                {paris,                     'h', "mai"}, //$NON-NLS-2$
+                {china,                     'h', "mai"}, //$NON-NLS-2$
+                {0L,                        'j', "001"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'j', "229"}, //$NON-NLS-2$
+                {-1000L,                    'j', "001"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'j', "131"}, //$NON-NLS-2$
+                {paris,                     'j', "128"}, //$NON-NLS-2$
+                {china,                     'j', "128"}, //$NON-NLS-2$
+                {0L,                        'k', "8"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'k', "15"}, //$NON-NLS-2$
+                {-1000L,                    'k', "7"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'k', "13"}, //$NON-NLS-2$
+                {paris,                     'k', "12"}, //$NON-NLS-2$
+                {china,                     'k', "12"}, //$NON-NLS-2$
+                {0L,                        'l', "8"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'l', "3"}, //$NON-NLS-2$
+                {-1000L,                    'l', "7"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'l', "1"}, //$NON-NLS-2$
+                {paris,                     'l', "12"}, //$NON-NLS-2$
+                {china,                     'l', "12"}, //$NON-NLS-2$
+                {0L,                        'm', "01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'm', "08"}, //$NON-NLS-2$
+                {-1000L,                    'm', "01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'm', "05"}, //$NON-NLS-2$
+                {paris,                     'm', "05"}, //$NON-NLS-2$
+                {china,                     'm', "05"}, //$NON-NLS-2$
+                {0L,                        'p', "am"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'p', "pm"}, //$NON-NLS-2$
+                {-1000L,                    'p', "am"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'p', "pm"}, //$NON-NLS-2$
+                {paris,                     'p', "pm"}, //$NON-NLS-2$
+                {china,                     'p', "pm"}, //$NON-NLS-2$
+                {0L,                        'r', "08:00:00 AM"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'r', "03:18:47 PM"}, //$NON-NLS-2$
+                {-1000L,                    'r', "07:59:59 AM"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'r', "01:59:07 PM"}, //$NON-NLS-2$
+                {paris,                     'r', "12:00:00 PM"}, //$NON-NLS-2$
+                {china,                     'r', "12:00:00 PM"}, //$NON-NLS-2$
+                {0L,                        's', "0"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            's', "9223372036854775"}, //$NON-NLS-2$
+                {-1000L,                    's', "-1"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  's', "1147327147"}, //$NON-NLS-2$
+                {paris,                     's', "1147082400"}, //$NON-NLS-2$
+                {china,                     's', "1147118400"}, //$NON-NLS-2$
+                {0L,                        'y', "70"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'y', "94"}, //$NON-NLS-2$
+                {-1000L,                    'y', "70"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'y', "06"}, //$NON-NLS-2$
+                {paris,                     'y', "06"}, //$NON-NLS-2$
+                {china,                     'y', "06"}, //$NON-NLS-2$
+                {0L,                        'z', "+0800"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'z', "+0800"}, //$NON-NLS-2$
+                {-1000L,                    'z', "+0800"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'z', "+0800"}, //$NON-NLS-2$
+                {paris,                     'z', "+0100"}, //$NON-NLS-2$
+                {china,                     'z', "-0800"}, //$NON-NLS-2$
+                
+        };
+        
+        final Object[][] lowerCaseJapanTriple = {
+                {0L,                        'a', "\u6728"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'a', "\u65e5"}, //$NON-NLS-2$
+                {-1000L,                    'a', "\u6728"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'a', "\u6728"}, //$NON-NLS-2$
+                {paris,                     'a', "\u6708"}, //$NON-NLS-2$
+                {china,                     'a', "\u6708"}, //$NON-NLS-2$
+                {0L,                        'b', "1\u6708"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'b', "8\u6708"}, //$NON-NLS-2$
+                {-1000L,                    'b', "1\u6708"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'b', "5\u6708"}, //$NON-NLS-2$
+                {paris,                     'b', "5\u6708"}, //$NON-NLS-2$
+                {china,                     'b', "5\u6708"}, //$NON-NLS-2$
+                {0L,                        'c', "\u6728 1\u6708 01 08:00:00 GMT+08:00 1970"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'c', "\u65e5 8\u6708 17 15:18:47 GMT+08:00 292278994"}, //$NON-NLS-2$
+                {-1000L,                    'c', "\u6728 1\u6708 01 07:59:59 GMT+08:00 1970"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'c', "\u6728 5\u6708 11 13:59:07 GMT+08:00 2006"}, //$NON-NLS-2$
+                {paris,                     'c', "\u6708 5\u6708 08 12:00:00 GMT+02:00 2006"}, //$NON-NLS-2$
+                {china,                     'c', "\u6708 5\u6708 08 12:00:00 GMT-08:00 2006"}, //$NON-NLS-2$
+                {0L,                        'd', "01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'd', "17"}, //$NON-NLS-2$
+                {-1000L,                    'd', "01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'd', "11"}, //$NON-NLS-2$
+                {paris,                     'd', "08"}, //$NON-NLS-2$
+                {china,                     'd', "08"}, //$NON-NLS-2$
+                {0L,                        'e', "1"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'e', "17"}, //$NON-NLS-2$
+                {-1000L,                    'e', "1"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'e', "11"}, //$NON-NLS-2$
+                {paris,                     'e', "8"}, //$NON-NLS-2$
+                {china,                     'e', "8"}, //$NON-NLS-2$
+                {0L,                        'h', "1\u6708"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'h', "8\u6708"}, //$NON-NLS-2$
+                {-1000L,                    'h', "1\u6708"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'h', "5\u6708"}, //$NON-NLS-2$
+                {paris,                     'h', "5\u6708"}, //$NON-NLS-2$
+                {china,                     'h', "5\u6708"}, //$NON-NLS-2$
+                {0L,                        'j', "001"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'j', "229"}, //$NON-NLS-2$
+                {-1000L,                    'j', "001"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'j', "131"}, //$NON-NLS-2$
+                {paris,                     'j', "128"}, //$NON-NLS-2$
+                {china,                     'j', "128"}, //$NON-NLS-2$
+                {0L,                        'k', "8"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'k', "15"}, //$NON-NLS-2$
+                {-1000L,                    'k', "7"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'k', "13"}, //$NON-NLS-2$
+                {paris,                     'k', "12"}, //$NON-NLS-2$
+                {china,                     'k', "12"}, //$NON-NLS-2$
+                {0L,                        'l', "8"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'l', "3"}, //$NON-NLS-2$
+                {-1000L,                    'l', "7"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'l', "1"}, //$NON-NLS-2$
+                {paris,                     'l', "12"}, //$NON-NLS-2$
+                {china,                     'l', "12"}, //$NON-NLS-2$
+                {0L,                        'm', "01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'm', "08"}, //$NON-NLS-2$
+                {-1000L,                    'm', "01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'm', "05"}, //$NON-NLS-2$
+                {paris,                     'm', "05"}, //$NON-NLS-2$
+                {china,                     'm', "05"}, //$NON-NLS-2$
+                {0L,                        'p', "\u5348\u524d"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'p', "\u5348\u5f8c"}, //$NON-NLS-2$
+                {-1000L,                    'p', "\u5348\u524d"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'p', "\u5348\u5f8c"}, //$NON-NLS-2$
+                {paris,                     'p', "\u5348\u5f8c"}, //$NON-NLS-2$
+                {china,                     'p', "\u5348\u5f8c"}, //$NON-NLS-2$
+                {0L,                        'r', "08:00:00 \u5348\u524d"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'r', "03:18:47 \u5348\u5f8c"}, //$NON-NLS-2$
+                {-1000L,                    'r', "07:59:59 \u5348\u524d"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'r', "01:59:07 \u5348\u5f8c"}, //$NON-NLS-2$
+                {paris,                     'r', "12:00:00 \u5348\u5f8c"}, //$NON-NLS-2$
+                {china,                     'r', "12:00:00 \u5348\u5f8c"}, //$NON-NLS-2$
+                {0L,                        's', "0"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            's', "9223372036854775"}, //$NON-NLS-2$
+                {-1000L,                    's', "-1"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  's', "1147327147"}, //$NON-NLS-2$
+                {paris,                     's', "1147082400"}, //$NON-NLS-2$
+                {china,                     's', "1147118400"}, //$NON-NLS-2$
+                {0L,                        'y', "70"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'y', "94"}, //$NON-NLS-2$
+                {-1000L,                    'y', "70"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'y', "06"}, //$NON-NLS-2$
+                {paris,                     'y', "06"}, //$NON-NLS-2$
+                {china,                     'y', "06"}, //$NON-NLS-2$
+                {0L,                        'z', "+0800"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'z', "+0800"}, //$NON-NLS-2$
+                {-1000L,                    'z', "+0800"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'z', "+0800"}, //$NON-NLS-2$
+                {paris,                     'z', "+0100"}, //$NON-NLS-2$
+                {china,                     'z', "-0800"}, //$NON-NLS-2$
+        };
+
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+        for (int i = 0; i < 90; i++) {
+            // go through legal conversion 
+            String formatSpecifier = "%t" + lowerCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+            String formatSpecifierUpper = "%T" + lowerCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+            // test '%t'
+            f = new Formatter(Locale.GERMAN);
+            f.format(formatSpecifier, lowerCaseGermanTriple[i][input]);
+            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+                            + " Argument: " + lowerCaseGermanTriple[i][input], //$NON-NLS-2$
+                            lowerCaseGermanTriple[i][output], f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format(Locale.FRANCE, formatSpecifier, lowerCaseFranceTriple[i][input]);
+            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+                            + " Argument: " + lowerCaseFranceTriple[i][input], //$NON-NLS-2$
+                            lowerCaseFranceTriple[i][output], f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format(Locale.JAPAN, formatSpecifier, lowerCaseJapanTriple[i][input]);
+            assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+                            + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
+                            lowerCaseJapanTriple[i][output], f.toString());
+
+            // test '%T'
+            f = new Formatter(Locale.GERMAN);
+            f.format(formatSpecifierUpper, lowerCaseGermanTriple[i][input]);
+            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+                            + " Argument: " + lowerCaseGermanTriple[i][input], //$NON-NLS-2$
+                            ((String)lowerCaseGermanTriple[i][output])
+                                    .toUpperCase(Locale.US), f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format(Locale.FRANCE, formatSpecifierUpper, lowerCaseFranceTriple[i][input]);
+            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+                            + " Argument: " + lowerCaseFranceTriple[i][input], //$NON-NLS-2$
+                            ((String)lowerCaseFranceTriple[i][output])
+                                    .toUpperCase(Locale.US), f.toString());
+
+            f = new Formatter(Locale.GERMAN);
+            f.format(Locale.JAPAN, formatSpecifierUpper, lowerCaseJapanTriple[i][input]);
+            assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+                            + " Argument: " + lowerCaseJapanTriple[i][input], //$NON-NLS-2$
+                            ((String)lowerCaseJapanTriple[i][output])
+                                    .toUpperCase(Locale.US), f.toString());
+        }
+
+        final Object[][] upperCaseGermanTriple = {
+                {0L,                        'A', "Donnerstag"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'A', "Sonntag"}, //$NON-NLS-2$
+                {-1000L,                    'A', "Donnerstag"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'A', "Donnerstag"}, //$NON-NLS-2$
+                {paris,                     'A', "Montag"}, //$NON-NLS-2$
+                {china,                     'A', "Montag"}, //$NON-NLS-2$
+                {0L,                        'B', "Januar"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'B', "August"}, //$NON-NLS-2$
+                {-1000L,                    'B', "Januar"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'B', "Mai"}, //$NON-NLS-2$
+                {paris,                     'B', "Mai"}, //$NON-NLS-2$ 
+                {china,                     'B', "Mai"}, //$NON-NLS-2$
+                {0L,                        'C', "19"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'C', "2922789"}, //$NON-NLS-2$
+                {-1000L,                    'C', "19"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'C', "20"}, //$NON-NLS-2$
+                {paris,                     'C', "20"}, //$NON-NLS-2$
+                {china,                     'C', "20"}, //$NON-NLS-2$
+                {0L,                        'D', "01/01/70"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'D', "08/17/94"}, //$NON-NLS-2$
+                {-1000L,                    'D', "01/01/70"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'D', "05/11/06"}, //$NON-NLS-2$
+                {paris,                     'D', "05/08/06"}, //$NON-NLS-2$
+                {china,                     'D', "05/08/06"}, //$NON-NLS-2$
+                {0L,                        'F', "1970-01-01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'F', "292278994-08-17"}, //$NON-NLS-2$
+                {-1000L,                    'F', "1970-01-01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'F', "2006-05-11"}, //$NON-NLS-2$
+                {paris,                     'F', "2006-05-08"}, //$NON-NLS-2$
+                {china,                     'F', "2006-05-08"}, //$NON-NLS-2$
+                {0L,                        'H', "08"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'H', "15"}, //$NON-NLS-2$
+                {-1000L,                    'H', "07"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'H', "13"}, //$NON-NLS-2$
+                {paris,                     'H', "12"}, //$NON-NLS-2$
+                {china,                     'H', "12"}, //$NON-NLS-2$
+                {0L,                        'I', "08"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'I', "03"}, //$NON-NLS-2$
+                {-1000L,                    'I', "07"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'I', "01"}, //$NON-NLS-2$
+                {paris,                     'I', "12"}, //$NON-NLS-2$
+                {china,                     'I', "12"}, //$NON-NLS-2$
+                {0L,                        'L', "000"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'L', "807"}, //$NON-NLS-2$
+                {-1000L,                    'L', "000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'L', "578"}, //$NON-NLS-2$
+                {paris,                     'L', "453"}, //$NON-NLS-2$
+                {china,                     'L', "609"}, //$NON-NLS-2$
+                {0L,                        'M', "00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'M', "18"}, //$NON-NLS-2$
+                {-1000L,                    'M', "59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'M', "59"}, //$NON-NLS-2$
+                {paris,                     'M', "00"}, //$NON-NLS-2$
+                {china,                     'M', "00"}, //$NON-NLS-2$
+                {0L,                        'N', "000000000"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'N', "807000000"}, //$NON-NLS-2$
+                {-1000L,                    'N', "000000000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'N', "578000000"}, //$NON-NLS-2$
+                {paris,                     'N', "609000000"}, //$NON-NLS-2$
+                {china,                     'N', "609000000"}, //$NON-NLS-2$
+                {0L,                        'Q', "0"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Q', "9223372036854775807"}, //$NON-NLS-2$
+                {-1000L,                    'Q', "-1000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Q', "1147327147578"}, //$NON-NLS-2$
+                {paris,                     'Q', "1147082400453"}, //$NON-NLS-2$
+                {china,                     'Q', "1147118400609"}, //$NON-NLS-2$
+                {0L,                        'R', "08:00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'R', "15:18"}, //$NON-NLS-2$
+                {-1000L,                    'R', "07:59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'R', "13:59"}, //$NON-NLS-2$
+                {paris,                     'R', "12:00"}, //$NON-NLS-2$
+                {china,                     'R', "12:00"}, //$NON-NLS-2$
+                {0L,                        'S', "00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'S', "47"}, //$NON-NLS-2$
+                {-1000L,                    'S', "59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'S', "07"}, //$NON-NLS-2$
+                {paris,                     'S', "00"}, //$NON-NLS-2$
+                {china,                     'S', "00"}, //$NON-NLS-2$
+                {0L,                        'T', "08:00:00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'T', "15:18:47"}, //$NON-NLS-2$
+                {-1000L,                    'T', "07:59:59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'T', "13:59:07"}, //$NON-NLS-2$
+                {paris,                     'T', "12:00:00"}, //$NON-NLS-2$
+                {china,                     'T', "12:00:00"}, //$NON-NLS-2$
+                {0L,                        'Y', "1970"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Y', "292278994"}, //$NON-NLS-2$
+                {-1000L,                    'Y', "1970"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Y', "2006"}, //$NON-NLS-2$
+                {paris,                     'Y', "2006"}, //$NON-NLS-2$
+                {china,                     'Y', "2006"}, //$NON-NLS-2$
+                {0L,                        'Z', "CST"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Z', "CST"}, //$NON-NLS-2$
+                {-1000L,                    'Z', "CST"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Z', "CST"}, //$NON-NLS-2$
+                {paris,                     'Z', "CEST"}, //$NON-NLS-2$
+                {china,                     'Z', "GMT-08:00"}, //$NON-NLS-2$
+                
+        };
+        
+        final Object[][] upperCaseFranceTriple = {
+                {0L,                        'A', "jeudi"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'A', "dimanche"}, //$NON-NLS-2$
+                {-1000L,                    'A', "jeudi"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'A', "jeudi"}, //$NON-NLS-2$
+                {paris,                     'A', "lundi"}, //$NON-NLS-2$
+                {china,                     'A', "lundi"}, //$NON-NLS-2$
+                {0L,                        'B', "janvier"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'B', "ao\u00fbt"}, //$NON-NLS-2$
+                {-1000L,                    'B', "janvier"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'B', "mai"}, //$NON-NLS-2$
+                {paris,                     'B', "mai"}, //$NON-NLS-2$
+                {china,                     'B', "mai"}, //$NON-NLS-2$
+                {0L,                        'C', "19"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'C', "2922789"}, //$NON-NLS-2$
+                {-1000L,                    'C', "19"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'C', "20"}, //$NON-NLS-2$
+                {paris,                     'C', "20"}, //$NON-NLS-2$
+                {china,                     'C', "20"}, //$NON-NLS-2$
+                {0L,                        'D', "01/01/70"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'D', "08/17/94"}, //$NON-NLS-2$
+                {-1000L,                    'D', "01/01/70"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'D', "05/11/06"}, //$NON-NLS-2$
+                {paris,                     'D', "05/08/06"}, //$NON-NLS-2$
+                {china,                     'D', "05/08/06"}, //$NON-NLS-2$
+                {0L,                        'F', "1970-01-01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'F', "292278994-08-17"}, //$NON-NLS-2$
+                {-1000L,                    'F', "1970-01-01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'F', "2006-05-11"}, //$NON-NLS-2$
+                {paris,                     'F', "2006-05-08"}, //$NON-NLS-2$
+                {china,                     'F', "2006-05-08"}, //$NON-NLS-2$
+                {0L,                        'H', "08"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'H', "15"}, //$NON-NLS-2$
+                {-1000L,                    'H', "07"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'H', "13"}, //$NON-NLS-2$
+                {paris,                     'H', "12"}, //$NON-NLS-2$
+                {china,                     'H', "12"}, //$NON-NLS-2$
+                {0L,                        'I', "08"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'I', "03"}, //$NON-NLS-2$
+                {-1000L,                    'I', "07"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'I', "01"}, //$NON-NLS-2$
+                {paris,                     'I', "12"}, //$NON-NLS-2$
+                {china,                     'I', "12"}, //$NON-NLS-2$
+                {0L,                        'L', "000"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'L', "807"}, //$NON-NLS-2$
+                {-1000L,                    'L', "000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'L', "578"}, //$NON-NLS-2$
+                {paris,                     'L', "453"}, //$NON-NLS-2$
+                {china,                     'L', "609"}, //$NON-NLS-2$
+                {0L,                        'M', "00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'M', "18"}, //$NON-NLS-2$
+                {-1000L,                    'M', "59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'M', "59"}, //$NON-NLS-2$
+                {paris,                     'M', "00"}, //$NON-NLS-2$
+                {china,                     'M', "00"}, //$NON-NLS-2$
+                {0L,                        'N', "000000000"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'N', "807000000"}, //$NON-NLS-2$
+                {-1000L,                    'N', "000000000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'N', "578000000"}, //$NON-NLS-2$
+                {paris,                     'N', "453000000"}, //$NON-NLS-2$
+                {china,                     'N', "468000000"}, //$NON-NLS-2$
+                {0L,                        'Q', "0"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Q', "9223372036854775807"}, //$NON-NLS-2$
+                {-1000L,                    'Q', "-1000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Q', "1147327147578"}, //$NON-NLS-2$
+                {paris,                     'Q', "1147082400453"}, //$NON-NLS-2$
+                {china,                     'Q', "1147118400609"}, //$NON-NLS-2$
+                {0L,                        'R', "08:00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'R', "15:18"}, //$NON-NLS-2$
+                {-1000L,                    'R', "07:59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'R', "13:59"}, //$NON-NLS-2$
+                {paris,                     'R', "12:00"}, //$NON-NLS-2$
+                {china,                     'R', "12:00"}, //$NON-NLS-2$
+                {0L,                        'S', "00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'S', "47"}, //$NON-NLS-2$
+                {-1000L,                    'S', "59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'S', "07"}, //$NON-NLS-2$
+                {paris,                     'S', "00"}, //$NON-NLS-2$
+                {china,                     'S', "00"}, //$NON-NLS-2$
+                {0L,                        'T', "08:00:00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'T', "15:18:47"}, //$NON-NLS-2$
+                {-1000L,                    'T', "07:59:59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'T', "13:59:07"}, //$NON-NLS-2$
+                {paris,                     'T', "12:00:00"}, //$NON-NLS-2$
+                {china,                     'T', "12:00:00"}, //$NON-NLS-2$
+                {0L,                        'Y', "1970"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Y', "292278994"}, //$NON-NLS-2$
+                {-1000L,                    'Y', "1970"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Y', "2006"}, //$NON-NLS-2$
+                {paris,                     'Y', "2006"}, //$NON-NLS-2$
+                {china,                     'Y', "2006"}, //$NON-NLS-2$
+                {0L,                        'Z', "CST"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Z', "CST"}, //$NON-NLS-2$
+                {-1000L,                    'Z', "CST"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Z', "CST"}, //$NON-NLS-2$
+                {paris,                     'Z', "CEST"}, //$NON-NLS-2$
+                {china,                     'Z', "GMT-08:00"}, //$NON-NLS-2$
+                
+        };
+
+        final Object[][] upperCaseJapanTriple = {
+                {0L,                        'A', "\u6728\u66dc\u65e5"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'A', "\u65e5\u66dc\u65e5"}, //$NON-NLS-2$
+                {-1000L,                    'A', "\u6728\u66dc\u65e5"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'A', "\u6728\u66dc\u65e5"}, //$NON-NLS-2$
+                {paris,                     'A', "\u6708\u66dc\u65e5"}, //$NON-NLS-2$
+                {china,                     'A', "\u6708\u66dc\u65e5"}, //$NON-NLS-2$
+                {0L,                        'B', "1\u6708"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'B', "8\u6708"}, //$NON-NLS-2$
+                {-1000L,                    'B', "1\u6708"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'B', "5\u6708"}, //$NON-NLS-2$
+                {paris,                     'B', "5\u6708"}, //$NON-NLS-2$
+                {china,                     'B', "5\u6708"}, //$NON-NLS-2$
+                {0L,                        'C', "19"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'C', "2922789"}, //$NON-NLS-2$
+                {-1000L,                    'C', "19"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'C', "20"}, //$NON-NLS-2$ 
+                {paris,                     'C', "20"}, //$NON-NLS-2$
+                {china,                     'C', "20"}, //$NON-NLS-2$
+                {0L,                        'D', "01/01/70"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'D', "08/17/94"}, //$NON-NLS-2$
+                {-1000L,                    'D', "01/01/70"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'D', "05/11/06"}, //$NON-NLS-2$
+                {paris,                     'D', "05/08/06"}, //$NON-NLS-2$
+                {china,                     'D', "05/08/06"}, //$NON-NLS-2$
+                {0L,                        'F', "1970-01-01"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'F', "292278994-08-17"}, //$NON-NLS-2$
+                {-1000L,                    'F', "1970-01-01"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'F', "2006-05-11"}, //$NON-NLS-2$
+                {paris,                     'F', "2006-05-08"}, //$NON-NLS-2$
+                {china,                     'F', "2006-05-08"}, //$NON-NLS-2$
+                {0L,                        'H', "08"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'H', "15"}, //$NON-NLS-2$
+                {-1000L,                    'H', "07"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'H', "13"}, //$NON-NLS-2$
+                {paris,                     'H', "12"}, //$NON-NLS-2$
+                {china,                     'H', "12"}, //$NON-NLS-2$
+                {0L,                        'I', "08"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'I', "03"}, //$NON-NLS-2$
+                {-1000L,                    'I', "07"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'I', "01"}, //$NON-NLS-2$
+                {paris,                     'I', "12"}, //$NON-NLS-2$
+                {china,                     'I', "12"}, //$NON-NLS-2$
+                {0L,                        'L', "000"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'L', "807"}, //$NON-NLS-2$
+                {-1000L,                    'L', "000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'L', "578"}, //$NON-NLS-2$
+                {paris,                     'L', "453"}, //$NON-NLS-2$
+                {china,                     'L', "609"}, //$NON-NLS-2$
+                {0L,                        'M', "00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'M', "18"}, //$NON-NLS-2$
+                {-1000L,                    'M', "59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'M', "59"}, //$NON-NLS-2$
+                {paris,                     'M', "00"}, //$NON-NLS-2$
+                {china,                     'M', "00"}, //$NON-NLS-2$
+                {0L,                        'N', "000000000"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'N', "807000000"}, //$NON-NLS-2$
+                {-1000L,                    'N', "000000000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'N', "578000000"}, //$NON-NLS-2$
+                {paris,                     'N', "453000000"}, //$NON-NLS-2$
+                {china,                     'N', "468000000"}, //$NON-NLS-2$
+                {0L,                        'Q', "0"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Q', "9223372036854775807"}, //$NON-NLS-2$
+                {-1000L,                    'Q', "-1000"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Q', "1147327147578"}, //$NON-NLS-2$
+                {paris,                     'Q', "1147082400453"}, //$NON-NLS-2$
+                {china,                     'Q', "1147118400609"}, //$NON-NLS-2$
+                {0L,                        'R', "08:00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'R', "15:18"}, //$NON-NLS-2$
+                {-1000L,                    'R', "07:59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'R', "13:59"}, //$NON-NLS-2$
+                {paris,                     'R', "12:00"}, //$NON-NLS-2$
+                {china,                     'R', "12:00"}, //$NON-NLS-2$
+                {0L,                        'S', "00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'S', "47"}, //$NON-NLS-2$
+                {-1000L,                    'S', "59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'S', "07"}, //$NON-NLS-2$
+                {paris,                     'S', "00"}, //$NON-NLS-2$
+                {china,                     'S', "00"}, //$NON-NLS-2$
+                {0L,                        'T', "08:00:00"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'T', "15:18:47"}, //$NON-NLS-2$
+                {-1000L,                    'T', "07:59:59"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'T', "13:59:07"}, //$NON-NLS-2$
+                {paris,                     'T', "12:00:00"}, //$NON-NLS-2$
+                {china,                     'T', "12:00:00"}, //$NON-NLS-2$
+                {0L,                        'Y', "1970"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Y', "292278994"}, //$NON-NLS-2$
+                {-1000L,                    'Y', "1970"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Y', "2006"}, //$NON-NLS-2$
+                {paris,                     'Y', "2006"}, //$NON-NLS-2$
+                {china,                     'Y', "2006"}, //$NON-NLS-2$
+                {0L,                        'Z', "CST"}, //$NON-NLS-2$
+                {Long.MAX_VALUE,            'Z', "CST"}, //$NON-NLS-2$
+                {-1000L,                    'Z', "CST"}, //$NON-NLS-2$
+                {new Date(1147327147578L),  'Z', "CST"}, //$NON-NLS-2$
+                {paris,                     'Z', "CEST"}, //$NON-NLS-2$
+                {china,                     'Z', "GMT-08:00"}, //$NON-NLS-2$
+        };
+
+
+        for (int i = 0; i < 90; i++) {
+            String formatSpecifier = "%t" + upperCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+            String formatSpecifierUpper = "%T" + upperCaseGermanTriple[i][pattern]; //$NON-NLS-2$
+                    if ((Character)upperCaseGermanTriple[i][pattern] == 'N') {
+                        // result can't be predicted on RI, so skip this test
+                        continue;
+                    }
+                    // test '%t'
+                    f = new Formatter(Locale.JAPAN);
+                    f.format(formatSpecifier, upperCaseJapanTriple[i][input]);
+                    assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+                            + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
+                            upperCaseJapanTriple[i][output], f.toString());
+
+                    f = new Formatter(Locale.JAPAN);
+                    f.format(Locale.GERMAN, formatSpecifier, upperCaseGermanTriple[i][input]);
+                    assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+                            + " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
+                            upperCaseGermanTriple[i][output], f.toString());
+
+                    f = new Formatter(Locale.JAPAN);
+                    f.format(Locale.FRANCE, formatSpecifier, upperCaseFranceTriple[i][input]);
+                    assertEquals("Format pattern: " + formatSpecifier //$NON-NLS-2$
+                            + " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
+                            upperCaseFranceTriple[i][output], f.toString());
+
+                    // test '%T'
+                    f = new Formatter(Locale.GERMAN);
+                    f.format(formatSpecifierUpper, upperCaseGermanTriple[i][input]);
+                    assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+                            + " Argument: " + upperCaseGermanTriple[i][input], //$NON-NLS-2$
+                            ((String)upperCaseGermanTriple[i][output])
+                                    .toUpperCase(Locale.US), f.toString());
+
+                    f = new Formatter(Locale.GERMAN);
+                    f.format(Locale.JAPAN, formatSpecifierUpper, upperCaseJapanTriple[i][input]);
+                    assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+                            + " Argument: " + upperCaseJapanTriple[i][input], //$NON-NLS-2$
+                            ((String)upperCaseJapanTriple[i][output])
+                                    .toUpperCase(Locale.US), f.toString());
+
+                    f = new Formatter(Locale.GERMAN);
+                    f.format(Locale.FRANCE, formatSpecifierUpper, upperCaseFranceTriple[i][input]);
+                    assertEquals("Format pattern: " + formatSpecifierUpper //$NON-NLS-2$
+                            + " Argument: " + upperCaseFranceTriple[i][input], //$NON-NLS-2$
+                            ((String)upperCaseFranceTriple[i][output])
+                                    .toUpperCase(Locale.US), f.toString());
+        }
+
+        f = new Formatter(Locale.US);
+        f.format("%-10ta", now); //$NON-NLS-2$
+        assertEquals("Thu       ", f.toString()); //$NON-NLS-2$
+
+        f = new Formatter(Locale.US);
+        f.format("%10000000000000000000000000000000001ta", now); //$NON-NLS-2$
+        assertEquals("Thu", f.toString().trim()); //$NON-NLS-2$
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for null argment for
+     *        Byte/Short/Integer/Long/BigInteger conversion
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_ByteShortIntegerLongNullConversion() {
+
+        Formatter f = new Formatter(Locale.FRANCE);
+        f.format("%d%<o%<x%<5X", (Integer) null);
+        assertEquals("nullnullnull NULL", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%d%<#03o %<0#4x%<6X", (Long) null);
+        assertEquals("nullnull null  NULL", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%(+,07d%<o %<x%<6X", (Byte) null);
+        assertEquals("   nullnull null  NULL", f.toString());
+
+        f = new Formatter(Locale.ITALY);
+        f.format("%(+,07d%<o %<x%<0#6X", (Short) null);
+        assertEquals("   nullnull null  NULL", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%(+,-7d%<( o%<+(x %<( 06X", (BigInteger) null);
+        assertEquals("null   nullnull   NULL", f.toString());
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for legal
+     *        BigInteger conversion type 'd'
+     */
+    public void test_formatLjava_lang_String$LBigInteger() {
+        final Object[][] tripleD = {
+                {new BigInteger("123456789012345678901234567890"),          "%d",       "123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%10d",     "123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%-1d",     "123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%+d",      "+123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "% d",      " 123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%,d",      "123.456.789.012.345.678.901.234.567.890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%(d",      "123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%08d",     "123456789012345678901234567890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%-+,(11d", "+123.456.789.012.345.678.901.234.567.890"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%0 ,(11d", " 123.456.789.012.345.678.901.234.567.890"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%d",       "-9876543210987654321098765432100000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%10d",     "-9876543210987654321098765432100000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%-1d",     "-9876543210987654321098765432100000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%+d",      "-9876543210987654321098765432100000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "% d",      "-9876543210987654321098765432100000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%,d",      "-9.876.543.210.987.654.321.098.765.432.100.000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%(d",      "(9876543210987654321098765432100000)"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%08d",     "-9876543210987654321098765432100000"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%-+,(11d", "(9.876.543.210.987.654.321.098.765.432.100.000)"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%0 ,(11d", "(9.876.543.210.987.654.321.098.765.432.100.000)"}, //$NON-NLS-2$
+        };
+        
+        final int input = 0;
+        final int pattern = 1;
+        final int output = 2;
+        Formatter f;
+        for (int i = 0; i < tripleD.length; i++) {
+            f = new Formatter(Locale.GERMAN);
+            f.format((String) tripleD[i][pattern],
+                    tripleD[i][input]);
+            assertEquals("triple[" + i + "]:" + tripleD[i][input] + ",pattern["
+                    + i + "]:" + tripleD[i][pattern], tripleD[i][output], f
+                    .toString());
+            
+        }
+        
+        final Object[][] tripleO = {
+                {new BigInteger("123456789012345678901234567890"),          "%o",       "143564417755415637016711617605322"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%-6o",     "143564417755415637016711617605322"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%08o",     "143564417755415637016711617605322"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%#o",      "0143564417755415637016711617605322"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%0#11o",   "0143564417755415637016711617605322"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%-#9o",    "0143564417755415637016711617605322"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%o",       "-36336340043453651353467270113157312240"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%-6o",     "-36336340043453651353467270113157312240"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%08o",     "-36336340043453651353467270113157312240"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%#o",      "-036336340043453651353467270113157312240"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%0#11o",   "-036336340043453651353467270113157312240"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%-#9o",    "-036336340043453651353467270113157312240"}, //$NON-NLS-2$
+        };
+        for (int i = 0; i < tripleO.length; i++) {
+            f = new Formatter(Locale.ITALY);
+            f.format((String) tripleO[i][pattern],
+                    tripleO[i][input]);
+            assertEquals("triple[" + i + "]:" + tripleO[i][input] + ",pattern["
+                    + i + "]:" + tripleO[i][pattern], tripleO[i][output], f
+                    .toString());
+            
+        }
+        
+        final Object[][] tripleX = {
+                {new BigInteger("123456789012345678901234567890"),          "%x",       "18ee90ff6c373e0ee4e3f0ad2"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%-8x",     "18ee90ff6c373e0ee4e3f0ad2"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%06x",     "18ee90ff6c373e0ee4e3f0ad2"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%#x",      "0x18ee90ff6c373e0ee4e3f0ad2"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%0#12x",   "0x18ee90ff6c373e0ee4e3f0ad2"}, //$NON-NLS-2$
+                {new BigInteger("123456789012345678901234567890"),          "%-#9x",    "0x18ee90ff6c373e0ee4e3f0ad2"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%x",       "-1e6f380472bd4bae6eb8259bd94a0"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%-8x",     "-1e6f380472bd4bae6eb8259bd94a0"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%06x",     "-1e6f380472bd4bae6eb8259bd94a0"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%#x",      "-0x1e6f380472bd4bae6eb8259bd94a0"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%0#12x",   "-0x1e6f380472bd4bae6eb8259bd94a0"}, //$NON-NLS-2$
+                {new BigInteger("-9876543210987654321098765432100000"),     "%-#9x",    "-0x1e6f380472bd4bae6eb8259bd94a0"}, //$NON-NLS-2$
+        };
+        
+        for (int i = 0; i < tripleX.length; i++) {
+            f = new Formatter(Locale.FRANCE);
+            f.format((String) tripleX[i][pattern],
+                    tripleX[i][input]);
+            assertEquals("triple[" + i + "]:" + tripleX[i][input] + ",pattern["
+                    + i + "]:" + tripleX[i][pattern], tripleX[i][output], f
+                    .toString());
+            
+        }
+        
+        f = new Formatter(Locale.GERMAN);
+        f.format("%(+,-7d%<( o%<+(x %<( 06X", (BigInteger) null);
+        assertEquals("null   nullnull   NULL", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for padding of
+     *        BigInteger conversion
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerPaddingConversion() {
+        Formatter f = null;
+
+        BigInteger bigInt = new BigInteger("123456789012345678901234567890");
+        f = new Formatter(Locale.GERMAN);
+        f.format("%32d", bigInt);
+        assertEquals("  123456789012345678901234567890", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%+32x", bigInt);
+        assertEquals("      +18ee90ff6c373e0ee4e3f0ad2", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("% 32o", bigInt);
+        assertEquals(" 143564417755415637016711617605322", f.toString());
+
+        BigInteger negBigInt = new BigInteger(
+                "-1234567890123456789012345678901234567890");
+        f = new Formatter(Locale.GERMAN);
+        f.format("%( 040X", negBigInt);
+        assertEquals("(000003A0C92075C0DBF3B8ACBC5F96CE3F0AD2)", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%+(045d", negBigInt);
+        assertEquals("(0001234567890123456789012345678901234567890)", f
+                .toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%+,-(60d", negBigInt);
+        assertEquals(
+                "(1.234.567.890.123.456.789.012.345.678.901.234.567.890)     ",
+                f.toString());
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for BigInteger
+     *        conversion exception
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerConversionException() {
+        Formatter f = null;
+
+        final String[] flagsConversionMismatches = { "%#d", "%,o", "%,x", "%,X" };
+        for (int i = 0; i < flagsConversionMismatches.length; i++) {
+            try {
+                f = new Formatter(Locale.CHINA);
+                f.format(flagsConversionMismatches[i], new BigInteger("1"));
+                fail("should throw FormatFlagsConversionMismatchException");
+            } catch (FormatFlagsConversionMismatchException e) {
+                // expected
+            }
+        }
+
+        final String[] missingFormatWidths = { "%-0d", "%0d", "%-d", "%-0o",
+                "%0o", "%-o", "%-0x", "%0x", "%-x", "%-0X", "%0X", "%-X" };
+        for (int i = 0; i < missingFormatWidths.length; i++) {
+            try {
+                f = new Formatter(Locale.KOREA);
+                f.format(missingFormatWidths[i], new BigInteger("1"));
+                fail("should throw MissingFormatWidthException");
+            } catch (MissingFormatWidthException e) {
+                // expected
+            }
+        }
+
+        final String[] illFlags = { "%+ d", "%-08d", "%+ o", "%-08o", "%+ x",
+                "%-08x", "%+ X", "%-08X" };
+        for (int i = 0; i < illFlags.length; i++) {
+            try {
+                f = new Formatter(Locale.CANADA);
+                f.format(illFlags[i], new BigInteger("1"));
+                fail("should throw IllegalFormatFlagsException");
+            } catch (IllegalFormatFlagsException e) {
+                // expected
+            }
+        }
+
+        final String[] precisionExceptions = { "%.4d", "%2.5o", "%8.6x",
+                "%11.17X" };
+        for (int i = 0; i < precisionExceptions.length; i++) {
+            try {
+                f = new Formatter(Locale.US);
+                f.format(precisionExceptions[i], new BigInteger("1"));
+                fail("should throw IllegalFormatPrecisionException");
+            } catch (IllegalFormatPrecisionException e) {
+                // expected
+            }
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%D", new BigInteger("1"));
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%O", new BigInteger("1"));
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+
+        try {
+            f = new Formatter();
+            f.format("%010000000000000000000000000000000001d", new BigInteger(
+                    "1"));
+            fail("should throw MissingFormatWidthException");
+        } catch (MissingFormatWidthException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for BigInteger
+     *        exception throwing order
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigIntegerExceptionOrder() {
+        Formatter f = null;
+        BigInteger big = new BigInteger("100");
+
+        /*
+         * Order summary: UnknownFormatConversionException >
+         * MissingFormatWidthException > IllegalFormatFlagsException >
+         * IllegalFormatPrecisionException > IllegalFormatConversionException >
+         * FormatFlagsConversionMismatchException
+         * 
+         */
+        f = new Formatter(Locale.US);
+        try {
+            // compare IllegalFormatConversionException and
+            // FormatFlagsConversionMismatchException
+            f.format("%(o", false);
+            fail("should throw IllegalFormatConversionException");
+        } catch (IllegalFormatConversionException e) {
+            // expected
+        }
+
+        try {
+            // compare IllegalFormatPrecisionException and
+            // IllegalFormatConversionException
+            f.format("%.4o", false);
+            fail("should throw IllegalFormatPrecisionException");
+        } catch (IllegalFormatPrecisionException e) {
+            // expected
+        }
+
+        try {
+            // compare IllegalFormatFlagsException and
+            // IllegalFormatPrecisionException
+            f.format("%+ .4o", big);
+            fail("should throw IllegalFormatFlagsException");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+
+        try {
+            // compare MissingFormatWidthException and
+            // IllegalFormatFlagsException
+            f.format("%+ -o", big);
+            fail("should throw MissingFormatWidthException");
+        } catch (MissingFormatWidthException e) {
+            // expected
+        }
+
+        try {
+            // compare UnknownFormatConversionException and
+            // MissingFormatWidthException
+            f.format("%-O", big);
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+    }
+    
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Float/Double
+     *        conversion type 'e' and 'E'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionE() {
+        Formatter f = null;
+        final Object[][] tripleE = {
+                {0f, "%e",          "0.000000e+00"},
+                {0f, "%#.0e",       "0.e+00"},
+                {0f, "%#- (9.8e",   " 0.00000000e+00"},
+                {0f, "%#+0(8.4e",   "+0.0000e+00"},
+                {0f, "%-+(1.6e",    "+0.000000e+00"},
+                {0f, "% 0(12e",     " 0.000000e+00"},
+                
+                {101f, "%e",          "1.010000e+02"},
+                {101f, "%#.0e",       "1.e+02"},
+                {101f, "%#- (9.8e",   " 1.01000000e+02"},
+                {101f, "%#+0(8.4e",   "+1.0100e+02"},
+                {101f, "%-+(1.6e",    "+1.010000e+02"},
+                {101f, "% 0(12e",     " 1.010000e+02"},
+                
+                {1.f, "%e",          "1.000000e+00"},
+                {1.f, "%#.0e",       "1.e+00"},
+                {1.f, "%#- (9.8e",   " 1.00000000e+00"},
+                {1.f, "%#+0(8.4e",   "+1.0000e+00"},
+                {1.f, "%-+(1.6e",    "+1.000000e+00"},
+                {1.f, "% 0(12e",     " 1.000000e+00"},
+                
+                {-98f, "%e",          "-9.800000e+01"},
+                {-98f, "%#.0e",       "-1.e+02"},
+                {-98f, "%#- (9.8e",   "(9.80000000e+01)"},
+                {-98f, "%#+0(8.4e",   "(9.8000e+01)"},
+                {-98f, "%-+(1.6e",    "(9.800000e+01)"},
+                {-98f, "% 0(12e",     "(9.800000e+01)"},
+                
+                {1.23f, "%e",          "1.230000e+00"},
+                {1.23f, "%#.0e",       "1.e+00"},
+                {1.23f, "%#- (9.8e",   " 1.23000002e+00"},
+                {1.23f, "%#+0(8.4e",   "+1.2300e+00"},
+                {1.23f, "%-+(1.6e",    "+1.230000e+00"},
+                {1.23f, "% 0(12e",     " 1.230000e+00"},
+                
+                {34.1234567f, "%e",          "3.412346e+01"},
+                {34.1234567f, "%#.0e",       "3.e+01"},
+                {34.1234567f, "%#- (9.8e",   " 3.41234550e+01"},
+                {34.1234567f, "%#+0(8.4e",   "+3.4123e+01"},
+                {34.1234567f, "%-+(1.6e",    "+3.412346e+01"},
+                {34.1234567f, "% 0(12e",     " 3.412346e+01"},
+                
+                {-.12345f, "%e",          "-1.234500e-01"},
+                {-.12345f, "%#.0e",       "-1.e-01"},
+                {-.12345f, "%#- (9.8e",   "(1.23450004e-01)"},
+                {-.12345f, "%#+0(8.4e",   "(1.2345e-01)"},
+                {-.12345f, "%-+(1.6e",    "(1.234500e-01)"},
+                {-.12345f, "% 0(12e",     "(1.234500e-01)"},
+                
+                {-9876.1234567f, "%e",          "-9.876123e+03"},
+                {-9876.1234567f, "%#.0e",       "-1.e+04"},
+                {-9876.1234567f, "%#- (9.8e",   "(9.87612305e+03)"},
+                {-9876.1234567f, "%#+0(8.4e",   "(9.8761e+03)"},
+                {-9876.1234567f, "%-+(1.6e",    "(9.876123e+03)"},
+                {-9876.1234567f, "% 0(12e",     "(9.876123e+03)"},
+                
+                {Float.MAX_VALUE, "%e",          "3.402823e+38"},
+                {Float.MAX_VALUE, "%#.0e",       "3.e+38"},
+                {Float.MAX_VALUE, "%#- (9.8e",   " 3.40282347e+38"},
+                {Float.MAX_VALUE, "%#+0(8.4e",   "+3.4028e+38"},
+                {Float.MAX_VALUE, "%-+(1.6e",    "+3.402823e+38"},
+                {Float.MAX_VALUE, "% 0(12e",     " 3.402823e+38"},
+                
+                {Float.MIN_VALUE, "%e",          "1.401298e-45"},
+                {Float.MIN_VALUE, "%#.0e",       "1.e-45"},
+                {Float.MIN_VALUE, "%#- (9.8e",   " 1.40129846e-45"},
+                {Float.MIN_VALUE, "%#+0(8.4e",   "+1.4013e-45"},
+                {Float.MIN_VALUE, "%-+(1.6e",    "+1.401298e-45"},
+                {Float.MIN_VALUE, "% 0(12e",     " 1.401298e-45"},
+                
+                {Float.NaN, "%e",          "NaN"},
+                {Float.NaN, "%#.0e",       "NaN"},
+                {Float.NaN, "%#- (9.8e",   "NaN      "},
+                {Float.NaN, "%#+0(8.4e",   "     NaN"},
+                {Float.NaN, "%-+(1.6e",    "NaN"},
+                {Float.NaN, "% 0(12e",     "         NaN"},
+                
+                
+                {Float.NEGATIVE_INFINITY, "%e",          "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%#.0e",       "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%#- (9.8e",   "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%#+0(8.4e",   "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%-+(1.6e",    "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "% 0(12e",     "  (Infinity)"},
+                
+                {Float.NEGATIVE_INFINITY, "%e",          "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%#.0e",       "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%#- (9.8e",   "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%#+0(8.4e",   "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%-+(1.6e",    "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "% 0(12e",     "  (Infinity)"},
+                
+                {0d, "%e",          "0.000000e+00"},
+                {0d, "%#.0e",       "0.e+00"},
+                {0d, "%#- (9.8e",   " 0.00000000e+00"},
+                {0d, "%#+0(8.4e",   "+0.0000e+00"},
+                {0d, "%-+(1.6e",    "+0.000000e+00"},
+                {0d, "% 0(12e",     " 0.000000e+00"},
+                
+                {1d, "%e",          "1.000000e+00"},
+                {1d, "%#.0e",       "1.e+00"},
+                {1d, "%#- (9.8e",   " 1.00000000e+00"},
+                {1d, "%#+0(8.4e",   "+1.0000e+00"},
+                {1d, "%-+(1.6e",    "+1.000000e+00"},
+                {1d, "% 0(12e",     " 1.000000e+00"},
+                
+                {-1d, "%e",          "-1.000000e+00"},
+                {-1d, "%#.0e",       "-1.e+00"},
+                {-1d, "%#- (9.8e",   "(1.00000000e+00)"},
+                {-1d, "%#+0(8.4e",   "(1.0000e+00)"},
+                {-1d, "%-+(1.6e",    "(1.000000e+00)"},
+                {-1d, "% 0(12e",     "(1.000000e+00)"},
+                
+                
+                {.00000001d, "%e",          "1.000000e-08"},
+                {.00000001d, "%#.0e",       "1.e-08"},
+                {.00000001d, "%#- (9.8e",   " 1.00000000e-08"},
+                {.00000001d, "%#+0(8.4e",   "+1.0000e-08"},
+                {.00000001d, "%-+(1.6e",    "+1.000000e-08"},
+                {.00000001d, "% 0(12e",     " 1.000000e-08"},
+                
+                {9122.10d, "%e",          "9.122100e+03"},
+                {9122.10d, "%#.0e",       "9.e+03"},
+                {9122.10d, "%#- (9.8e",   " 9.12210000e+03"},
+                {9122.10d, "%#+0(8.4e",   "+9.1221e+03"},
+                {9122.10d, "%-+(1.6e",    "+9.122100e+03"},
+                {9122.10d, "% 0(12e",     " 9.122100e+03"},
+                
+                {0.1d, "%e",          "1.000000e-01"},
+                {0.1d, "%#.0e",       "1.e-01"},
+                {0.1d, "%#- (9.8e",   " 1.00000000e-01"},
+                {0.1d, "%#+0(8.4e",   "+1.0000e-01"},
+                {0.1d, "%-+(1.6e",    "+1.000000e-01"},
+                {0.1d, "% 0(12e",     " 1.000000e-01"},
+                
+                {-2.d, "%e",          "-2.000000e+00"},
+                {-2.d, "%#.0e",       "-2.e+00"},
+                {-2.d, "%#- (9.8e",   "(2.00000000e+00)"},
+                {-2.d, "%#+0(8.4e",   "(2.0000e+00)"},
+                {-2.d, "%-+(1.6e",    "(2.000000e+00)"},
+                {-2.d, "% 0(12e",     "(2.000000e+00)"},
+                
+                {-.39d, "%e",          "-3.900000e-01"},
+                {-.39d, "%#.0e",       "-4.e-01"},
+                {-.39d, "%#- (9.8e",   "(3.90000000e-01)"},
+                {-.39d, "%#+0(8.4e",   "(3.9000e-01)"},
+                {-.39d, "%-+(1.6e",    "(3.900000e-01)"},
+                {-.39d, "% 0(12e",     "(3.900000e-01)"},
+                
+                {-1234567890.012345678d, "%e",          "-1.234568e+09"},
+                {-1234567890.012345678d, "%#.0e",       "-1.e+09"},
+                {-1234567890.012345678d, "%#- (9.8e",   "(1.23456789e+09)"},
+                {-1234567890.012345678d, "%#+0(8.4e",   "(1.2346e+09)"},
+                {-1234567890.012345678d, "%-+(1.6e",    "(1.234568e+09)"},
+                {-1234567890.012345678d, "% 0(12e",     "(1.234568e+09)"},
+                
+                {Double.MAX_VALUE, "%e",          "1.797693e+308"},
+                {Double.MAX_VALUE, "%#.0e",       "2.e+308"},
+                {Double.MAX_VALUE, "%#- (9.8e",   " 1.79769313e+308"},
+                {Double.MAX_VALUE, "%#+0(8.4e",   "+1.7977e+308"},
+                {Double.MAX_VALUE, "%-+(1.6e",    "+1.797693e+308"},
+                {Double.MAX_VALUE, "% 0(12e",     " 1.797693e+308"},
+                
+                {Double.MIN_VALUE, "%e",          "4.900000e-324"},
+                {Double.MIN_VALUE, "%#.0e",       "5.e-324"},
+                {Double.MIN_VALUE, "%#- (9.8e",   " 4.90000000e-324"},
+                {Double.MIN_VALUE, "%#+0(8.4e",   "+4.9000e-324"},
+                {Double.MIN_VALUE, "%-+(1.6e",    "+4.900000e-324"},
+                {Double.MIN_VALUE, "% 0(12e",     " 4.900000e-324"},
+                
+                {Double.NaN, "%e",          "NaN"},
+                {Double.NaN, "%#.0e",       "NaN"},
+                {Double.NaN, "%#- (9.8e",   "NaN      "},
+                {Double.NaN, "%#+0(8.4e",   "     NaN"},
+                {Double.NaN, "%-+(1.6e",    "NaN"},
+                {Double.NaN, "% 0(12e",     "         NaN"},
+                
+                {Double.NEGATIVE_INFINITY, "%e",          "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%#.0e",       "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%#- (9.8e",   "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "%#+0(8.4e",   "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "%-+(1.6e",    "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "% 0(12e",     "  (Infinity)"},
+                
+                {Double.POSITIVE_INFINITY, "%e",          "Infinity"},
+                {Double.POSITIVE_INFINITY, "%#.0e",       "Infinity"},
+                {Double.POSITIVE_INFINITY, "%#- (9.8e",   " Infinity"},
+                {Double.POSITIVE_INFINITY, "%#+0(8.4e",   "+Infinity"},
+                {Double.POSITIVE_INFINITY, "%-+(1.6e",    "+Infinity"},
+                {Double.POSITIVE_INFINITY, "% 0(12e",     "    Infinity"},
+        };
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+            for (int i = 0; i < tripleE.length; i++) {
+                f = new Formatter(Locale.US);
+                f.format((String)tripleE[i][pattern], tripleE[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+                        + i + "]:" + tripleE[i][pattern],
+                        tripleE[i][output], f.toString());
+
+                // test for conversion type 'E'
+                f = new Formatter(Locale.US);
+                f.format(((String)tripleE[i][pattern]).toUpperCase(), tripleE[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+                        + i + "]:" + tripleE[i][pattern], ((String)tripleE[i][output])
+                        .toUpperCase(Locale.UK), f.toString());
+            }
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%e", 1001f);
+        /*
+         * fail on RI, spec says 'e' requires the output to be formatted in
+         * general scientific notation and the localization algorithm is
+         * applied. But RI format this case to 1.001000e+03, which does not
+         * conform to the German Locale
+         */
+        assertEquals("1,001000e+03", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Float/Double
+     *        conversion type 'g' and 'G'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG() {
+        Formatter f = null;
+        final Object[][] tripleG = {
+                {1001f, "%g",           "1001.00"},
+                {1001f, "%- (,9.8g",    " 1,001.0000"},
+                {1001f, "%+0(,8.4g",    "+001,001"},
+                {1001f, "%-+(,1.6g",    "+1,001.00"},
+                {1001f, "% 0(,12.0g",   " 0000001e+03"},
+                
+                {1.f, "%g",           "1.00000"},
+                {1.f, "%- (,9.8g",    " 1.0000000"},
+                {1.f, "%+0(,8.4g",    "+001.000"},
+                {1.f, "%-+(,1.6g",    "+1.00000"},
+                {1.f, "% 0(,12.0g",   " 00000000001"},
+                
+                {-98f, "%g",           "-98.0000"},
+                {-98f, "%- (,9.8g",    "(98.000000)"},
+                {-98f, "%+0(,8.4g",    "(098.00)"},
+                {-98f, "%-+(,1.6g",    "(98.0000)"},
+                {-98f, "% 0(,12.0g",   "(000001e+02)"},
+                
+                {0.000001f, "%g",           "1.00000e-06"},
+                {0.000001f, "%- (,9.8g",    " 1.0000000e-06"},
+                {0.000001f, "%+0(,8.4g",    "+1.000e-06"},
+                {0.000001f, "%-+(,1.6g",    "+1.00000e-06"},
+                {0.000001f, "% 0(,12.0g",   " 0000001e-06"},
+                
+                {345.1234567f, "%g",           "345.123"},
+                {345.1234567f, "%- (,9.8g",    " 345.12344"},
+                {345.1234567f, "%+0(,8.4g",    "+00345.1"},
+                {345.1234567f, "%-+(,1.6g",    "+345.123"},
+                {345.1234567f, "% 0(,12.0g",   " 0000003e+02"},
+
+                {-.00000012345f, "%g",           "-1.23450e-07"},
+                {-.00000012345f, "%- (,9.8g",    "(1.2344999e-07)"},
+                {-.00000012345f, "%+0(,8.4g",    "(1.234e-07)"},
+                {-.00000012345f, "%-+(,1.6g",    "(1.23450e-07)"},
+                {-.00000012345f, "% 0(,12.0g",   "(000001e-07)"},
+                
+                {-987.1234567f, "%g",           "-987.123"},
+                {-987.1234567f, "%- (,9.8g",    "(987.12347)"},
+                {-987.1234567f, "%+0(,8.4g",    "(0987.1)"},
+                {-987.1234567f, "%-+(,1.6g",    "(987.123)"},
+                {-987.1234567f, "% 0(,12.0g",   "(000001e+03)"},
+                
+                {Float.MAX_VALUE, "%g",           "3.40282e+38"},
+                {Float.MAX_VALUE, "%- (,9.8g",    " 3.4028235e+38"},
+                {Float.MAX_VALUE, "%+0(,8.4g",    "+3.403e+38"},
+                {Float.MAX_VALUE, "%-+(,1.6g",    "+3.40282e+38"},
+                {Float.MAX_VALUE, "% 0(,12.0g",   " 0000003e+38"},
+                
+                {Float.MIN_VALUE, "%g",           "1.40130e-45"},
+                {Float.MIN_VALUE, "%- (,9.8g",    " 1.4012985e-45"},
+                {Float.MIN_VALUE, "%+0(,8.4g",    "+1.401e-45"},
+                {Float.MIN_VALUE, "%-+(,1.6g",    "+1.40130e-45"},
+                {Float.MIN_VALUE, "% 0(,12.0g",   " 0000001e-45"},
+                
+                {Float.NaN, "%g",           "NaN"},
+                {Float.NaN, "%- (,9.8g",    "NaN      "},
+                {Float.NaN, "%+0(,8.4g",    "     NaN"},
+                {Float.NaN, "%-+(,1.6g",    "NaN"},
+                {Float.NaN, "% 0(,12.0g",   "         NaN"},
+                
+                {Float.NEGATIVE_INFINITY, "%g",           "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%- (,9.8g",    "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%+0(,8.4g",    "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%-+(,1.6g",    "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "% 0(,12.0g",   "  (Infinity)"},
+                
+                {Float.POSITIVE_INFINITY, "%g",           "Infinity"},
+                {Float.POSITIVE_INFINITY, "%- (,9.8g",    " Infinity"},
+                {Float.POSITIVE_INFINITY, "%+0(,8.4g",    "+Infinity"},
+                {Float.POSITIVE_INFINITY, "%-+(,1.6g",    "+Infinity"},
+                {Float.POSITIVE_INFINITY, "% 0(,12.0g",   "    Infinity"},
+                
+                {1d, "%g",           "1.00000"},
+                {1d, "%- (,9.8g",    " 1.0000000"},
+                {1d, "%+0(,8.4g",    "+001.000"},
+                {1d, "%-+(,1.6g",    "+1.00000"},
+                {1d, "% 0(,12.0g",   " 00000000001"},
+                
+                {-1d, "%g",           "-1.00000"},
+                {-1d, "%- (,9.8g",    "(1.0000000)"},
+                {-1d, "%+0(,8.4g",    "(01.000)"},
+                {-1d, "%-+(,1.6g",    "(1.00000)"},
+                {-1d, "% 0(,12.0g",   "(0000000001)"},
+                
+                {.00000001d, "%g",           "1.00000e-08"},
+                {.00000001d, "%- (,9.8g",    " 1.0000000e-08"},
+                {.00000001d, "%+0(,8.4g",    "+1.000e-08"},
+                {.00000001d, "%-+(,1.6g",    "+1.00000e-08"},
+                {.00000001d, "% 0(,12.0g",   " 0000001e-08"},
+                
+                {1912.10d, "%g",           "1912.10"},
+                {1912.10d, "%- (,9.8g",    " 1,912.1000"},
+                {1912.10d, "%+0(,8.4g",    "+001,912"},
+                {1912.10d, "%-+(,1.6g",    "+1,912.10"},
+                {1912.10d, "% 0(,12.0g",   " 0000002e+03"},
+                
+                {0.1d, "%g",           "0.100000"},
+                {0.1d, "%- (,9.8g",    " 0.10000000"},
+                {0.1d, "%+0(,8.4g",    "+00.1000"},
+                {0.1d, "%-+(,1.6g",    "+0.100000"},
+                {0.1d, "% 0(,12.0g",   " 000000000.1"},
+                
+                {-2.d, "%g",           "-2.00000"},
+                {-2.d, "%- (,9.8g",    "(2.0000000)"},
+                {-2.d, "%+0(,8.4g",    "(02.000)"},
+                {-2.d, "%-+(,1.6g",    "(2.00000)"},
+                {-2.d, "% 0(,12.0g",   "(0000000002)"},
+                
+                {-.00039d, "%g",           "-0.000390000"},
+                {-.00039d, "%- (,9.8g",    "(0.00039000000)"},
+                {-.00039d, "%+0(,8.4g",    "(0.0003900)"},
+                {-.00039d, "%-+(,1.6g",    "(0.000390000)"},
+                {-.00039d, "% 0(,12.0g",   "(00000.0004)"},
+                
+                {-1234567890.012345678d, "%g",           "-1.23457e+09"},
+                {-1234567890.012345678d, "%- (,9.8g",    "(1.2345679e+09)"},
+                {-1234567890.012345678d, "%+0(,8.4g",    "(1.235e+09)"},
+                {-1234567890.012345678d, "%-+(,1.6g",    "(1.23457e+09)"},
+                {-1234567890.012345678d, "% 0(,12.0g",   "(000001e+09)"},
+                
+                {Double.MAX_VALUE, "%g",           "1.79769e+308"},
+                {Double.MAX_VALUE, "%- (,9.8g",    " 1.7976931e+308"},
+                {Double.MAX_VALUE, "%+0(,8.4g",    "+1.798e+308"},
+                {Double.MAX_VALUE, "%-+(,1.6g",    "+1.79769e+308"},
+                {Double.MAX_VALUE, "% 0(,12.0g",   " 000002e+308"},
+                
+                {Double.MIN_VALUE, "%g",           "4.90000e-324"},
+                {Double.MIN_VALUE, "%- (,9.8g",    " 4.9000000e-324"},
+                {Double.MIN_VALUE, "%+0(,8.4g",    "+4.900e-324"},
+                {Double.MIN_VALUE, "%-+(,1.6g",    "+4.90000e-324"},
+                {Double.MIN_VALUE, "% 0(,12.0g",   " 000005e-324"},
+                
+                {Double.NaN, "%g",           "NaN"},
+                {Double.NaN, "%- (,9.8g",    "NaN      "},
+                {Double.NaN, "%+0(,8.4g",    "     NaN"},
+                {Double.NaN, "%-+(,1.6g",    "NaN"},
+                {Double.NaN, "% 0(,12.0g",   "         NaN"},
+                
+                {Double.NEGATIVE_INFINITY, "%g",           "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%- (,9.8g",    "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "%+0(,8.4g",    "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "%-+(,1.6g",    "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "% 0(,12.0g",   "  (Infinity)"},
+                
+                {Double.POSITIVE_INFINITY, "%g",           "Infinity"},
+                {Double.POSITIVE_INFINITY, "%- (,9.8g",    " Infinity"},
+                {Double.POSITIVE_INFINITY, "%+0(,8.4g",    "+Infinity"},
+                {Double.POSITIVE_INFINITY, "%-+(,1.6g",    "+Infinity"},
+                {Double.POSITIVE_INFINITY, "% 0(,12.0g",   "    Infinity"},
+                
+        };
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+            for (int i = 0; i < tripleG.length; i++) {
+                
+                f = new Formatter(Locale.US);
+                f.format((String)tripleG[i][pattern], tripleG[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+                        + i + "]:" + tripleG[i][pattern],
+                        tripleG[i][output], f.toString());
+
+                // test for conversion type 'G'
+                f = new Formatter(Locale.US);
+                f.format(((String)tripleG[i][pattern]).toUpperCase(), tripleG[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+                        + i + "]:" + tripleG[i][pattern], ((String)tripleG[i][output])
+                        .toUpperCase(Locale.UK), f.toString());
+            }
+
+        f = new Formatter(Locale.US);
+        f.format("%.5g", 0f);
+        assertEquals("0.0000", f.toString());
+
+        f = new Formatter(Locale.US);
+        f.format("%.0g", 0f);
+        /*
+         * fail on RI, spec says if the precision is 0, then it is taken to be
+         * 1. but RI throws ArrayIndexOutOfBoundsException.
+         */
+        assertEquals("0", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%g", 1001f);
+        /*
+         * fail on RI, spec says 'g' requires the output to be formatted in
+         * general scientific notation and the localization algorithm is
+         * applied. But RI format this case to 1001.00, which does not conform
+         * to the German Locale
+         */
+        assertEquals("1001,00", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Float/Double
+     *        conversion type 'g' and 'G' overflow
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG_Overflow() {
+        Formatter f = new Formatter();
+        f.format("%g", 999999.5);
+        assertEquals("1.00000e+06", f.toString());
+
+        f = new Formatter();
+        f.format("%g", 99999.5);
+        assertEquals("99999.5", f.toString());
+
+        f = new Formatter();
+        f.format("%.4g", 99.95);
+        assertEquals("99.95", f.toString());
+
+        f = new Formatter();
+        f.format("%g", 99.95);
+        assertEquals("99.9500", f.toString());
+
+        f = new Formatter();
+        f.format("%g", 0.9);
+        assertEquals("0.900000", f.toString());
+
+        f = new Formatter();
+        f.format("%.0g", 0.000095);
+        assertEquals("0.0001", f.toString());
+
+        f = new Formatter();
+        f.format("%g", 0.0999999);
+        assertEquals("0.0999999", f.toString());
+
+        f = new Formatter();
+        f.format("%g", 0.00009);
+        assertEquals("9.00000e-05", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Float/Double
+     *        conversion type 'f'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionF() {
+        Formatter f = null;
+
+        final Object[][] tripleF = {
+                {0f, "%f",          "0,000000"},
+                {0f, "%#.3f",       "0,000"},
+                {0f, "%,5f",        "0,000000"},
+                {0f, "%- (12.0f",   " 0          "},
+                {0f, "%#+0(1.6f",   "+0,000000"},
+                {0f, "%-+(8.4f",    "+0,0000 "},
+                {0f, "% 0#(9.8f",   " 0,00000000"},
+                
+                {1234f, "%f",          "1234,000000"},
+                {1234f, "%#.3f",       "1234,000"},
+                {1234f, "%,5f",        "1.234,000000"},
+                {1234f, "%- (12.0f",   " 1234       "},
+                {1234f, "%#+0(1.6f",   "+1234,000000"},
+                {1234f, "%-+(8.4f",    "+1234,0000"},
+                {1234f, "% 0#(9.8f",   " 1234,00000000"},
+                
+                {1.f, "%f",          "1,000000"},
+                {1.f, "%#.3f",       "1,000"},
+                {1.f, "%,5f",        "1,000000"},
+                {1.f, "%- (12.0f",   " 1          "},
+                {1.f, "%#+0(1.6f",   "+1,000000"},
+                {1.f, "%-+(8.4f",    "+1,0000 "},
+                {1.f, "% 0#(9.8f",   " 1,00000000"},
+                
+                {-98f, "%f",          "-98,000000"},
+                {-98f, "%#.3f",       "-98,000"},
+                {-98f, "%,5f",        "-98,000000"},
+                {-98f, "%- (12.0f",   "(98)        "},
+                {-98f, "%#+0(1.6f",   "(98,000000)"},
+                {-98f, "%-+(8.4f",    "(98,0000)"},
+                {-98f, "% 0#(9.8f",   "(98,00000000)"},
+                
+                {0.000001f, "%f",          "0,000001"},
+                {0.000001f, "%#.3f",       "0,000"},
+                {0.000001f, "%,5f",        "0,000001"},
+                {0.000001f, "%- (12.0f",   " 0          "},
+                {0.000001f, "%#+0(1.6f",   "+0,000001"},
+                {0.000001f, "%-+(8.4f",    "+0,0000 "},
+                {0.000001f, "% 0#(9.8f",   " 0,00000100"},
+                
+                {345.1234567f, "%f",          "345,123444"},
+                {345.1234567f, "%#.3f",       "345,123"},
+                {345.1234567f, "%,5f",        "345,123444"},
+                {345.1234567f, "%- (12.0f",   " 345        "},
+                {345.1234567f, "%#+0(1.6f",   "+345,123444"},
+                {345.1234567f, "%-+(8.4f",    "+345,1234"},
+                {345.1234567f, "% 0#(9.8f",   " 345,12344360"},
+                
+                {-.00000012345f, "%f",          "-0,000000"},
+                {-.00000012345f, "%#.3f",       "-0,000"},
+                {-.00000012345f, "%,5f",        "-0,000000"},
+                {-.00000012345f, "%- (12.0f",   "(0)         "},
+                {-.00000012345f, "%#+0(1.6f",   "(0,000000)"},
+                {-.00000012345f, "%-+(8.4f",    "(0,0000)"},
+                {-.00000012345f, "% 0#(9.8f",   "(0,00000012)"},
+                
+                {-987654321.1234567f, "%f",          "-987654336,000000"},
+                {-987654321.1234567f, "%#.3f",       "-987654336,000"},
+                {-987654321.1234567f, "%,5f",        "-987.654.336,000000"},
+                {-987654321.1234567f, "%- (12.0f",   "(987654336) "},
+                {-987654321.1234567f, "%#+0(1.6f",   "(987654336,000000)"},
+                {-987654321.1234567f, "%-+(8.4f",    "(987654336,0000)"},
+                {-987654321.1234567f, "% 0#(9.8f",   "(987654336,00000000)"},
+                
+                {Float.MAX_VALUE, "%f",          "340282346638528860000000000000000000000,000000"},
+                {Float.MAX_VALUE, "%#.3f",       "340282346638528860000000000000000000000,000"},
+                {Float.MAX_VALUE, "%,5f",        "340.282.346.638.528.860.000.000.000.000.000.000.000,000000"},
+                {Float.MAX_VALUE, "%- (12.0f",   " 340282346638528860000000000000000000000"},
+                {Float.MAX_VALUE, "%#+0(1.6f",   "+340282346638528860000000000000000000000,000000"},
+                {Float.MAX_VALUE, "%-+(8.4f",    "+340282346638528860000000000000000000000,0000"},
+                {Float.MAX_VALUE, "% 0#(9.8f",   " 340282346638528860000000000000000000000,00000000"},
+                
+                {Float.MIN_VALUE, "%f",          "0,000000"},
+                {Float.MIN_VALUE, "%#.3f",       "0,000"},
+                {Float.MIN_VALUE, "%,5f",        "0,000000"},
+                {Float.MIN_VALUE, "%- (12.0f",   " 0          "},
+                {Float.MIN_VALUE, "%#+0(1.6f",   "+0,000000"},
+                {Float.MIN_VALUE, "%-+(8.4f",    "+0,0000 "},
+                {Float.MIN_VALUE, "% 0#(9.8f",   " 0,00000000"},
+                
+                {Float.NaN, "%f",          "NaN"},
+                {Float.NaN, "%#.3f",       "NaN"},
+                {Float.NaN, "%,5f",        "  NaN"},
+                {Float.NaN, "%- (12.0f",   "NaN         "},
+                {Float.NaN, "%#+0(1.6f",   "NaN"},
+                {Float.NaN, "%-+(8.4f",    "NaN     "},
+                {Float.NaN, "% 0#(9.8f",   "      NaN"},
+                
+                {Float.NEGATIVE_INFINITY, "%f",          "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%#.3f",       "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%,5f",        "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%- (12.0f",   "(Infinity)  "},
+                {Float.NEGATIVE_INFINITY, "%#+0(1.6f",   "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "%-+(8.4f",    "(Infinity)"},
+                {Float.NEGATIVE_INFINITY, "% 0#(9.8f",   "(Infinity)"},
+                
+                {Float.POSITIVE_INFINITY, "%f",          "Infinity"},
+                {Float.POSITIVE_INFINITY, "%#.3f",       "Infinity"},
+                {Float.POSITIVE_INFINITY, "%,5f",        "Infinity"},
+                {Float.POSITIVE_INFINITY, "%- (12.0f",   " Infinity   "},
+                {Float.POSITIVE_INFINITY, "%#+0(1.6f",   "+Infinity"},
+                {Float.POSITIVE_INFINITY, "%-+(8.4f",    "+Infinity"},
+                {Float.POSITIVE_INFINITY, "% 0#(9.8f",   " Infinity"},
+                
+                
+                {0d, "%f",          "0,000000"},
+                {0d, "%#.3f",       "0,000"},
+                {0d, "%,5f",        "0,000000"},
+                {0d, "%- (12.0f",   " 0          "},
+                {0d, "%#+0(1.6f",   "+0,000000"},
+                {0d, "%-+(8.4f",    "+0,0000 "},
+                {0d, "% 0#(9.8f",   " 0,00000000"},
+                
+                {1d, "%f",          "1,000000"},
+                {1d, "%#.3f",       "1,000"},
+                {1d, "%,5f",        "1,000000"},
+                {1d, "%- (12.0f",   " 1          "},
+                {1d, "%#+0(1.6f",   "+1,000000"},
+                {1d, "%-+(8.4f",    "+1,0000 "},
+                {1d, "% 0#(9.8f",   " 1,00000000"},
+                
+                {-1d, "%f",          "-1,000000"},
+                {-1d, "%#.3f",       "-1,000"},
+                {-1d, "%,5f",        "-1,000000"},
+                {-1d, "%- (12.0f",   "(1)         "},
+                {-1d, "%#+0(1.6f",   "(1,000000)"},
+                {-1d, "%-+(8.4f",    "(1,0000)"},
+                {-1d, "% 0#(9.8f",   "(1,00000000)"},
+                
+                {.00000001d, "%f",          "0,000000"},
+                {.00000001d, "%#.3f",       "0,000"},
+                {.00000001d, "%,5f",        "0,000000"},
+                {.00000001d, "%- (12.0f",   " 0          "},
+                {.00000001d, "%#+0(1.6f",   "+0,000000"},
+                {.00000001d, "%-+(8.4f",    "+0,0000 "},
+                {.00000001d, "% 0#(9.8f",   " 0,00000001"},
+                
+                {1000.10d, "%f",          "1000,100000"},
+                {1000.10d, "%#.3f",       "1000,100"},
+                {1000.10d, "%,5f",        "1.000,100000"},
+                {1000.10d, "%- (12.0f",   " 1000       "},
+                {1000.10d, "%#+0(1.6f",   "+1000,100000"},
+                {1000.10d, "%-+(8.4f",    "+1000,1000"},
+                {1000.10d, "% 0#(9.8f",   " 1000,10000000"},
+                
+                {0.1d, "%f",          "0,100000"},
+                {0.1d, "%#.3f",       "0,100"},
+                {0.1d, "%,5f",        "0,100000"},
+                {0.1d, "%- (12.0f",   " 0          "},
+                {0.1d, "%#+0(1.6f",   "+0,100000"},
+                {0.1d, "%-+(8.4f",    "+0,1000 "},
+                {0.1d, "% 0#(9.8f",   " 0,10000000"},
+                
+                {-2.d, "%f",          "-2,000000"},
+                {-2.d, "%#.3f",       "-2,000"},
+                {-2.d, "%,5f",        "-2,000000"},
+                {-2.d, "%- (12.0f",   "(2)         "},
+                {-2.d, "%#+0(1.6f",   "(2,000000)"},
+                {-2.d, "%-+(8.4f",    "(2,0000)"},
+                {-2.d, "% 0#(9.8f",   "(2,00000000)"},
+                
+                {-.00009d, "%f",          "-0,000090"},
+                {-.00009d, "%#.3f",       "-0,000"},
+                {-.00009d, "%,5f",        "-0,000090"},
+                {-.00009d, "%- (12.0f",   "(0)         "},
+                {-.00009d, "%#+0(1.6f",   "(0,000090)"},
+                {-.00009d, "%-+(8.4f",    "(0,0001)"},
+                {-.00009d, "% 0#(9.8f",   "(0,00009000)"},
+                
+                {-1234567890.012345678d, "%f",          "-1234567890,012346"},
+                {-1234567890.012345678d, "%#.3f",       "-1234567890,012"},
+                {-1234567890.012345678d, "%,5f",        "-1.234.567.890,012346"},
+                {-1234567890.012345678d, "%- (12.0f",   "(1234567890)"},
+                {-1234567890.012345678d, "%#+0(1.6f",   "(1234567890,012346)"},
+                {-1234567890.012345678d, "%-+(8.4f",    "(1234567890,0123)"},
+                {-1234567890.012345678d, "% 0#(9.8f",   "(1234567890,01234580)"},
+                
+                {Double.MAX_VALUE, "%f",          "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000"},
+                {Double.MAX_VALUE, "%#.3f",       "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000"},
+                {Double.MAX_VALUE, "%,5f",        "179.769.313.486.231.570.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,000000"},
+                {Double.MAX_VALUE, "%- (12.0f",   " 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
+                {Double.MAX_VALUE, "%#+0(1.6f",   "+179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000"},
+                {Double.MAX_VALUE, "%-+(8.4f",    "+179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0000"},
+                {Double.MAX_VALUE, "% 0#(9.8f",   " 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,00000000"},
+                
+                {Double.MIN_VALUE, "%f",          "0,000000"},
+                {Double.MIN_VALUE, "%#.3f",       "0,000"},
+                {Double.MIN_VALUE, "%,5f",        "0,000000"},
+                {Double.MIN_VALUE, "%- (12.0f",   " 0          "},
+                {Double.MIN_VALUE, "%#+0(1.6f",   "+0,000000"},
+                {Double.MIN_VALUE, "%-+(8.4f",    "+0,0000 "},
+                {Double.MIN_VALUE, "% 0#(9.8f",   " 0,00000000"},
+                
+                {Double.NaN, "%f",          "NaN"},
+                {Double.NaN, "%#.3f",       "NaN"},
+                {Double.NaN, "%,5f",        "  NaN"},
+                {Double.NaN, "%- (12.0f",   "NaN         "},
+                {Double.NaN, "%#+0(1.6f",   "NaN"},
+                {Double.NaN, "%-+(8.4f",    "NaN     "},
+                {Double.NaN, "% 0#(9.8f",   "      NaN"},
+                
+                {Double.POSITIVE_INFINITY, "%f",          "Infinity"},
+                {Double.POSITIVE_INFINITY, "%#.3f",       "Infinity"},
+                {Double.POSITIVE_INFINITY, "%,5f",        "Infinity"},
+                {Double.POSITIVE_INFINITY, "%- (12.0f",   " Infinity   "},
+                {Double.POSITIVE_INFINITY, "%#+0(1.6f",   "+Infinity"},
+                {Double.POSITIVE_INFINITY, "%-+(8.4f",    "+Infinity"},
+                {Double.POSITIVE_INFINITY, "% 0#(9.8f",   " Infinity"},
+                
+                {Double.NEGATIVE_INFINITY, "%f",          "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%#.3f",       "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%,5f",        "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%- (12.0f",   "(Infinity)  "},
+                {Double.NEGATIVE_INFINITY, "%#+0(1.6f",   "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "%-+(8.4f",    "(Infinity)"},
+                {Double.NEGATIVE_INFINITY, "% 0#(9.8f",   "(Infinity)"},
+        };
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+            for (int i = 0; i < tripleF.length; i++) {
+                f = new Formatter(Locale.GERMAN);
+                f.format((String)tripleF[i][pattern], tripleF[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleF[i][input] + ",pattern["
+                        + i + "]:" + tripleF[i][pattern],
+                        tripleF[i][output], f.toString());
+            }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for Float/Double
+     *        conversion type 'a' and 'A'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionA() {
+        Formatter f = null;
+        final Object[][] tripleA = {
+                {-0f, "%a",         "-0x0.0p0"},
+                {-0f, "%#.3a",      "-0x0.000p0"},
+                {-0f, "%5a",        "-0x0.0p0"},
+                {-0f, "%- 12.0a",   "-0x0.0p0    "},
+                {-0f, "%#+01.6a",   "-0x0.000000p0"},
+                {-0f, "%-+8.4a",    "-0x0.0000p0"},
+                
+                {0f, "%a",         "0x0.0p0"},
+                {0f, "%#.3a",      "0x0.000p0"},
+                {0f, "%5a",        "0x0.0p0"},
+                {0f, "%- 12.0a",   " 0x0.0p0    "},
+                {0f, "%#+01.6a",   "+0x0.000000p0"},
+                {0f, "%-+8.4a",    "+0x0.0000p0"},
+                
+                {1234f, "%a",         "0x1.348p10"},
+                {1234f, "%#.3a",      "0x1.348p10"},
+                {1234f, "%5a",        "0x1.348p10"},
+                {1234f, "%- 12.0a",   " 0x1.3p10   "},
+                {1234f, "%#+01.6a",   "+0x1.348000p10"},
+                {1234f, "%-+8.4a",    "+0x1.3480p10"},
+                
+                {1.f, "%a",         "0x1.0p0"},
+                {1.f, "%#.3a",      "0x1.000p0"},
+                {1.f, "%5a",        "0x1.0p0"},
+                {1.f, "%- 12.0a",   " 0x1.0p0    "},
+                {1.f, "%#+01.6a",   "+0x1.000000p0"},
+                {1.f, "%-+8.4a",    "+0x1.0000p0"},
+                
+                {-98f, "%a",         "-0x1.88p6"},
+                {-98f, "%#.3a",      "-0x1.880p6"},
+                {-98f, "%5a",        "-0x1.88p6"},
+                {-98f, "%- 12.0a",   "-0x1.8p6    "},
+                {-98f, "%#+01.6a",   "-0x1.880000p6"},
+                {-98f, "%-+8.4a",    "-0x1.8800p6"},
+                
+                {345.1234567f, "%a",         "0x1.591f9ap8"},
+                {345.1234567f, "%5a",        "0x1.591f9ap8"},
+                {345.1234567f, "%#+01.6a",   "+0x1.591f9ap8"},
+                
+                {-987654321.1234567f, "%a",         "-0x1.d6f346p29"},
+                {-987654321.1234567f, "%#.3a",      "-0x1.d6fp29"},
+                {-987654321.1234567f, "%5a",        "-0x1.d6f346p29"},
+                {-987654321.1234567f, "%- 12.0a",   "-0x1.dp29   "},
+                {-987654321.1234567f, "%#+01.6a",   "-0x1.d6f346p29"},
+                {-987654321.1234567f, "%-+8.4a",    "-0x1.d6f3p29"},
+                
+                {Float.MAX_VALUE, "%a",         "0x1.fffffep127"},
+                {Float.MAX_VALUE, "%5a",        "0x1.fffffep127"},
+                {Float.MAX_VALUE, "%#+01.6a",   "+0x1.fffffep127"},
+                
+                {Float.NaN, "%a",         "NaN"},
+                {Float.NaN, "%#.3a",      "NaN"},
+                {Float.NaN, "%5a",        "  NaN"},
+                {Float.NaN, "%- 12.0a",   "NaN         "},
+                {Float.NaN, "%#+01.6a",   "NaN"},
+                {Float.NaN, "%-+8.4a",    "NaN     "},
+                
+                {Float.NEGATIVE_INFINITY, "%a",         "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%#.3a",      "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%5a",        "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%- 12.0a",   "-Infinity   "},
+                {Float.NEGATIVE_INFINITY, "%#+01.6a",   "-Infinity"},
+                {Float.NEGATIVE_INFINITY, "%-+8.4a",    "-Infinity"},
+                
+                {Float.POSITIVE_INFINITY, "%a",         "Infinity"},
+                {Float.POSITIVE_INFINITY, "%#.3a",      "Infinity"},
+                {Float.POSITIVE_INFINITY, "%5a",        "Infinity"},
+                {Float.POSITIVE_INFINITY, "%- 12.0a",   " Infinity   "},
+                {Float.POSITIVE_INFINITY, "%#+01.6a",   "+Infinity"},
+                {Float.POSITIVE_INFINITY, "%-+8.4a",    "+Infinity"},
+                
+                {-0d, "%a",         "-0x0.0p0"},
+                {-0d, "%#.3a",      "-0x0.000p0"},
+                {-0d, "%5a",        "-0x0.0p0"},
+                {-0d, "%- 12.0a",   "-0x0.0p0    "},
+                {-0d, "%#+01.6a",   "-0x0.000000p0"},
+                {-0d, "%-+8.4a",    "-0x0.0000p0"},
+
+                {0d, "%a",         "0x0.0p0"},
+                {0d, "%#.3a",      "0x0.000p0"},
+                {0d, "%5a",        "0x0.0p0"},
+                {0d, "%- 12.0a",   " 0x0.0p0    "},
+                {0d, "%#+01.6a",   "+0x0.000000p0"},
+                {0d, "%-+8.4a",    "+0x0.0000p0"},
+                
+                {1d, "%a",         "0x1.0p0"},
+                {1d, "%#.3a",      "0x1.000p0"},
+                {1d, "%5a",        "0x1.0p0"},
+                {1d, "%- 12.0a",   " 0x1.0p0    "},
+                {1d, "%#+01.6a",   "+0x1.000000p0"},
+                {1d, "%-+8.4a",    "+0x1.0000p0"},
+                
+                {-1d, "%a",         "-0x1.0p0"},
+                {-1d, "%#.3a",      "-0x1.000p0"},
+                {-1d, "%5a",        "-0x1.0p0"},
+                {-1d, "%- 12.0a",   "-0x1.0p0    "},
+                {-1d, "%#+01.6a",   "-0x1.000000p0"},
+                {-1d, "%-+8.4a",    "-0x1.0000p0"},
+                
+                {.00000001d, "%a",         "0x1.5798ee2308c3ap-27"},
+                {.00000001d, "%5a",        "0x1.5798ee2308c3ap-27"},
+                {.00000001d, "%- 12.0a",   " 0x1.5p-27  "},
+                {.00000001d, "%#+01.6a",   "+0x1.5798eep-27"},
+                
+                {1000.10d, "%a",         "0x1.f40cccccccccdp9"},
+                {1000.10d, "%5a",        "0x1.f40cccccccccdp9"},
+                {1000.10d, "%- 12.0a",   " 0x1.fp9    "},
+                
+                {0.1d, "%a",         "0x1.999999999999ap-4"},
+                {0.1d, "%5a",        "0x1.999999999999ap-4"},
+                
+                {-2.d, "%a",         "-0x1.0p1"},
+                {-2.d, "%#.3a",      "-0x1.000p1"},
+                {-2.d, "%5a",        "-0x1.0p1"},
+                {-2.d, "%- 12.0a",   "-0x1.0p1    "},
+                {-2.d, "%#+01.6a",   "-0x1.000000p1"},
+                {-2.d, "%-+8.4a",    "-0x1.0000p1"},
+                
+                {-.00009d, "%a",         "-0x1.797cc39ffd60fp-14"},
+                {-.00009d, "%5a",        "-0x1.797cc39ffd60fp-14"},
+                
+                {-1234567890.012345678d, "%a",         "-0x1.26580b480ca46p30"},
+                {-1234567890.012345678d, "%5a",        "-0x1.26580b480ca46p30"},
+                {-1234567890.012345678d, "%- 12.0a",   "-0x1.2p30   "},
+                {-1234567890.012345678d, "%#+01.6a",   "-0x1.26580bp30"},
+                {-1234567890.012345678d, "%-+8.4a",    "-0x1.2658p30"},
+                
+                {Double.MAX_VALUE, "%a",         "0x1.fffffffffffffp1023"},
+                {Double.MAX_VALUE, "%5a",        "0x1.fffffffffffffp1023"},
+                
+                {Double.MIN_VALUE, "%a",         "0x0.0000000000001p-1022"},
+                {Double.MIN_VALUE, "%5a",        "0x0.0000000000001p-1022"},
+                
+                {Double.NaN, "%a",         "NaN"},
+                {Double.NaN, "%#.3a",      "NaN"},
+                {Double.NaN, "%5a",        "  NaN"},
+                {Double.NaN, "%- 12.0a",   "NaN         "},
+                {Double.NaN, "%#+01.6a",   "NaN"},
+                {Double.NaN, "%-+8.4a",    "NaN     "},
+                
+                {Double.NEGATIVE_INFINITY, "%a",         "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%#.3a",      "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%5a",        "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%- 12.0a",   "-Infinity   "},
+                {Double.NEGATIVE_INFINITY, "%#+01.6a",   "-Infinity"},
+                {Double.NEGATIVE_INFINITY, "%-+8.4a",    "-Infinity"},
+                
+                {Double.POSITIVE_INFINITY, "%a",         "Infinity"},
+                {Double.POSITIVE_INFINITY, "%#.3a",      "Infinity"},
+                {Double.POSITIVE_INFINITY, "%5a",        "Infinity"},
+                {Double.POSITIVE_INFINITY, "%- 12.0a",   " Infinity   "},
+                {Double.POSITIVE_INFINITY, "%#+01.6a",   "+Infinity"},
+                {Double.POSITIVE_INFINITY, "%-+8.4a",    "+Infinity"},
+                
+        };
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+            for (int i = 0; i < tripleA.length; i++) {
+                f = new Formatter(Locale.UK);
+                f.format((String)tripleA[i][pattern], tripleA[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleA[i][input] + ",pattern["
+                        + i + "]:" + tripleA[i][pattern],
+                        tripleA[i][output], f.toString());
+
+                // test for conversion type 'A'
+                f = new Formatter(Locale.UK);
+                f.format(((String)tripleA[i][pattern]).toUpperCase(), tripleA[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleA[i][input] + ",pattern["
+                        + i + "]:" + tripleA[i][pattern], ((String)tripleA[i][output])
+                        .toUpperCase(Locale.UK), f.toString());
+            }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for BigDecimal
+     *        conversion type 'e' and 'E'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionE() {
+        Formatter f = null;
+        final Object[][] tripleE = {
+                {BigDecimal.ZERO, "%e",         "0.000000e+00"},
+                {BigDecimal.ZERO, "%#.0e",      "0.e+00"},
+                {BigDecimal.ZERO, "%# 9.8e",    " 0.00000000e+00"},
+                {BigDecimal.ZERO, "%#+0(8.4e",  "+0.0000e+00"},
+                {BigDecimal.ZERO, "%-+17.6e",   "+0.000000e+00    "},
+                {BigDecimal.ZERO, "% 0(20e",    " 00000000.000000e+00"},
+                
+                {BigDecimal.ONE, "%e",         "1.000000e+00"},
+                {BigDecimal.ONE, "%#.0e",      "1.e+00"},
+                {BigDecimal.ONE, "%# 9.8e",    " 1.00000000e+00"},
+                {BigDecimal.ONE, "%#+0(8.4e",  "+1.0000e+00"},
+                {BigDecimal.ONE, "%-+17.6e",   "+1.000000e+00    "},
+                {BigDecimal.ONE, "% 0(20e",    " 00000001.000000e+00"},
+                
+                {BigDecimal.TEN, "%e",         "1.000000e+01"},
+                {BigDecimal.TEN, "%#.0e",      "1.e+01"},
+                {BigDecimal.TEN, "%# 9.8e",    " 1.00000000e+01"},
+                {BigDecimal.TEN, "%#+0(8.4e",  "+1.0000e+01"},
+                {BigDecimal.TEN, "%-+17.6e",   "+1.000000e+01    "},
+                {BigDecimal.TEN, "% 0(20e",    " 00000001.000000e+01"},
+                
+                {new BigDecimal(-1), "%e",         "-1.000000e+00"},
+                {new BigDecimal(-1), "%#.0e",      "-1.e+00"},
+                {new BigDecimal(-1), "%# 9.8e",    "-1.00000000e+00"},
+                {new BigDecimal(-1), "%#+0(8.4e",  "(1.0000e+00)"},
+                {new BigDecimal(-1), "%-+17.6e",   "-1.000000e+00    "},
+                {new BigDecimal(-1), "% 0(20e",    "(0000001.000000e+00)"},
+                
+                {new BigDecimal("5.000E999"), "%e",         "5.000000e+999"},
+                {new BigDecimal("5.000E999"), "%#.0e",      "5.e+999"},
+                {new BigDecimal("5.000E999"), "%# 9.8e",    " 5.00000000e+999"},
+                {new BigDecimal("5.000E999"), "%#+0(8.4e",  "+5.0000e+999"},
+                {new BigDecimal("5.000E999"), "%-+17.6e",   "+5.000000e+999   "},
+                {new BigDecimal("5.000E999"), "% 0(20e",    " 0000005.000000e+999"},
+                
+                {new BigDecimal("-5.000E999"), "%e",         "-5.000000e+999"},
+                {new BigDecimal("-5.000E999"), "%#.0e",      "-5.e+999"},
+                {new BigDecimal("-5.000E999"), "%# 9.8e",    "-5.00000000e+999"},
+                {new BigDecimal("-5.000E999"), "%#+0(8.4e",  "(5.0000e+999)"},
+                {new BigDecimal("-5.000E999"), "%-+17.6e",   "-5.000000e+999   "},
+                {new BigDecimal("-5.000E999"), "% 0(20e",    "(000005.000000e+999)"},
+        };
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+            for (int i = 0; i < tripleE.length; i++) {
+                f = new Formatter(Locale.US);
+                f.format((String)tripleE[i][pattern], tripleE[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+                        + i + "]:" + tripleE[i][pattern],
+                        tripleE[i][output], f.toString());
+
+                // test for conversion type 'E'
+                f = new Formatter(Locale.US);
+                f.format(((String)tripleE[i][pattern]).toUpperCase(), tripleE[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleE[i][input] + ",pattern["
+                        + i + "]:" + tripleE[i][pattern], ((String)tripleE[i][output])
+                        .toUpperCase(Locale.US), f.toString());
+            }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for BigDecimal
+     *        conversion type 'g' and 'G'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionG() {
+        Formatter f = null;
+        final Object[][] tripleG = {
+                {BigDecimal.ZERO, "%g",         "0.00000"},
+                {BigDecimal.ZERO, "%.5g",       "0.0000"},
+                {BigDecimal.ZERO, "%- (,9.8g",  " 0.0000000"},
+                {BigDecimal.ZERO, "%+0(,8.4g",  "+000.000"},
+                {BigDecimal.ZERO, "%-+10.6g",   "+0.00000  "},
+                {BigDecimal.ZERO, "% 0(,12.0g", " 00000000000"},
+                {BigDecimal.ONE, "%g",          "1.00000"},
+                {BigDecimal.ONE, "%.5g",        "1.0000"},
+                {BigDecimal.ONE, "%- (,9.8g",   " 1.0000000"},
+                {BigDecimal.ONE, "%+0(,8.4g",   "+001.000"},
+                {BigDecimal.ONE, "%-+10.6g",    "+1.00000  "},
+                {BigDecimal.ONE, "% 0(,12.0g",  " 00000000001"},
+                
+                {new BigDecimal(-1), "%g",          "-1.00000"},
+                {new BigDecimal(-1), "%.5g",        "-1.0000"},
+                {new BigDecimal(-1), "%- (,9.8g",   "(1.0000000)"},
+                {new BigDecimal(-1), "%+0(,8.4g",   "(01.000)"},
+                {new BigDecimal(-1), "%-+10.6g",    "-1.00000  "},
+                {new BigDecimal(-1), "% 0(,12.0g",  "(0000000001)"},
+                
+                {new BigDecimal(-0.000001), "%g",           "-1.00000e-06"},
+                {new BigDecimal(-0.000001), "%.5g",         "-1.0000e-06"},
+                {new BigDecimal(-0.000001), "%- (,9.8g",    "(1.0000000e-06)"},
+                {new BigDecimal(-0.000001), "%+0(,8.4g",    "(1.000e-06)"},
+                {new BigDecimal(-0.000001), "%-+10.6g",     "-1.00000e-06"},
+                {new BigDecimal(-0.000001), "% 0(,12.0g",   "(000001e-06)"},
+                
+                {new BigDecimal(0.0002), "%g",          "0.000200000"},
+                {new BigDecimal(0.0002), "%.5g",        "0.00020000"},
+                {new BigDecimal(0.0002), "%- (,9.8g",   " 0.00020000000"},
+                {new BigDecimal(0.0002), "%+0(,8.4g",   "+0.0002000"},
+                {new BigDecimal(0.0002), "%-+10.6g",    "+0.000200000"},
+                {new BigDecimal(0.0002), "% 0(,12.0g",  " 000000.0002"},
+                
+                {new BigDecimal(-0.003), "%g",          "-0.00300000"},
+                {new BigDecimal(-0.003), "%.5g",        "-0.0030000"},
+                {new BigDecimal(-0.003), "%- (,9.8g",   "(0.0030000000)"},
+                {new BigDecimal(-0.003), "%+0(,8.4g",   "(0.003000)"},
+                {new BigDecimal(-0.003), "%-+10.6g",    "-0.00300000"},
+                {new BigDecimal(-0.003), "% 0(,12.0g",  "(000000.003)"},
+                
+                {new BigDecimal("5.000E999"), "%g",             "5.00000e+999"},
+                {new BigDecimal("5.000E999"), "%.5g",           "5.0000e+999"},
+                {new BigDecimal("5.000E999"), "%- (,9.8g",      " 5.0000000e+999"},
+                {new BigDecimal("5.000E999"), "%+0(,8.4g",      "+5.000e+999"},
+                {new BigDecimal("5.000E999"), "%-+10.6g",       "+5.00000e+999"},
+                {new BigDecimal("5.000E999"), "% 0(,12.0g",     " 000005e+999"},
+                
+                {new BigDecimal("-5.000E999"), "%g",            "-5.00000e+999"},
+                {new BigDecimal("-5.000E999"), "%.5g",          "-5.0000e+999"},
+                {new BigDecimal("-5.000E999"), "%- (,9.8g",     "(5.0000000e+999)"},
+                {new BigDecimal("-5.000E999"), "%+0(,8.4g",     "(5.000e+999)"},
+                {new BigDecimal("-5.000E999"), "%-+10.6g",      "-5.00000e+999"},
+                {new BigDecimal("-5.000E999"), "% 0(,12.0g",    "(00005e+999)"},
+        };
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+            for (int i = 0; i < tripleG.length; i++) {
+                f = new Formatter(Locale.US);
+                f.format((String)tripleG[i][pattern], tripleG[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+                        + i + "]:" + tripleG[i][pattern],
+                        tripleG[i][output], f.toString());
+
+                // test for conversion type 'G'
+                f = new Formatter(Locale.US);
+                f.format(((String)tripleG[i][pattern]).toUpperCase(), tripleG[i][input]);
+                assertEquals("triple[" + i + "]:" + tripleG[i][input] + ",pattern["
+                        + i + "]:" + tripleG[i][pattern], ((String)tripleG[i][output])
+                        .toUpperCase(Locale.US), f.toString());
+            }
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%- (,9.6g", new BigDecimal("4E6"));
+        /*
+         * fail on RI, spec says 'g' requires the output to be formatted in
+         * general scientific notation and the localization algorithm is
+         * applied. But RI format this case to 4.00000e+06, which does not
+         * conform to the German Locale
+         */
+        assertEquals(" 4,00000e+06", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for BigDecimal
+     *        conversion type 'f'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionF() {
+
+        Formatter f = null;
+        final int input   = 0;
+        final int pattern = 1;
+        final int output  = 2;
+        final Object[][] tripleF = {
+                {BigDecimal.ZERO,                                               "%f",           "0.000000"},
+                {BigDecimal.ZERO,                                               "%#.3f",        "0.000"},
+                {BigDecimal.ZERO,                                               "%#,5f",        "0.000000"},
+                {BigDecimal.ZERO,                                               "%- #(12.0f",   " 0.         "},
+                {BigDecimal.ZERO,                                               "%#+0(1.6f",    "+0.000000"},
+                {BigDecimal.ZERO,                                               "%-+(8.4f",     "+0.0000 "},
+                {BigDecimal.ZERO,                                               "% 0#(9.8f",    " 0.00000000"},
+                {BigDecimal.ONE,                                                "%f",           "1.000000"},
+                {BigDecimal.ONE,                                                "%#.3f",        "1.000"},
+                {BigDecimal.ONE,                                                "%#,5f",        "1.000000"},
+                {BigDecimal.ONE,                                                "%- #(12.0f",   " 1.         "},
+                {BigDecimal.ONE,                                                "%#+0(1.6f",    "+1.000000"},
+                {BigDecimal.ONE,                                                "%-+(8.4f",     "+1.0000 "},
+                {BigDecimal.ONE,                                                "% 0#(9.8f",    " 1.00000000"},
+                {BigDecimal.TEN,                                                "%f",           "10.000000"},
+                {BigDecimal.TEN,                                                "%#.3f",        "10.000"},
+                {BigDecimal.TEN,                                                "%#,5f",        "10.000000"},
+                {BigDecimal.TEN,                                                "%- #(12.0f",   " 10.        "},
+                {BigDecimal.TEN,                                                "%#+0(1.6f",    "+10.000000"},
+                {BigDecimal.TEN,                                                "%-+(8.4f",     "+10.0000"},
+                {BigDecimal.TEN,                                                "% 0#(9.8f",    " 10.00000000"},
+                {new BigDecimal(-1),                                            "%f",           "-1.000000"},
+                {new BigDecimal(-1),                                            "%#.3f",        "-1.000"},
+                {new BigDecimal(-1),                                            "%#,5f",        "-1.000000"},
+                {new BigDecimal(-1),                                            "%- #(12.0f",   "(1.)        "},
+                {new BigDecimal(-1),                                            "%#+0(1.6f",    "(1.000000)"},
+                {new BigDecimal(-1),                                            "%-+(8.4f",     "(1.0000)"},
+                {new BigDecimal(-1),                                            "% 0#(9.8f",    "(1.00000000)"},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "%f",           "9999999999999999999999999999999999999999999.000000"},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "%#.3f",        "9999999999999999999999999999999999999999999.000"},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "%#,5f",        "9,999,999,999,999,999,999,999,999,999,999,999,999,999,999.000000"},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "%- #(12.0f",   " 9999999999999999999999999999999999999999999."},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "%#+0(1.6f",    "+9999999999999999999999999999999999999999999.000000"},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "%-+(8.4f",     "+9999999999999999999999999999999999999999999.0000"},
+                {new BigDecimal("9999999999999999999999999999999999999999999"), "% 0#(9.8f",    " 9999999999999999999999999999999999999999999.00000000"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "%f",          "-9999999999999999999999999999999999999999999.000000"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "%#.3f",       "-9999999999999999999999999999999999999999999.000"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "%#,5f",       "-9,999,999,999,999,999,999,999,999,999,999,999,999,999,999.000000"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "%- #(12.0f",  "(9999999999999999999999999999999999999999999.)"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "%#+0(1.6f",   "(9999999999999999999999999999999999999999999.000000)"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "%-+(8.4f",    "(9999999999999999999999999999999999999999999.0000)"},
+                {new BigDecimal("-9999999999999999999999999999999999999999999"), "% 0#(9.8f",   "(9999999999999999999999999999999999999999999.00000000)"},
+        }; 
+        for (int i = 0; i < tripleF.length; i++) {
+            f = new Formatter(Locale.US);
+            f.format((String)tripleF[i][pattern], tripleF[i][input]);
+            assertEquals("triple[" + i + "]:" + tripleF[i][input] + ",pattern["
+                    + i + "]:" + tripleF[i][pattern], tripleF[i][output], f.toString());
+        }
+
+        f = new Formatter(Locale.US);
+        f.format("%f", new BigDecimal("5.0E9"));
+        // error on RI
+        // RI throw ArrayIndexOutOfBoundsException
+        assertEquals("5000000000.000000", f.toString());
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for exceptions in
+     *        Float/Double/BigDecimal conversion type 'e', 'E', 'g', 'G', 'f', 'a', 'A'
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalConversionException() {
+        Formatter f = null;
+
+        final char[] conversions = { 'e', 'E', 'g', 'G', 'f', 'a', 'A' };
+        final Object[] illArgs = { false, (byte) 1, (short) 2, 3, (long) 4,
+                new BigInteger("5"), new Character('c'), new Object(),
+                new Date() };
+        for (int i = 0; i < illArgs.length; i++) {
+            for (int j = 0; j < conversions.length; j++) {
+                try {
+                    f = new Formatter(Locale.UK);
+                    f.format("%" + conversions[j], illArgs[i]);
+                    fail("should throw IllegalFormatConversionException");
+                } catch (IllegalFormatConversionException e) {
+                    // expected
+                }
+            }
+        }
+
+        try {
+            f = new Formatter(Locale.UK);
+            f.format("%a", new BigDecimal(1));
+            fail("should throw IllegalFormatConversionException");
+        } catch (IllegalFormatConversionException e) {
+            // expected
+        }
+
+        try {
+            f = new Formatter(Locale.UK);
+            f.format("%A", new BigDecimal(1));
+            fail("should throw IllegalFormatConversionException");
+        } catch (IllegalFormatConversionException e) {
+            // expected
+        }
+
+        final String[] flagsConversionMismatches = { "%,e", "%,E", "%#g",
+                "%#G", "%,a", "%,A", "%(a", "%(A" };
+        for (int i = 0; i < flagsConversionMismatches.length; i++) {
+            try {
+                f = new Formatter(Locale.CHINA);
+                f.format(flagsConversionMismatches[i], new BigDecimal(1));
+                fail("should throw FormatFlagsConversionMismatchException");
+            } catch (FormatFlagsConversionMismatchException e) {
+                // expected
+            }
+            try {
+                f = new Formatter(Locale.JAPAN);
+                f.format(flagsConversionMismatches[i], (BigDecimal) null);
+                fail("should throw FormatFlagsConversionMismatchException");
+            } catch (FormatFlagsConversionMismatchException e) {
+                // expected
+            }
+        }
+
+        final String[] missingFormatWidths = { "%-0e", "%0e", "%-e", "%-0E",
+                "%0E", "%-E", "%-0g", "%0g", "%-g", "%-0G", "%0G", "%-G",
+                "%-0f", "%0f", "%-f", "%-0a", "%0a", "%-a", "%-0A", "%0A",
+                "%-A" };
+        for (int i = 0; i < missingFormatWidths.length; i++) {
+            try {
+                f = new Formatter(Locale.KOREA);
+                f.format(missingFormatWidths[i], 1f);
+                fail("should throw MissingFormatWidthException");
+            } catch (MissingFormatWidthException e) {
+                // expected
+            }
+
+            try {
+                f = new Formatter(Locale.KOREA);
+                f.format(missingFormatWidths[i], (Float) null);
+                fail("should throw MissingFormatWidthException");
+            } catch (MissingFormatWidthException e) {
+                // expected
+            }
+        }
+
+        final String[] illFlags = { "%+ e", "%+ E", "%+ g", "%+ G", "%+ f",
+                "%+ a", "%+ A", "%-03e", "%-03E", "%-03g", "%-03G", "%-03f",
+                "%-03a", "%-03A" };
+        for (int i = 0; i < illFlags.length; i++) {
+            try {
+                f = new Formatter(Locale.CANADA);
+                f.format(illFlags[i], 1.23d);
+                fail("should throw IllegalFormatFlagsException");
+            } catch (IllegalFormatFlagsException e) {
+                // expected
+            }
+
+            try {
+                f = new Formatter(Locale.CANADA);
+                f.format(illFlags[i], (Double) null);
+                fail("should throw IllegalFormatFlagsException");
+            } catch (IllegalFormatFlagsException e) {
+                // expected
+            }
+        }
+
+        f = new Formatter(Locale.US);
+        try {
+            f.format("%F", 1);
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for
+     *        Float/Double/BigDecimal exception throwing order
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalExceptionOrder() {
+        Formatter f = null;
+
+        /*
+         * Summary: UnknownFormatConversionException >
+         * MissingFormatWidthException > IllegalFormatFlagsException >
+         * FormatFlagsConversionMismatchException >
+         * IllegalFormatConversionException
+         * 
+         */
+        try {
+            // compare FormatFlagsConversionMismatchException and
+            // IllegalFormatConversionException
+            f = new Formatter(Locale.US);
+            f.format("%,e", (byte) 1);
+            fail("should throw FormatFlagsConversionMismatchException");
+        } catch (FormatFlagsConversionMismatchException e) {
+            // expected
+        }
+
+        try {
+            // compare IllegalFormatFlagsException and
+            // FormatFlagsConversionMismatchException
+            f = new Formatter(Locale.US);
+            f.format("%+ ,e", 1f);
+            fail("should throw IllegalFormatFlagsException");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+
+        try {
+            // compare MissingFormatWidthException and
+            // IllegalFormatFlagsException
+            f = new Formatter(Locale.US);
+            f.format("%+ -e", 1f);
+            fail("should throw MissingFormatWidthException");
+        } catch (MissingFormatWidthException e) {
+            // expected
+        }
+
+        try {
+            // compare UnknownFormatConversionException and
+            // MissingFormatWidthException
+            f = new Formatter(Locale.US);
+            f.format("%-F", 1f);
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for BigDecimal
+     *        exception throwing order
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalExceptionOrder() {
+        Formatter f = null;
+        BigDecimal bd = new BigDecimal("1.0");
+
+        /*
+         * Summary: UnknownFormatConversionException >
+         * MissingFormatWidthException > IllegalFormatFlagsException >
+         * FormatFlagsConversionMismatchException >
+         * IllegalFormatConversionException
+         * 
+         */
+        try {
+            // compare FormatFlagsConversionMismatchException and
+            // IllegalFormatConversionException
+            f = new Formatter(Locale.US);
+            f.format("%,e", (byte) 1);
+            fail("should throw FormatFlagsConversionMismatchException");
+        } catch (FormatFlagsConversionMismatchException e) {
+            // expected
+        }
+
+        try {
+            // compare IllegalFormatFlagsException and
+            // FormatFlagsConversionMismatchException
+            f = new Formatter(Locale.US);
+            f.format("%+ ,e", bd);
+            fail("should throw IllegalFormatFlagsException");
+        } catch (IllegalFormatFlagsException e) {
+            // expected
+        }
+
+        try {
+            // compare MissingFormatWidthException and
+            // IllegalFormatFlagsException
+            f = new Formatter(Locale.US);
+            f.format("%+ -e", bd);
+            fail("should throw MissingFormatWidthException");
+        } catch (MissingFormatWidthException e) {
+            // expected
+        }
+
+        // compare UnknownFormatConversionException and
+        // MissingFormatWidthException
+        try {
+            f = new Formatter(Locale.US);
+            f.format("%-F", bd);
+            fail("should throw UnknownFormatConversionException");
+        } catch (UnknownFormatConversionException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Formatter#format(String, Object...) for null argment for
+     *        Float/Double/BigDecimal conversion
+     */
+    public void test_formatLjava_lang_String$Ljava_lang_Object_FloatDoubleBigDecimalNullConversion() {
+        Formatter f = null;
+
+        // test (Float)null
+        f = new Formatter(Locale.FRANCE);
+        f.format("%#- (9.0e", (Float) null);
+        assertEquals("         ", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%-+(1.6E", (Float) null);
+        assertEquals("NULL", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("%+0(,8.4g", (Float) null);
+        assertEquals("    null", f.toString());
+
+        f = new Formatter(Locale.FRANCE);
+        f.format("%- (9.8G", (Float) null);
+        assertEquals("NULL     ", f.toString());
+
+        f = new Formatter(Locale.FRANCE);
+        f.format("%- (12.1f", (Float) null);
+        assertEquals("n           ", f.toString());
+
+        f = new Formatter(Locale.FRANCE);
+        f.format("% .4a", (Float) null);
+        assertEquals("null", f.toString());
+
+        f = new Formatter(Locale.FRANCE);
+        f.format("%06A", (Float) null);
+        assertEquals("  NULL", f.toString());
+
+        // test (Double)null
+        f = new Formatter(Locale.GERMAN);
+        f.format("%- (9e", (Double) null);
+        assertEquals("null     ", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%#-+(1.6E", (Double) null);
+        assertEquals("NULL", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%+0(6.4g", (Double) null);
+        assertEquals("  null", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%- (,5.8G", (Double) null);
+        assertEquals("NULL ", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("% (.4f", (Double) null);
+        assertEquals("null", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("%#.6a", (Double) null);
+        assertEquals("null", f.toString());
+
+        f = new Formatter(Locale.GERMAN);
+        f.format("% 2.5A", (Double) null);
+        assertEquals("NULL", f.toString());
+
+        // test (BigDecimal)null
+        f = new Formatter(Locale.UK);
+        f.format("%#- (6.2e", (BigDecimal) null);
+        assertEquals("nu    ", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("%-+(1.6E", (BigDecimal) null);
+        assertEquals("NULL", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("%+-(,5.3g", (BigDecimal) null);
+        assertEquals("nul  ", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("%0 3G", (BigDecimal) null);
+        assertEquals("NULL", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("%0 (9.0G", (BigDecimal) null);
+        assertEquals("         ", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("% (.5f", (BigDecimal) null);
+        assertEquals("null", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("%06a", (BigDecimal) null);
+        assertEquals("  null", f.toString());
+
+        f = new Formatter(Locale.UK);
+        f.format("% .5A", (BigDecimal) null);
+        assertEquals("NULL", f.toString());
+    }
+    
     /**
      * @tests java.util.Formatter.BigDecimalLayoutForm#values()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "values",
-        args = {}
-    )
     public void test_values() {
         BigDecimalLayoutForm[] vals = BigDecimalLayoutForm.values();
         assertEquals("Invalid length of enum values", 2, vals.length);
-        assertEquals("Wrong scientific value in enum", 
-                                      BigDecimalLayoutForm.SCIENTIFIC, vals[0]);
-        assertEquals("Wrong dec float value in enum", 
-                                   BigDecimalLayoutForm.DECIMAL_FLOAT, vals[1]);
+        assertEquals("Wrong scientific value in enum", BigDecimalLayoutForm.SCIENTIFIC, vals[0]);
+        assertEquals("Wrong dec float value in enum", BigDecimalLayoutForm.DECIMAL_FLOAT, vals[1]);
     }
     
     /**
      * @tests java.util.Formatter.BigDecimalLayoutForm#valueOf(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {java.lang.String.class}
-    )
     public void test_valueOfLjava_lang_String() {
         BigDecimalLayoutForm sci = BigDecimalLayoutForm.valueOf("SCIENTIFIC");
         assertEquals("Wrong scientific value in enum", BigDecimalLayoutForm.SCIENTIFIC, sci);
 
         BigDecimalLayoutForm decFloat = BigDecimalLayoutForm.valueOf("DECIMAL_FLOAT");
         assertEquals("Wrong dec float value from valueOf ", BigDecimalLayoutForm.DECIMAL_FLOAT, decFloat);
+    }
+    
+    /*
+     * Regression test for Harmony-5845
+     * test the short name for timezone whether uses DaylightTime or not
+     */
+    public void test_DaylightTime() {
+        Calendar c1 = new GregorianCalendar(2007, 0, 1);
+        Calendar c2 = new GregorianCalendar(2007, 7, 1);
 
-        try {
-            decFloat = BigDecimalLayoutForm.valueOf("Wrong format");
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException e) {
-            //expected
+        for (String tz : TimeZone.getAvailableIDs()) {
+            if (tz.equals("America/Los_Angeles")) {
+                c1.setTimeZone(TimeZone.getTimeZone(tz));
+                c2.setTimeZone(TimeZone.getTimeZone(tz));
+                assertTrue(String.format("%1$tZ%2$tZ", c1, c2).equals("PSTPDT"));
+            }
+            if (tz.equals("America/Panama")) {
+                c1.setTimeZone(TimeZone.getTimeZone(tz));
+                c2.setTimeZone(TimeZone.getTimeZone(tz));
+                assertTrue(String.format("%1$tZ%2$tZ", c1, c2).equals("ESTEST"));
+            }
         }
     }
+    
+    /*
+     * Regression test for Harmony-5845
+     * test scientific notation to follow RI's behavior
+     */
+    public void test_ScientificNotation() {
+        Formatter f = new Formatter();
+        MathContext mc = new MathContext(30);
+        BigDecimal value = new BigDecimal(0.1, mc);
+        f.format("%.30G", value);
+
+        String result = f.toString();
+        String expected = "0.100000000000000005551115123126";
+        assertEquals(expected, result);
+    }
+
+    
+    /**
+     * Setup resource files for testing
+     */
+    protected void setUp() throws IOException {
+        root = System.getProperty("user.name").equalsIgnoreCase("root");
+        notExist = File.createTempFile("notexist", null);
+        notExist.delete();
+
+        fileWithContent = File.createTempFile("filewithcontent", null);
+        BufferedOutputStream bw = new BufferedOutputStream(
+                new FileOutputStream(fileWithContent));
+        bw.write(1);// write something into the file
+        bw.close();
+
+        readOnly = File.createTempFile("readonly", null);
+        readOnly.setReadOnly();
+
+        secret = File.createTempFile("secret", null);
+        
+        defaultTimeZone = TimeZone.getDefault();
+        TimeZone cst = TimeZone.getTimeZone("Asia/Shanghai");
+        TimeZone.setDefault(cst);
+    }
+
+    /**
+     * Delete the resource files if they exist
+     */
+    protected void tearDown() {
+        if (notExist.exists()) {
+            notExist.delete();
+        }
+
+        if (fileWithContent.exists()) {
+            fileWithContent.delete();
+        }
+        if (readOnly.exists()) {
+            readOnly.delete();
+        }
+        if (secret.exists()) {
+            secret.delete();
+        }
+        
+        TimeZone.setDefault(defaultTimeZone);
+    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/HashMapTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/HashMapTest.java
index 56ba684..39f7216 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/HashMapTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/HashMapTest.java
@@ -1,35 +1,741 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
 
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(HashMap.class) 
-public class HashMapTest extends TestCase {
+import tests.support.Support_MapTest2;
+import tests.support.Support_UnmodifiableCollectionTest;
+
+public class HashMapTest extends junit.framework.TestCase {
+    class MockMap extends AbstractMap {
+        public Set entrySet() {
+            return null;
+        }
+        public int size(){
+            return 0;
+        }
+    }
+    
+    private static class MockMapNull extends AbstractMap {
+        public Set entrySet() {
+            return null;
+        }
+
+        public int size() {
+            return 10;
+        }
+    }
+    
+    interface MockInterface {
+        public String mockMethod();
+    }
+
+    class MockClass implements MockInterface {
+        public String mockMethod() {
+            return "This is a MockClass";
+        }
+    }
+
+    class MockHandler implements InvocationHandler {
+
+        Object obj;
+
+        public MockHandler(Object o) {
+            obj = o;
+        }
+
+        public Object invoke(Object proxy, Method m, Object[] args)
+                throws Throwable {
+
+            Object result = null;
+
+            try {
+
+                result = m.invoke(obj, args);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+
+            }
+            return result;
+        }
+
+    }
+
+
+	HashMap hm;
+
+	final static int hmSize = 1000;
+
+	static Object[] objArray;
+
+	static Object[] objArray2;
+	{
+		objArray = new Object[hmSize];
+		objArray2 = new Object[hmSize];
+		for (int i = 0; i < objArray.length; i++) {
+			objArray[i] = new Integer(i);
+			objArray2[i] = objArray[i].toString();
+		}
+	}
+
+	/**
+	 * @tests java.util.HashMap#HashMap()
+	 */
+	public void test_Constructor() {
+		// Test for method java.util.HashMap()
+		new Support_MapTest2(new HashMap()).runTest();
+
+		HashMap hm2 = new HashMap();
+		assertEquals("Created incorrect HashMap", 0, hm2.size());
+	}
+
+	/**
+	 * @tests java.util.HashMap#HashMap(int)
+	 */
+	public void test_ConstructorI() {
+		// Test for method java.util.HashMap(int)
+		HashMap hm2 = new HashMap(5);
+		assertEquals("Created incorrect HashMap", 0, hm2.size());
+		try {
+			new HashMap(-1);
+		} catch (IllegalArgumentException e) {
+			return;
+		}
+		fail(
+				"Failed to throw IllegalArgumentException for initial capacity < 0");
+
+		HashMap empty = new HashMap(0);
+		assertNull("Empty hashmap access", empty.get("nothing"));
+		empty.put("something", "here");
+		assertTrue("cannot get element", empty.get("something") == "here");
+	}
+
+	/**
+	 * @tests java.util.HashMap#HashMap(int, float)
+	 */
+	public void test_ConstructorIF() {
+		// Test for method java.util.HashMap(int, float)
+		HashMap hm2 = new HashMap(5, (float) 0.5);
+		assertEquals("Created incorrect HashMap", 0, hm2.size());
+		try {
+			new HashMap(0, 0);
+		} catch (IllegalArgumentException e) {
+			return;
+		}
+		fail(
+				"Failed to throw IllegalArgumentException for initial load factor <= 0");
+
+		HashMap empty = new HashMap(0, 0.75f);
+		assertNull("Empty hashtable access", empty.get("nothing"));
+		empty.put("something", "here");
+		assertTrue("cannot get element", empty.get("something") == "here");
+	}
+
+	/**
+	 * @tests java.util.HashMap#HashMap(java.util.Map)
+	 */
+	public void test_ConstructorLjava_util_Map() {
+		// Test for method java.util.HashMap(java.util.Map)
+		Map myMap = new TreeMap();
+		for (int counter = 0; counter < hmSize; counter++)
+			myMap.put(objArray2[counter], objArray[counter]);
+		HashMap hm2 = new HashMap(myMap);
+		for (int counter = 0; counter < hmSize; counter++)
+			assertTrue("Failed to construct correct HashMap", hm
+					.get(objArray2[counter]) == hm2.get(objArray2[counter]));
+        
+        try {
+            Map mockMap = new MockMap();
+            hm = new HashMap(mockMap);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            //empty
+        }
+        
+        HashMap map = new HashMap();
+        map.put("a", "a");
+        SubMap map2 = new SubMap(map); 
+        assertTrue(map2.containsKey("a"));
+        assertTrue(map2.containsValue("a"));
+	}
+
+	/**
+	 * @tests java.util.HashMap#clear()
+	 */
+	public void test_clear() {
+		hm.clear();
+		assertEquals("Clear failed to reset size", 0, hm.size());
+		for (int i = 0; i < hmSize; i++)
+			assertNull("Failed to clear all elements",
+					hm.get(objArray2[i]));
+        
+		// Check clear on a large loaded map of Integer keys
+		HashMap<Integer, String> map = new HashMap<Integer, String>();
+        for (int i = -32767; i < 32768; i++) {
+            map.put(i, "foobar");
+        }
+        map.clear();
+        assertEquals("Failed to reset size on large integer map", 0, hm.size());
+        for (int i = -32767; i < 32768; i++) {
+            assertNull("Failed to clear integer map values", map.get(i));
+        }
+	}
+
+	/**
+	 * @tests java.util.HashMap#clone()
+	 */
+	public void test_clone() {
+		// Test for method java.lang.Object java.util.HashMap.clone()
+		HashMap hm2 = (HashMap) hm.clone();
+		assertTrue("Clone answered equivalent HashMap", hm2 != hm);
+		for (int counter = 0; counter < hmSize; counter++)
+			assertTrue("Clone answered unequal HashMap", hm
+					.get(objArray2[counter]) == hm2.get(objArray2[counter]));
+
+		HashMap map = new HashMap();
+		map.put("key", "value");
+		// get the keySet() and values() on the original Map
+		Set keys = map.keySet();
+		Collection values = map.values();
+		assertEquals("values() does not work", 
+				"value", values.iterator().next());
+		assertEquals("keySet() does not work", 
+				"key", keys.iterator().next());
+		AbstractMap map2 = (AbstractMap) map.clone();
+		map2.put("key", "value2");
+		Collection values2 = map2.values();
+		assertTrue("values() is identical", values2 != values);
+		// values() and keySet() on the cloned() map should be different
+		assertEquals("values() was not cloned", 
+				"value2", values2.iterator().next());
+		map2.clear();
+		map2.put("key2", "value3");
+		Set key2 = map2.keySet();
+		assertTrue("keySet() is identical", key2 != keys);
+		assertEquals("keySet() was not cloned", 
+				"key2", key2.iterator().next());
+        
+        // regresion test for HARMONY-4603
+        HashMap hashmap = new HashMap();
+        MockClonable mock = new MockClonable(1);
+        hashmap.put(1, mock);
+        assertEquals(1, ((MockClonable) hashmap.get(1)).i);
+        HashMap hm3 = (HashMap)hashmap.clone();
+        assertEquals(1, ((MockClonable) hm3.get(1)).i);
+        mock.i = 0;
+        assertEquals(0, ((MockClonable) hashmap.get(1)).i);
+        assertEquals(0, ((MockClonable) hm3.get(1)).i);
+	}
+
+	/**
+	 * @tests java.util.HashMap#containsKey(java.lang.Object)
+	 */
+	public void test_containsKeyLjava_lang_Object() {
+		// Test for method boolean
+		// java.util.HashMap.containsKey(java.lang.Object)
+		assertTrue("Returned false for valid key", hm.containsKey(new Integer(
+				876).toString()));
+		assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD"));
+
+		HashMap m = new HashMap();
+		m.put(null, "test");
+		assertTrue("Failed with null key", m.containsKey(null));
+		assertTrue("Failed with missing key matching null hash", !m
+				.containsKey(new Integer(0)));
+	}
+
+	/**
+	 * @tests java.util.HashMap#containsValue(java.lang.Object)
+	 */
+	public void test_containsValueLjava_lang_Object() {
+		// Test for method boolean
+		// java.util.HashMap.containsValue(java.lang.Object)
+		assertTrue("Returned false for valid value", hm
+				.containsValue(new Integer(875)));
+		assertTrue("Returned true for invalid valie", !hm
+				.containsValue(new Integer(-9)));
+	}
+
+	/**
+	 * @tests java.util.HashMap#entrySet()
+	 */
+	public void test_entrySet() {
+		// Test for method java.util.Set java.util.HashMap.entrySet()
+		Set s = hm.entrySet();
+		Iterator i = s.iterator();
+		assertTrue("Returned set of incorrect size", hm.size() == s.size());
+		while (i.hasNext()) {
+			Map.Entry m = (Map.Entry) i.next();
+			assertTrue("Returned incorrect entry set", hm.containsKey(m
+					.getKey())
+					&& hm.containsValue(m.getValue()));
+		}
+        
+        Iterator iter = s.iterator(); 
+        s.remove(iter.next());
+        assertEquals(1001, s.size());
+	}
+
+	/**
+	 * @tests java.util.HashMap#get(java.lang.Object)
+	 */
+	public void test_getLjava_lang_Object() {
+		// Test for method java.lang.Object
+		// java.util.HashMap.get(java.lang.Object)
+		assertNull("Get returned non-null for non existent key",
+				hm.get("T"));
+		hm.put("T", "HELLO");
+		assertEquals("Get returned incorrect value for existing key", "HELLO", hm.get("T")
+				);
+
+		HashMap m = new HashMap();
+		m.put(null, "test");
+		assertEquals("Failed with null key", "test", m.get(null));
+		assertNull("Failed with missing key matching null hash", m
+				.get(new Integer(0)));
+		
+		// Regression for HARMONY-206
+		ReusableKey k = new ReusableKey();
+		HashMap map = new HashMap();
+		k.setKey(1);
+		map.put(k, "value1");
+
+		k.setKey(18);
+		assertNull(map.get(k));
+
+		k.setKey(17);
+		assertNull(map.get(k));
+	}
+	
+	/**
+	 * Tests for proxy object keys and values
+	 */
+	public void test_proxies() {
+        // Regression for HARMONY-6237
+        MockInterface proxyKey = (MockInterface) Proxy.newProxyInstance(
+                MockInterface.class.getClassLoader(),
+                new Class[] { MockInterface.class }, new MockHandler(
+                        new MockClass()));
+        MockInterface proxyValue = (MockInterface) Proxy.newProxyInstance(
+                MockInterface.class.getClassLoader(),
+                new Class[] { MockInterface.class }, new MockHandler(
+                        new MockClass()));
+
+        // Proxy key
+        Object val = new Object();
+        hm.put(proxyKey, val);
+
+        assertEquals("Failed with proxy object key", val, hm
+                .get(proxyKey));
+        assertTrue("Failed to find proxy key", hm.containsKey(proxyKey));
+        assertEquals("Failed to remove proxy object key", val,
+                hm.remove(proxyKey));
+        assertFalse("Should not have found proxy key", hm.containsKey(proxyKey));
+        
+        // Proxy value
+        Object k = new Object();
+        hm.put(k, proxyValue);
+        
+        assertTrue("Failed to find proxy object as value", hm.containsValue(proxyValue));
+        
+        // Proxy key and value
+        HashMap map = new HashMap();
+        map.put(proxyKey, proxyValue);
+        assertTrue("Failed to find proxy key", map.containsKey(proxyKey));
+        assertEquals(1, map.size());
+        Object[] entries = map.entrySet().toArray();
+        Map.Entry entry = (Map.Entry)entries[0];
+        assertTrue("Failed to find proxy association", map.entrySet().contains(entry));
+	}
+
+	/**
+	 * @tests java.util.HashMap#isEmpty()
+	 */
+	public void test_isEmpty() {
+		// Test for method boolean java.util.HashMap.isEmpty()
+		assertTrue("Returned false for new map", new HashMap().isEmpty());
+		assertTrue("Returned true for non-empty", !hm.isEmpty());
+	}
+
+	/**
+	 * @tests java.util.HashMap#keySet()
+	 */
+	public void test_keySet() {
+		// Test for method java.util.Set java.util.HashMap.keySet()
+		Set s = hm.keySet();
+		assertTrue("Returned set of incorrect size()", s.size() == hm.size());
+		for (int i = 0; i < objArray.length; i++)
+			assertTrue("Returned set does not contain all keys", s
+					.contains(objArray[i].toString()));
+
+		HashMap m = new HashMap();
+		m.put(null, "test");
+		assertTrue("Failed with null key", m.keySet().contains(null));
+		assertNull("Failed with null key", m.keySet().iterator().next());
+
+		Map map = new HashMap(101);
+		map.put(new Integer(1), "1");
+		map.put(new Integer(102), "102");
+		map.put(new Integer(203), "203");
+		Iterator it = map.keySet().iterator();
+		Integer remove1 = (Integer) it.next();
+		it.hasNext();
+		it.remove();
+		Integer remove2 = (Integer) it.next();
+		it.remove();
+		ArrayList list = new ArrayList(Arrays.asList(new Integer[] {
+				new Integer(1), new Integer(102), new Integer(203) }));
+		list.remove(remove1);
+		list.remove(remove2);
+		assertTrue("Wrong result", it.next().equals(list.get(0)));
+		assertEquals("Wrong size", 1, map.size());
+		assertTrue("Wrong contents", map.keySet().iterator().next().equals(
+				list.get(0)));
+
+		Map map2 = new HashMap(101);
+		map2.put(new Integer(1), "1");
+		map2.put(new Integer(4), "4");
+		Iterator it2 = map2.keySet().iterator();
+		Integer remove3 = (Integer) it2.next();
+		Integer next;
+		if (remove3.intValue() == 1)
+			next = new Integer(4);
+		else
+			next = new Integer(1);
+		it2.hasNext();
+		it2.remove();
+		assertTrue("Wrong result 2", it2.next().equals(next));
+		assertEquals("Wrong size 2", 1, map2.size());
+		assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(
+				next));
+	}
+
+	/**
+	 * @tests java.util.HashMap#put(java.lang.Object, java.lang.Object)
+	 */
+	public void test_putLjava_lang_ObjectLjava_lang_Object() {
+        hm.put("KEY", "VALUE");
+        assertEquals("Failed to install key/value pair", "VALUE", hm.get("KEY"));
+
+        HashMap<Object,Object> m = new HashMap<Object,Object>();
+        m.put(new Short((short) 0), "short");
+        m.put(null, "test");
+        m.put(new Integer(0), "int");
+        assertEquals("Failed adding to bucket containing null", "short", m
+                .get(new Short((short) 0)));
+        assertEquals("Failed adding to bucket containing null2", "int", m
+                .get(new Integer(0)));
+        
+        // Check my actual key instance is returned
+        HashMap<Integer, String> map = new HashMap<Integer, String>();
+        for (int i = -32767; i < 32768; i++) {
+            map.put(i, "foobar");
+        }
+        Integer myKey = new Integer(0);
+        // Put a new value at the old key position
+        map.put(myKey, "myValue");
+        assertTrue(map.containsKey(myKey));
+        assertEquals("myValue", map.get(myKey));
+        boolean found = false;
+        for (Iterator<Integer> itr = map.keySet().iterator(); itr.hasNext();) {
+            Integer key = itr.next();
+            if (found = key == myKey) {
+                break;
+            }
+        }
+        assertFalse("Should not find new key instance in hashmap", found);
+
+        // Add a new key instance and check it is returned
+        assertNotNull(map.remove(myKey));
+        map.put(myKey, "myValue");
+        assertTrue(map.containsKey(myKey));
+        assertEquals("myValue", map.get(myKey));
+        for (Iterator<Integer> itr = map.keySet().iterator(); itr.hasNext();) {
+            Integer key = itr.next();
+            if (found = key == myKey) {
+                break;
+            }
+        }
+        assertTrue("Did not find new key instance in hashmap", found);
+
+        // Ensure keys with identical hashcode are stored separately
+        HashMap<Object,Object> objmap = new HashMap<Object, Object>();
+        for (int i = 0; i < 32768; i++) {
+            objmap.put(i, "foobar");
+        }
+        // Put non-equal object with same hashcode
+        MyKey aKey = new MyKey();
+        assertNull(objmap.put(aKey, "value"));
+        assertNull(objmap.remove(new MyKey()));
+        assertEquals("foobar", objmap.get(0));
+        assertEquals("value", objmap.get(aKey));
+    }
+	
+    static class MyKey {
+        public MyKey() {
+            super();
+        }
+        
+        public int hashCode() {
+            return 0;
+        }
+    }
+	/**
+	 * @tests java.util.HashMap#putAll(java.util.Map)
+	 */
+	public void test_putAllLjava_util_Map() {
+		// Test for method void java.util.HashMap.putAll(java.util.Map)
+		HashMap hm2 = new HashMap();
+		hm2.putAll(hm);
+		for (int i = 0; i < 1000; i++)
+			assertTrue("Failed to clear all elements", hm2.get(
+					new Integer(i).toString()).equals((new Integer(i))));
+        
+        Map mockMap = new MockMap();
+        hm2 = new HashMap();
+        hm2.putAll(mockMap);
+        assertEquals("Size should be 0", 0, hm2.size());
+	}
+    
+    /**
+     * @tests java.util.HashMap#putAll(java.util.Map)
+     */
+    public void test_putAllLjava_util_Map_Null() {
+        HashMap hashMap = new HashMap();
+        try {
+            hashMap.putAll(new MockMapNull());
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected.
+        }
+
+        try {
+            hashMap = new HashMap(new MockMapNull());
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected.
+        }
+    } 
+
+	/**
+	 * @tests java.util.HashMap#remove(java.lang.Object)
+	 */
+	public void test_removeLjava_lang_Object() {
+		int size = hm.size();
+		Integer y = new Integer(9);
+		Integer x = ((Integer) hm.remove(y.toString()));
+		assertTrue("Remove returned incorrect value", x.equals(new Integer(9)));
+		assertNull("Failed to remove given key", hm.get(new Integer(9)));
+		assertTrue("Failed to decrement size", hm.size() == (size - 1));
+		assertNull("Remove of non-existent key returned non-null", hm
+				.remove("LCLCLC"));
+
+		HashMap m = new HashMap();
+		m.put(null, "test");
+		assertNull("Failed with same hash as null",
+				m.remove(new Integer(0)));
+		assertEquals("Failed with null key", "test", m.remove(null));
+		
+		HashMap<Integer, Object> map = new HashMap<Integer, Object>();
+        for (int i = 0; i < 32768; i++) {
+            map.put(i, "const");
+        }
+        Object[] values = new Object[32768];
+        for (int i = 0; i < 32768; i++) {
+            values[i] = new Object();
+            map.put(i, values[i]);
+        }
+        for (int i = 32767; i >= 0; i--) {
+            assertEquals("Failed to remove same value", values[i], map.remove(i));
+        }
+
+        // Ensure keys with identical hashcode are removed properly
+        map = new HashMap<Integer, Object>();
+        for (int i = -32767; i < 32768; i++) {
+            map.put(i, "foobar");
+        }
+        // Remove non equal object with same hashcode
+        assertNull(map.remove(new MyKey()));
+        assertEquals("foobar", map.get(0));
+        map.remove(0);
+        assertNull(map.get(0));
+	}
+
+	/**
+	 * @tests java.util.HashMap#size()
+	 */
+	public void test_size() {
+		// Test for method int java.util.HashMap.size()
+		assertTrue("Returned incorrect size",
+				hm.size() == (objArray.length + 2));
+	}
+
+	/**
+	 * @tests java.util.HashMap#values()
+	 */
+	public void test_values() {
+		// Test for method java.util.Collection java.util.HashMap.values()
+		Collection c = hm.values();
+		assertTrue("Returned collection of incorrect size()", c.size() == hm
+				.size());
+		for (int i = 0; i < objArray.length; i++)
+			assertTrue("Returned collection does not contain all keys", c
+					.contains(objArray[i]));
+
+		HashMap myHashMap = new HashMap();
+		for (int i = 0; i < 100; i++)
+			myHashMap.put(objArray2[i], objArray[i]);
+		Collection values = myHashMap.values();
+		new Support_UnmodifiableCollectionTest(
+				"Test Returned Collection From HashMap.values()", values)
+				.runTest();
+		values.remove(new Integer(0));
+		assertTrue(
+				"Removing from the values collection should remove from the original map",
+				!myHashMap.containsValue(new Integer(0)));
+
+	}
+    
+    /**
+     * @tests java.util.AbstractMap#toString()
+     */
+    public void test_toString() {
+
+        HashMap m = new HashMap();
+        m.put(m, m);
+        String result = m.toString();
+        assertTrue("should contain self ref", result.indexOf("(this") > -1);
+    }
+    
+	static class ReusableKey {
+		private int key = 0;
+
+		public void setKey(int key) {
+			this.key = key;
+		}
+
+		public int hashCode() {
+			return key;
+		}
+
+		public boolean equals(Object o) {
+			if (o == this) {
+				return true;
+			}
+			if (!(o instanceof ReusableKey)) {
+				return false;
+			}
+			return key == ((ReusableKey) o).key;
+		}
+	}
+    
+	public void test_Map_Entry_hashCode() {
+        //Related to HARMONY-403
+	    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(10);
+	    Integer key = new Integer(1);
+	    Integer val = new Integer(2);
+	    map.put(key, val);
+	    int expected = key.hashCode() ^ val.hashCode();
+	    assertEquals(expected, map.hashCode());
+	    key = new Integer(4);
+	    val = new Integer(8);
+	    map.put(key, val);
+	    expected += key.hashCode() ^ val.hashCode();
+	    assertEquals(expected, map.hashCode());
+	} 
+    
+    class MockClonable implements Cloneable{
+        public int i;
+        
+        public MockClonable(int i) {
+            this.i = i;
+        }
+        
+        @Override
+        protected Object clone() throws CloneNotSupportedException {
+            return new MockClonable(i);
+        }
+    }
+    
+    /*
+     * Regression test for HY-4750
+     */
+    public void test_EntrySet() {
+        HashMap map = new HashMap();
+        map.put(new Integer(1), "ONE");
+
+        Set entrySet = map.entrySet();
+        Iterator e = entrySet.iterator();
+        Object real = e.next();
+        Map.Entry copyEntry = new MockEntry();
+        assertEquals(real, copyEntry);
+        assertTrue(entrySet.contains(copyEntry));
+        
+        entrySet.remove(copyEntry);
+        assertFalse(entrySet.contains(copyEntry));
+        
+        
+    }
+
+    private static class MockEntry implements Map.Entry {
+
+        public Object getKey() {
+            return new Integer(1);
+        }
+
+        public Object getValue() {
+            return "ONE";
+        }
+
+        public Object setValue(Object object) {
+            return null;
+        }
+    }
+	
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		hm = new HashMap();
+		for (int i = 0; i < objArray.length; i++)
+			hm.put(objArray2[i], objArray[i]);
+		hm.put("test", null);
+		hm.put(null, "test");
+	}
+
+
     class SubMap<K, V> extends HashMap<K, V> {
         public SubMap(Map<? extends K, ? extends V> m) {
             super(m);
@@ -41,31 +747,8 @@
     }
 
     /**
-     * @tests java.util.HashMap#HashMap(java.util.Map)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "NullPointerException is not verified.",
-        method = "HashMap",
-        args = {java.util.Map.class}
-    )
-    public void test_ConstructorLjava_util_Map() {
-        HashMap map = new HashMap();
-        map.put("a", "a");
-        SubMap map2 = new SubMap(map); 
-        assertTrue(map2.containsKey("a"));
-        assertTrue(map2.containsValue("a"));
-    }
-
-    /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
         HashMap<String, String> hm = new HashMap<String, String>();
         hm.put("key", "value");
@@ -80,16 +763,11 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
         HashMap<String, String> hm = new HashMap<String, String>();
         hm.put("key", "value");
 
         SerializationTest.verifyGolden(this, hm);
     }
+
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IdentityHashMapTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IdentityHashMapTest.java
index 43bb856..83ef5e0 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IdentityHashMapTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IdentityHashMapTest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashSet;
@@ -34,102 +29,69 @@
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(IdentityHashMap.class) 
 public class IdentityHashMapTest extends junit.framework.TestCase {
 
-    /**
-     * @tests java.util.IdentityHashMap#containsKey(java.lang.Object)
-     * @tests java.util.IdentityHashMap#containsValue(java.lang.Object)
-     * @tests java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
-     * @tests java.util.IdentityHashMap#get(java.lang.Object)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks null as a parameter.",
-            method = "containsKey",
-            args = {java.lang.Object.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks null as a parameter.",
-            method = "containsValue",
-            args = {java.lang.Object.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks null as a parameter.",
-            method = "put",
-            args = {java.lang.Object.class, java.lang.Object.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Checks null as a parameter.",
-            method = "get",
-            args = {java.lang.Object.class}
-        )
-    })
-    public void test_null_Keys_and_Values() {
-        // tests with null keys and values
-        IdentityHashMap map = new IdentityHashMap();
-        Object result;
+	/**
+	 * @tests java.util.IdentityHashMap#containsKey(java.lang.Object)
+	 * @tests java.util.IdentityHashMap#containsValue(java.lang.Object)
+	 * @tests java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
+	 * @tests java.util.IdentityHashMap#get(java.lang.Object)
+	 */
+	public void test_null_Keys_and_Values() {
+		// tests with null keys and values
+		IdentityHashMap map = new IdentityHashMap();
+		Object result;
 
-        // null key and null value
-        result = map.put(null, null);
-        assertTrue("testA can not find null key", map.containsKey(null));
-        assertTrue("testA can not find null value", map.containsValue(null));
-        assertNull("testA can not get null value for null key",
-                map.get(null));
-        assertNull("testA put returned wrong value", result);
+		// null key and null value
+		result = map.put(null, null);
+		assertTrue("testA can not find null key", map.containsKey(null));
+		assertTrue("testA can not find null value", map.containsValue(null));
+		assertNull("testA can not get null value for null key",
+				map.get(null));
+		assertNull("testA put returned wrong value", result);
 
-        // null value
-        String value = "a value";
-        result = map.put(null, value);
-        assertTrue("testB can not find null key", map.containsKey(null));
-        assertTrue("testB can not find a value with null key", map
-                .containsValue(value));
-        assertTrue("testB can not get value for null key",
-                map.get(null) == value);
-        assertNull("testB put returned wrong value", result);
+		// null value
+		String value = "a value";
+		result = map.put(null, value);
+		assertTrue("testB can not find null key", map.containsKey(null));
+		assertTrue("testB can not find a value with null key", map
+				.containsValue(value));
+		assertTrue("testB can not get value for null key",
+				map.get(null) == value);
+		assertNull("testB put returned wrong value", result);
 
-        // a null key
-        String key = "a key";
-        result = map.put(key, null);
-        assertTrue("testC can not find a key with null value", map
-                .containsKey(key));
-        assertTrue("testC can not find null value", map.containsValue(null));
-        assertNull("testC can not get null value for key", map.get(key));
-        assertNull("testC put returned wrong value", result);
+		// a null key
+		String key = "a key";
+		result = map.put(key, null);
+		assertTrue("testC can not find a key with null value", map
+				.containsKey(key));
+		assertTrue("testC can not find null value", map.containsValue(null));
+		assertNull("testC can not get null value for key", map.get(key));
+		assertNull("testC put returned wrong value", result);
 
-        // another null key
-        String anothervalue = "another value";
-        result = map.put(null, anothervalue);
-        assertTrue("testD can not find null key", map.containsKey(null));
-        assertTrue("testD can not find a value with null key", map
-                .containsValue(anothervalue));
-        assertTrue("testD can not get value for null key",
-                map.get(null) == anothervalue);
-        assertTrue("testD put returned wrong value", result == value);
+		// another null key
+		String anothervalue = "another value";
+		result = map.put(null, anothervalue);
+		assertTrue("testD can not find null key", map.containsKey(null));
+		assertTrue("testD can not find a value with null key", map
+				.containsValue(anothervalue));
+		assertTrue("testD can not get value for null key",
+				map.get(null) == anothervalue);
+		assertTrue("testD put returned wrong value", result == value);
 
-        // remove a null key
-        result = map.remove(null);
-        assertTrue("testE remove returned wrong value", result == anothervalue);
-        assertTrue("testE should not find null key", !map.containsKey(null));
-        assertTrue("testE should not find a value with null key", !map
-                .containsValue(anothervalue));
-        assertNull("testE should not get value for null key",
-                map.get(null));
-    }
+		// remove a null key
+		result = map.remove(null);
+		assertTrue("testE remove returned wrong value", result == anothervalue);
+		assertTrue("testE should not find null key", !map.containsKey(null));
+		assertTrue("testE should not find a value with null key", !map
+				.containsValue(anothervalue));
+		assertNull("testE should not get value for null key",
+				map.get(null));
+	}
 
     /**
      * @tests java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks null as a parameter.",
-        method = "put",
-        args = {java.lang.Object.class, java.lang.Object.class}
-    )
     public void test_putLjava_lang_ObjectLjava_lang_Object() {
         IdentityHashMap<Object, Object> map = new IdentityHashMap<Object, Object>();
         
@@ -144,41 +106,29 @@
         assertNull("Assert 1: Failure getting null value", map.get(key));
     }
 
-    /**
-     * @tests java.util.IdentityHashMap#remove(java.lang.Object)
-     * @tests java.util.IdentityHashMap#keySet()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify removed value.",
-        method = "remove",
-        args = {java.lang.Object.class}
-    )
-    public void test_remove() {
-        IdentityHashMap map = new IdentityHashMap();
-        map.put(null, null);
-        map.put("key1", "value1");
-        map.put("key2", "value2");
-        map.remove("key1");
+	/**
+	 * @tests java.util.IdentityHashMap#remove(java.lang.Object)
+	 * @tests java.util.IdentityHashMap#keySet()
+	 */
+	public void test_remove() {
+		IdentityHashMap map = new IdentityHashMap();
+		map.put(null, null);
+		map.put("key1", "value1");
+		map.put("key2", "value2");
+		map.remove("key1");
 
-        assertTrue("Did not remove key1", !map.containsKey("key1"));
-        assertTrue("Did not remove the value for key1", !map
-                .containsValue("value1"));
+		assertTrue("Did not remove key1", !map.containsKey("key1"));
+		assertTrue("Did not remove the value for key1", !map
+				.containsValue("value1"));
 
-        assertTrue("Modified key2", map.get("key2") != null
-                && map.get("key2") == "value2");
-        assertNull("Modified null entry", map.get(null));
-    }
+		assertTrue("Modified key2", map.get("key2") != null
+				&& map.get("key2") == "value2");
+		assertNull("Modified null entry", map.get(null));
+	}
 
     /**
      * @tests java.util.IdentityHashMapTest#remove(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test.",
-        method = "remove",
-        args = {java.lang.Object.class}
-    )
     public void test_removeLjava_lang_Object() {
         // Regression for HARMONY-37
         IdentityHashMap<String, String> hashMap = new IdentityHashMap<String, String>();
@@ -195,288 +145,269 @@
         assertEquals("Assert 3: After removing null element size is incorrect", 0, hashMap.size());
     }
 
-    /**
-     * @tests java.util.IdentityHashMap#entrySet()
-     * @tests java.util.IdentityHashMap#keySet()
-     * @tests java.util.IdentityHashMap#values()
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "keySet",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "entrySet",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "values",
-            args = {}
-        )
-    })
-    public void test_sets() {
-        // tests with null keys and values
-        IdentityHashMap map = new IdentityHashMap();
+	/**
+	 * @tests java.util.IdentityHashMap#entrySet()
+	 * @tests java.util.IdentityHashMap#keySet()
+	 * @tests java.util.IdentityHashMap#values()
+	 */
+	public void test_sets() {
+		// tests with null keys and values
+		IdentityHashMap map = new IdentityHashMap();
 
-        // null key and null value
-        map.put("key", "value");
-        map.put(null, null);
-        map.put("a key", null);
-        map.put("another key", null);
+		// null key and null value
+		map.put("key", "value");
+		map.put(null, null);
+		map.put("a key", null);
+		map.put("another key", null);
 
-        Set keyset = map.keySet();
-        Collection valueset = map.values();
-        Set entries = map.entrySet();
-        Iterator it = entries.iterator();
-        while (it.hasNext()) {
-            Map.Entry entry = (Map.Entry) it.next();
-            assertTrue("EntrySetIterator can not find entry ", entries
-                    .contains(entry));
+		Set keyset = map.keySet();
+		Collection valueset = map.values();
+		Set entries = map.entrySet();
+		Iterator it = entries.iterator();
+		while (it.hasNext()) {
+			Map.Entry entry = (Map.Entry) it.next();
+			assertTrue("EntrySetIterator can not find entry ", entries
+					.contains(entry));
 
-            assertTrue("entry key not found in map", map.containsKey(entry
-                    .getKey()));
-            assertTrue("entry value not found in map", map.containsValue(entry
-                    .getValue()));
+			assertTrue("entry key not found in map", map.containsKey(entry
+					.getKey()));
+			assertTrue("entry value not found in map", map.containsValue(entry
+					.getValue()));
 
-            assertTrue("entry key not found in the keyset", keyset
-                    .contains(entry.getKey()));
-            assertTrue("entry value not found in the valueset", valueset
-                    .contains(entry.getValue()));
-        }
+			assertTrue("entry key not found in the keyset", keyset
+					.contains(entry.getKey()));
+			assertTrue("entry value not found in the valueset", valueset
+					.contains(entry.getValue()));
+		}
+	}
+
+	/**
+	 * @tests java.util.IdentityHashMap#entrySet()
+	 * @tests java.util.IdentityHashMap#remove(java.lang.Object)
+	 */
+	public void test_entrySet_removeAll() {
+		IdentityHashMap map = new IdentityHashMap();
+		for (int i = 0; i < 1000; i++) {
+			map.put(new Integer(i), new Integer(i));
+		}
+		Set set = map.entrySet();
+
+		set.removeAll(set);
+		assertEquals("did not remove all elements in the map", 0, map.size());
+		assertTrue("did not remove all elements in the entryset", set.isEmpty());
+
+		Iterator it = set.iterator();
+		assertTrue("entrySet iterator still has elements", !it.hasNext());
+	}
+
+	/**
+	 * @tests java.util.IdentityHashMap#keySet()
+	 * @tests java.util.IdentityHashMap#clear()
+	 */
+	public void test_keySet_clear() {
+		IdentityHashMap map = new IdentityHashMap();
+		for (int i = 0; i < 1000; i++) {
+			map.put(new Integer(i), new Integer(i));
+		}
+		Set set = map.keySet();
+		set.clear();
+
+		assertEquals("did not remove all elements in the map", 0, map.size());
+		assertTrue("did not remove all elements in the keyset", set.isEmpty());
+
+		Iterator it = set.iterator();
+		assertTrue("keySet iterator still has elements", !it.hasNext());
+	}
+
+	/**
+	 * @tests java.util.IdentityHashMap#values()
+	 */
+	public void test_values() {
+
+		IdentityHashMap map = new IdentityHashMap();
+		for (int i = 0; i < 10; i++) {
+			map.put(new Integer(i), new Integer(i));
+		}
+
+		Integer key = new Integer(20);
+		Integer value = new Integer(40);
+		map.put(key, value);
+
+		Collection vals = map.values();
+		boolean result = vals.remove(key);
+		assertTrue("removed entries incorrectly", map.size() == 11 && !result);
+		assertTrue("removed key incorrectly", map.containsKey(key));
+		assertTrue("removed value incorrectly", map.containsValue(value));
+
+		result = vals.remove(value);
+		assertTrue("Did not remove entry as expected", map.size() == 10
+				&& result);
+		assertTrue("Did not remove key as expected", !map.containsKey(key));
+		assertTrue("Did not remove value as expected", !map
+				.containsValue(value));
+
+		// put an equivalent key to a value
+		key = new Integer(1);
+		value = new Integer(100);
+		map.put(key, value);
+
+		result = vals.remove(key);
+		assertTrue("TestB. removed entries incorrectly", map.size() == 11
+				&& !result);
+		assertTrue("TestB. removed key incorrectly", map.containsKey(key));
+		assertTrue("TestB. removed value incorrectly", map.containsValue(value));
+
+		result = vals.remove(value);
+		assertTrue("TestB. Did not remove entry as expected", map.size() == 10
+				&& result);
+		assertTrue("TestB. Did not remove key as expected", !map
+				.containsKey(key));
+		assertTrue("TestB. Did not remove value as expected", !map
+				.containsValue(value));
+
+		vals.clear();
+		assertEquals("Did not remove all entries as expected", 0, map.size());
+	}
+
+	/**
+	 * @tests java.util.IdentityHashMap#keySet()
+	 * @tests java.util.IdentityHashMap#remove(java.lang.Object)
+	 */
+	public void test_keySet_removeAll() {
+		IdentityHashMap map = new IdentityHashMap();
+		for (int i = 0; i < 1000; i++) {
+			map.put(new Integer(i), new Integer(i));
+		}
+		Set set = map.keySet();
+		set.removeAll(set);
+
+		assertEquals("did not remove all elements in the map", 0, map.size());
+		assertTrue("did not remove all elements in the keyset", set.isEmpty());
+
+		Iterator it = set.iterator();
+		assertTrue("keySet iterator still has elements", !it.hasNext());
+	}
+
+	/**
+	 * @tests java.util.IdentityHashMap#keySet()
+	 */
+	public void test_keySet_retainAll() {
+		IdentityHashMap map = new IdentityHashMap();
+		for (int i = 0; i < 1000; i++) {
+			map.put(new Integer(i), new Integer(i));
+		}
+		Set set = map.keySet();
+
+		// retain all the elements
+		boolean result = set.retainAll(set);
+		assertTrue("retain all should return false", !result);
+		assertEquals("did not retain all", 1000, set.size());
+
+		// send empty set to retainAll
+		result = set.retainAll(new TreeSet());
+		assertTrue("retain all should return true", result);
+		assertEquals("did not remove all elements in the map", 0, map.size());
+		assertTrue("did not remove all elements in the keyset", set.isEmpty());
+
+		Iterator it = set.iterator();
+		assertTrue("keySet iterator still has elements", !it.hasNext());
+	}
+
+	/**
+	 * @tests java.util.IdentityHashMap#keySet()
+	 * @tests java.util.IdentityHashMap#remove(java.lang.Object)
+	 */
+	public void test_keyset_remove() {
+		IdentityHashMap map = new IdentityHashMap();
+
+		Integer key = new Integer(21);
+
+		map.put(new Integer(1), null);
+		map.put(new Integer(11), null);
+		map.put(key, null);
+		map.put(new Integer(31), null);
+		map.put(new Integer(41), null);
+		map.put(new Integer(51), null);
+		map.put(new Integer(61), null);
+		map.put(new Integer(71), null);
+		map.put(new Integer(81), null);
+		map.put(new Integer(91), null);
+
+		Set set = map.keySet();
+
+		Set newset = new HashSet();
+		Iterator it = set.iterator();
+		while (it.hasNext()) {
+			Object element = it.next();
+			if (element == key) {
+				it.remove();
+			} else
+				newset.add(element);
+		}
+		int size = newset.size();
+		assertTrue("keyset and newset don't have same size",
+				newset.size() == size);
+		assertTrue("element is in newset ", !newset.contains(key));
+		assertTrue("element not removed from keyset", !set.contains(key));
+		assertTrue("element not removed from map", !map.containsKey(key));
+
+		assertTrue("newset and keyset do not have same elements 1", newset
+				.equals(set));
+		assertTrue("newset and keyset do not have same elements 2", set
+				.equals(newset));
+	}
+
+    public void test_clone_scenario1() {
+        IdentityHashMap hashMap = new IdentityHashMap();
+        assertEquals(0, hashMap.hashCode());
+        Object cloneHashMap = hashMap.clone();
+        ((IdentityHashMap) cloneHashMap).put("key", "value");
+        assertEquals(0, hashMap.hashCode());
+        assertTrue(0 != cloneHashMap.hashCode());
     }
 
-    /**
-     * @tests java.util.IdentityHashMap#entrySet()
-     * @tests java.util.IdentityHashMap#remove(java.lang.Object)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies positive functionality. Doesn't verify that remove method returns null if there was no entry for key.",
-            method = "entrySet",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "Verifies positive functionality. Doesn't verify that remove method returns null if there was no entry for key.",
-            method = "remove",
-            args = {java.lang.Object.class}
-        )
-    })
-    public void test_entrySet_removeAll() {
-        IdentityHashMap map = new IdentityHashMap();
-        for (int i = 0; i < 1000; i++) {
-            map.put(new Integer(i), new Integer(i));
-        }
-        Set set = map.entrySet();
-
-        set.removeAll(set);
-        assertEquals("did not remove all elements in the map", 0, map.size());
-        assertTrue("did not remove all elements in the entryset", set.isEmpty());
-
-        Iterator it = set.iterator();
-        assertTrue("entrySet iterator still has elements", !it.hasNext());
+    public void test_clone_scenario2() {
+        IdentityHashMap hashMap = new IdentityHashMap();
+        assertEquals(0, hashMap.hashCode());
+        Object cloneHashMap = hashMap.clone();
+        hashMap.put("key", "value");
+        assertEquals(1, hashMap.size());
+        assertEquals(0, ((IdentityHashMap) cloneHashMap).size());
+        assertEquals("value", hashMap.get("key"));
+        assertNull(((IdentityHashMap) cloneHashMap).get("key"));
+        assertTrue(0 != hashMap.hashCode());
+        assertEquals(0, cloneHashMap.hashCode());
     }
 
-    /**
-     * @tests java.util.IdentityHashMap#keySet()
-     * @tests java.util.IdentityHashMap#clear()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "clear",
-        args = {}
-    )
-    public void test_keySet_clear() {
-        IdentityHashMap map = new IdentityHashMap();
-        for (int i = 0; i < 1000; i++) {
-            map.put(new Integer(i), new Integer(i));
-        }
-        Set set = map.keySet();
-        set.clear();
-
-        assertEquals("did not remove all elements in the map", 0, map.size());
-        assertTrue("did not remove all elements in the keyset", set.isEmpty());
-
-        Iterator it = set.iterator();
-        assertTrue("keySet iterator still has elements", !it.hasNext());
+    public void test_clone_scenario3() {
+        IdentityHashMap hashMap = new IdentityHashMap();
+        assertEquals(0, hashMap.hashCode());
+        hashMap.put("key", "value");
+        Object cloneHashMap = hashMap.clone();
+        assertEquals(1, hashMap.size());
+        assertEquals(1, ((IdentityHashMap) cloneHashMap).size());
+        assertEquals("value", hashMap.get("key"));
+        assertEquals("value", ((IdentityHashMap) cloneHashMap).get("key"));
+        assertEquals(hashMap.hashCode(), cloneHashMap.hashCode());
     }
 
-    /**
-     * @tests java.util.IdentityHashMap#values()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "values",
-        args = {}
-    )
-    public void test_values() {
-
-        IdentityHashMap map = new IdentityHashMap();
-        for (int i = 0; i < 10; i++) {
-            map.put(new Integer(i), new Integer(i));
-        }
-
-        Integer key = new Integer(20);
-        Integer value = new Integer(40);
-        map.put(key, value);
-
-        Collection vals = map.values();
-        boolean result = vals.remove(key);
-        assertTrue("removed entries incorrectly", map.size() == 11 && !result);
-        assertTrue("removed key incorrectly", map.containsKey(key));
-        assertTrue("removed value incorrectly", map.containsValue(value));
-
-        result = vals.remove(value);
-        assertTrue("Did not remove entry as expected", map.size() == 10
-                && result);
-        assertTrue("Did not remove key as expected", !map.containsKey(key));
-        assertTrue("Did not remove value as expected", !map
-                .containsValue(value));
-
-        // put an equivalent key to a value
-        key = new Integer(1);
-        value = new Integer(100);
-        map.put(key, value);
-
-        result = vals.remove(key);
-        assertTrue("TestB. removed entries incorrectly", map.size() == 11
-                && !result);
-        assertTrue("TestB. removed key incorrectly", map.containsKey(key));
-        assertTrue("TestB. removed value incorrectly", map.containsValue(value));
-
-        result = vals.remove(value);
-        assertTrue("TestB. Did not remove entry as expected", map.size() == 10
-                && result);
-        assertTrue("TestB. Did not remove key as expected", !map
-                .containsKey(key));
-        assertTrue("TestB. Did not remove value as expected", !map
-                .containsValue(value));
-
-        vals.clear();
-        assertEquals("Did not remove all entries as expected", 0, map.size());
+    public void test_clone_scenario4() {
+        IdentityHashMap hashMap = new IdentityHashMap();
+        Object cloneHashMap = hashMap.clone();
+        assertNull(((IdentityHashMap) cloneHashMap).get((Object) null));
+        hashMap.put((Object) null, cloneHashMap);
+        assertNull(((IdentityHashMap) cloneHashMap).get((Object) null));
+        assertEquals(cloneHashMap, hashMap.get((Object) null));
     }
 
-    /**
-     * @tests java.util.IdentityHashMap#keySet()
-     * @tests java.util.IdentityHashMap#remove(java.lang.Object)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "keySet",
-        args = {}
-    )
-    public void test_keySet_removeAll() {
-        IdentityHashMap map = new IdentityHashMap();
-        for (int i = 0; i < 1000; i++) {
-            map.put(new Integer(i), new Integer(i));
-        }
-        Set set = map.keySet();
-        set.removeAll(set);
-
-        assertEquals("did not remove all elements in the map", 0, map.size());
-        assertTrue("did not remove all elements in the keyset", set.isEmpty());
-
-        Iterator it = set.iterator();
-        assertTrue("keySet iterator still has elements", !it.hasNext());
-    }
-
-    /**
-     * @tests java.util.IdentityHashMap#keySet()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "keySet",
-        args = {}
-    )
-    public void test_keySet_retainAll() {
-        IdentityHashMap map = new IdentityHashMap();
-        for (int i = 0; i < 1000; i++) {
-            map.put(new Integer(i), new Integer(i));
-        }
-        Set set = map.keySet();
-
-        // retain all the elements
-        boolean result = set.retainAll(set);
-        assertTrue("retain all should return false", !result);
-        assertEquals("did not retain all", 1000, set.size());
-
-        // send empty set to retainAll
-        result = set.retainAll(new TreeSet());
-        assertTrue("retain all should return true", result);
-        assertEquals("did not remove all elements in the map", 0, map.size());
-        assertTrue("did not remove all elements in the keyset", set.isEmpty());
-
-        Iterator it = set.iterator();
-        assertTrue("keySet iterator still has elements", !it.hasNext());
-    }
-
-    /**
-     * @tests java.util.IdentityHashMap#keySet()
-     * @tests java.util.IdentityHashMap#remove(java.lang.Object)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "keySet",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "remove",
-            args = {java.lang.Object.class}
-        )
-    })
-    public void test_keyset_remove() {
-        IdentityHashMap map = new IdentityHashMap();
-
-        Integer key = new Integer(21);
-
-        map.put(new Integer(1), null);
-        map.put(new Integer(11), null);
-        map.put(key, null);
-        map.put(new Integer(31), null);
-        map.put(new Integer(41), null);
-        map.put(new Integer(51), null);
-        map.put(new Integer(61), null);
-        map.put(new Integer(71), null);
-        map.put(new Integer(81), null);
-        map.put(new Integer(91), null);
-
-        Set set = map.keySet();
-
-        Set newset = new HashSet();
-        Iterator it = set.iterator();
-        while (it.hasNext()) {
-            Object element = it.next();
-            if (element == key) {
-                it.remove();
-            } else
-                newset.add(element);
-        }
-        int size = newset.size();
-        assertTrue("keyset and newset don't have same size",
-                newset.size() == size);
-        assertTrue("element is in newset ", !newset.contains(key));
-        assertTrue("element not removed from keyset", !set.contains(key));
-        assertTrue("element not removed from map", !map.containsKey(key));
-
-        assertTrue("newset and keyset do not have same elements 1", newset
-                .equals(set));
-        assertTrue("newset and keyset do not have same elements 2", set
-                .equals(newset));
+    public void test_clone_scenario5() throws Exception {
+        IdentityHashMap hashMap = new IdentityHashMap();
+        Object cloneHashMap = hashMap.clone();
+        assertNull(hashMap.remove((Object) null));
+        ((IdentityHashMap) cloneHashMap).put((Object) null, cloneHashMap);
+        assertNull(hashMap.remove((Object) null));
+        assertEquals(cloneHashMap, ((IdentityHashMap) cloneHashMap)
+                .get((Object) null));
     }
 
     // comparator for IdentityHashMap objects
@@ -494,12 +425,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
         IdentityHashMap<String, String> identityHashMap = new IdentityHashMap<String, String>();
         identityHashMap.put("key1", "value1");
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatCodePointExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatCodePointExceptionTest.java
index 602d1db..7ef9715 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatCodePointExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatCodePointExceptionTest.java
@@ -16,31 +16,19 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.IllegalFormatCodePointException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(IllegalFormatCodePointException.class) 
 public class IllegalFormatCodePointExceptionTest extends TestCase {
 
     /**
      * @tests java.util.IllegalFormatCodePointException.IllegalFormatCodePointException(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalFormatCodePointException",
-        args = {int.class}
-    )
     public void test_illegalFormatCodePointException() {
         IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
                 -1);
@@ -50,12 +38,6 @@
     /**
      * @tests java.util.IllegalFormatCodePointException.getCodePoint()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCodePoint",
-        args = {}
-    )
     public void test_getCodePoint() {
         int codePoint = 12345;
         IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
@@ -66,12 +48,6 @@
     /**
      * @tests java.util.IllegalFormatCodePointException.getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         int codePoint = 12345;
         IllegalFormatCodePointException illegalFormatCodePointException = new IllegalFormatCodePointException(
@@ -98,12 +74,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(
@@ -113,12 +83,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatConversionExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatConversionExceptionTest.java
index 22a845d..4d5c37d 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatConversionExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatConversionExceptionTest.java
@@ -16,32 +16,20 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.IllegalFormatConversionException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(IllegalFormatConversionException.class) 
 public class IllegalFormatConversionExceptionTest extends TestCase {
 
     /**
      * @tests java.util.IllegalFormatConversionException#IllegalFormatConversionException(char,
      *        Class)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalFormatConversionException",
-        args = {char.class, java.lang.Class.class}
-    )
     public void test_illegalFormatConversionException() {
         try {
             new IllegalFormatConversionException(' ', null);
@@ -49,19 +37,11 @@
         } catch (NullPointerException e) {
             // desired
         }
-        
-        assertNotNull(new IllegalFormatConversionException(' ', String.class));
     }
 
     /**
      * @tests java.util.IllegalFormatConversionException#getArgumentClass()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getArgumentClass",
-        args = {}
-    )
     public void test_getArgumentClass() {
         char c = '*';
         Class<String> argClass = String.class;
@@ -75,12 +55,6 @@
     /**
      * @tests java.util.IllegalFormatConversionException#getConversion()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getConversion",
-        args = {}
-    )
     public void test_getConversion() {
         char c = '*';
         Class<String> argClass = String.class;
@@ -93,12 +67,6 @@
     /**
      * @tests java.util.IllegalFormatConversionException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         char c = '*';
         Class<String> argClass = String.class;
@@ -129,12 +97,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new IllegalFormatConversionException('*',
@@ -144,12 +106,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatFlagsExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatFlagsExceptionTest.java
index 8ae825c..530f281 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatFlagsExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatFlagsExceptionTest.java
@@ -16,31 +16,19 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.IllegalFormatFlagsException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(IllegalFormatFlagsException.class) 
 public class IllegalFormatFlagsExceptionTest extends TestCase {
 
     /**
      * @tests java.util.IllegalFormatFlagsException#IllegalFormatFlagsException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalFormatFlagsException",
-        args = {java.lang.String.class}
-    )
     public void test_illegalFormatFlagsException() {
         try {
             new IllegalFormatFlagsException(null);
@@ -48,19 +36,11 @@
         } catch (NullPointerException e) {
             // expected
         }
-        
-        assertNotNull(new IllegalFormatFlagsException("String"));
     }
 
     /**
      * @tests java.util.IllegalFormatFlagsException.getFlags()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFlags",
-        args = {}
-    )
     public void test_getFlags() {
         String flags = "TESTFLAGS";
         IllegalFormatFlagsException illegalFormatFlagsException = new IllegalFormatFlagsException(
@@ -71,12 +51,6 @@
     /**
      * @tests java.util.IllegalFormatFlagsException.getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String flags = "TESTFLAGS";
         IllegalFormatFlagsException illegalFormatFlagsException = new IllegalFormatFlagsException(
@@ -103,12 +77,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new IllegalFormatFlagsException(
@@ -118,12 +86,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new IllegalFormatFlagsException(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatPrecisionExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatPrecisionExceptionTest.java
index 823473e..f7c60ea 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatPrecisionExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatPrecisionExceptionTest.java
@@ -15,31 +15,19 @@
  */
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.IllegalFormatPrecisionException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(IllegalFormatPrecisionException.class) 
 public class IllegalFormatPrecisionExceptionTest extends TestCase {
 
     /**
      * @tests java.util.IllegalFormatPrecisionException#IllegalFormatPrecisionException(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalFormatPrecisionException",
-        args = {int.class}
-    )
     public void test_illegalFormatPrecisionException() {
         IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
                 Integer.MIN_VALUE);
@@ -50,12 +38,6 @@
     /**
      * @tests java.util.IllegalFormatPrecisionException#getPrecision()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getPrecision",
-        args = {}
-    )
     public void test_getPrecision() {
         int precision = 12345;
         IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
@@ -66,12 +48,6 @@
     /**
      * @tests method for 'java.util.IllegalFormatPrecisionException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         int precision = 12345;
         IllegalFormatPrecisionException illegalFormatPrecisionException = new IllegalFormatPrecisionException(
@@ -99,12 +75,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(
@@ -114,12 +84,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatWidthExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatWidthExceptionTest.java
index 6885a4e..4262aa0 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatWidthExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/IllegalFormatWidthExceptionTest.java
@@ -15,31 +15,19 @@
  */
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.IllegalFormatWidthException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(IllegalFormatWidthException.class) 
 public class IllegalFormatWidthExceptionTest extends TestCase {
 
     /**
      * @tests java.util.IllegalFormatWidthException#IllegalFormatWidthException(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "IllegalFormatWidthException",
-        args = {int.class}
-    )
     public void test_illegalFormatWidthException() {
         int width = Integer.MAX_VALUE;
         IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
@@ -51,12 +39,6 @@
     /**
      * @tests java.util.IllegalFormatWidthException#getWidth()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getWidth",
-        args = {}
-    )
     public void test_getWidth() {
         int width = 12345;
         IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
@@ -68,12 +50,6 @@
     /**
      * @tests java.util.IllegalFormatWidthException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         int width = 12345;
         IllegalFormatWidthException illegalFormatWidthException = new IllegalFormatWidthException(
@@ -100,12 +76,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new IllegalFormatWidthException(12345),
@@ -115,12 +85,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new IllegalFormatWidthException(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InputMismatchExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InputMismatchExceptionTest.java
index e14987e..60c5dc7 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InputMismatchExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InputMismatchExceptionTest.java
@@ -15,20 +15,14 @@
  */
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.InputMismatchException;
 import java.util.NoSuchElementException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(InputMismatchException.class) 
 public class InputMismatchExceptionTest extends TestCase {
 
     private static final String ERROR_MESSAGE = "for serialization test"; //$NON-NLS-1$
@@ -36,12 +30,6 @@
     /**
      * @tests java.util.InputMismatchException#InputMismatchException()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InputMismatchException",
-        args = {}
-    )
     @SuppressWarnings("cast")
     public void test_Constructor() {
         InputMismatchException exception = new InputMismatchException();
@@ -53,12 +41,6 @@
     /**
      * @tests java.util.InputMismatchException#InputMismatchException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InputMismatchException",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         InputMismatchException exception = new InputMismatchException(
                 ERROR_MESSAGE);
@@ -69,12 +51,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new InputMismatchException(ERROR_MESSAGE));
@@ -83,12 +59,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new InputMismatchException(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InvalidPropertiesFormatExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InvalidPropertiesFormatExceptionTest.java
index 0996a24..63ab11e 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InvalidPropertiesFormatExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/InvalidPropertiesFormatExceptionTest.java
@@ -1,53 +1,50 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
+import java.io.NotSerializableException;
 import java.util.InvalidPropertiesFormatException;
 
-@TestTargetClass(InvalidPropertiesFormatException.class)
-public class InvalidPropertiesFormatExceptionTest extends TestCase {
+import org.apache.harmony.testframework.serialization.SerializationTest;
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InvalidPropertiesFormatException",
-        args = {java.lang.Throwable.class}
-    )
-    public void testInvalidPropertiesFormatExceptionThrowable() {
-        assertNotNull(new InvalidPropertiesFormatException(new Exception()));
-        assertNotNull(new InvalidPropertiesFormatException((Throwable)null));
+public class InvalidPropertiesFormatExceptionTest extends
+        junit.framework.TestCase {
+
+    /**
+     * @tests java.util.InvalidPropertiesFormatException#SerializationTest()
+     */
+    public void test_Serialization() throws Exception {
+        InvalidPropertiesFormatException ipfe = new InvalidPropertiesFormatException(
+                "Hey, this is InvalidPropertiesFormatException");
+        try {
+            SerializationTest.verifySelf(ipfe);
+        } catch (NotSerializableException e) {
+            // expected
+        }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "InvalidPropertiesFormatException",
-        args = {java.lang.String.class}
-    )
-    public void testInvalidPropertiesFormatExceptionString() {
-        assertNotNull(new InvalidPropertiesFormatException("String"));
-        assertNotNull(new InvalidPropertiesFormatException((String)null));
+    /**
+     * @tests {@link java.util.InvalidPropertiesFormatException#InvalidPropertiesFormatException(Throwable)}
+     */
+    public void test_Constructor_Ljava_lang_Throwable() {
+        Throwable throwable = new Throwable();
+        InvalidPropertiesFormatException exception = new InvalidPropertiesFormatException(
+                throwable);
+        assertEquals("the casue did not equals argument passed in constructor",
+                throwable, exception.getCause());
     }
 
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/LocaleTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/LocaleTest.java
index 5acb81c..1abfc49 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/LocaleTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/LocaleTest.java
@@ -1,49 +1,408 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
-@TestTargetClass(Locale.class) 
-public class LocaleTest extends TestCase {
+public class LocaleTest extends junit.framework.TestCase {
 
-    /**
+	Locale testLocale;
+
+	Locale l;
+	
+	Locale defaultLocale;
+
+	/**
+	 * @tests java.util.Locale#Locale(java.lang.String, java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_StringLjava_lang_String() {
+		// Test for method java.util.Locale(java.lang.String, java.lang.String)
+		Locale x = new Locale("xx", "CV");
+		assertTrue("Failed to create Locale", x.getCountry().equals("CV")
+				&& x.getVariant().equals(""));
+	}
+
+	/**
+	 * @tests java.util.Locale#Locale(java.lang.String, java.lang.String,
+	 *        java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_StringLjava_lang_StringLjava_lang_String() {
+		// Test for method java.util.Locale(java.lang.String, java.lang.String,
+		// java.lang.String)
+		Locale x = new Locale("xx", "CV", "ZZ");
+		assertTrue("Failed to create Locale", x.getLanguage().equals("xx")
+				&& (x.getCountry().equals("CV") && x.getVariant().equals("ZZ")));
+                try {
+                   new Locale(null, "CV", "ZZ");
+                   fail("expected NullPointerException with 1st parameter == null");
+                } catch(NullPointerException e) {
+                }
+
+                try {
+                   new Locale("xx", null, "ZZ");
+                   fail("expected NullPointerException with 2nd parameter == null");
+                } catch(NullPointerException e) {
+                }
+
+                try {
+                   new Locale("xx", "CV", null);
+                   fail("expected NullPointerException with 3rd parameter == null");
+                } catch(NullPointerException e) {
+                }
+	}
+
+	/**
+	 * @tests java.util.Locale#clone()
+	 */
+	public void test_clone() {
+		// Test for method java.lang.Object java.util.Locale.clone()
+		assertTrue("Clone failed", l.clone().equals(l));
+	}
+
+	/**
+	 * @tests java.util.Locale#equals(java.lang.Object)
+	 */
+	public void test_equalsLjava_lang_Object() {
+		// Test for method boolean java.util.Locale.equals(java.lang.Object)
+		Locale l2 = new Locale("en", "CA", "WIN32");
+		assertTrue("Same object returned false", testLocale.equals(testLocale));
+		assertTrue("Same values returned false", testLocale.equals(l2));
+		assertTrue("Different locales returned true", !testLocale.equals(l));
+
+	}
+
+	/**
      * @tests java.util.Locale#getAvailableLocales()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAvailableLocales",
-        args = {}
-    )
     public void test_getAvailableLocales() {
+        // Test for method java.util.Locale []
+        // java.util.Locale.getAvailableLocales()
+        // Assumes there will generally be about 100+ available locales...
         Locale[] locales = Locale.getAvailableLocales();
-        // Assumes that there will be a decent number of locales
-        // BEGIN android-changed
-        // this assumption is wrong. Android has a reduced locale repository.
-        // was >100, now it's >10
-        assertTrue("Assert 0: Cannot find locales", locales.length > 10);
-        // END android-changed
+        assertTrue("Wrong number of locales: ", locales.length > 100);
+        // regression test for HARMONY-1514
+        // HashSet can filter duplicate locales
+        Set<Locale> localesSet = new HashSet<Locale>(Arrays.asList(locales));
+        // Non-bug difference for HARMONY-5442
+        assertTrue(localesSet.size() <= locales.length);
     }
+
+	/**
+     * @tests java.util.Locale#getCountry()
+     */
+	public void test_getCountry() {
+		// Test for method java.lang.String java.util.Locale.getCountry()
+		assertTrue("Returned incorrect country: " + testLocale.getCountry(),
+				testLocale.getCountry().equals("CA"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getDefault()
+	 */
+	public void test_getDefault() {
+		// Test for method java.util.Locale java.util.Locale.getDefault()
+		assertTrue("returns copy", Locale.getDefault() == Locale.getDefault());
+		Locale org = Locale.getDefault();
+		Locale.setDefault(l);
+		Locale x = Locale.getDefault();
+		Locale.setDefault(org);
+		assertEquals("Failed to get locale", "fr_CA_WIN32", x.toString());
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayCountry()
+	 */
+	public void test_getDisplayCountry() {
+		// Test for method java.lang.String java.util.Locale.getDisplayCountry()
+		assertTrue("Returned incorrect country: "
+				+ testLocale.getDisplayCountry(), testLocale
+				.getDisplayCountry().equals("Canada"));
+        
+        // Regression for Harmony-1146
+        // Non-bug difference for HARMONY-5442
+        Locale l_countryCD = new Locale("", "CD"); //$NON-NLS-1$ //$NON-NLS-2$
+                assertEquals("Congo - Kinshasa", //$NON-NLS-1$
+                        l_countryCD.getDisplayCountry()); 
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayCountry(java.util.Locale)
+	 */
+	public void test_getDisplayCountryLjava_util_Locale() {
+		// Test for method java.lang.String
+		// java.util.Locale.getDisplayCountry(java.util.Locale)
+		assertEquals("Returned incorrect country", "Italie", Locale.ITALY
+				.getDisplayCountry(l));
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayLanguage()
+	 */
+	public void test_getDisplayLanguage() {
+		// Test for method java.lang.String
+		// java.util.Locale.getDisplayLanguage()
+		assertTrue("Returned incorrect language: "
+				+ testLocale.getDisplayLanguage(), testLocale
+				.getDisplayLanguage().equals("English"));
+        
+		// Regression for Harmony-1146
+        Locale l_languageAE = new Locale("ae", ""); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("Avestan", l_languageAE.getDisplayLanguage()); //$NON-NLS-1$
+        
+        // Regression for HARMONY-4402
+        Locale defaultLocale = Locale.getDefault();
+        try {
+            Locale locale = new Locale("no", "NO");
+            Locale.setDefault(locale);
+            assertEquals("norsk", locale.getDisplayLanguage()); //$NON-NLS-1$
+        } finally {
+            Locale.setDefault(defaultLocale);
+        }
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayLanguage(java.util.Locale)
+	 */
+	public void test_getDisplayLanguageLjava_util_Locale() {
+		// Test for method java.lang.String
+		// java.util.Locale.getDisplayLanguage(java.util.Locale)
+		assertTrue("Returned incorrect language: "
+				+ testLocale.getDisplayLanguage(l), testLocale
+				.getDisplayLanguage(l).equals("anglais"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayName()
+	 */
+	public void test_getDisplayName() {
+		// Test for method java.lang.String java.util.Locale.getDisplayName()
+		assertTrue("Returned incorrect name: " + testLocale.getDisplayName(),
+				testLocale.getDisplayName().equals("English (Canada,WIN32)"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayName(java.util.Locale)
+	 */
+	public void test_getDisplayNameLjava_util_Locale() {
+		// Test for method java.lang.String
+		// java.util.Locale.getDisplayName(java.util.Locale)
+		assertTrue("Returned incorrect name: " + testLocale.getDisplayName(l),
+				testLocale.getDisplayName(l).equals("anglais (Canada,WIN32)"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayVariant()
+	 */
+	public void test_getDisplayVariant() {
+		// Test for method java.lang.String java.util.Locale.getDisplayVariant()
+		assertTrue("Returned incorrect variant: "
+				+ testLocale.getDisplayVariant(), testLocale
+				.getDisplayVariant().equals("WIN32"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getDisplayVariant(java.util.Locale)
+	 */
+	public void test_getDisplayVariantLjava_util_Locale() {
+		// Test for method java.lang.String
+		// java.util.Locale.getDisplayVariant(java.util.Locale)
+		assertTrue("Returned incorrect variant: "
+				+ testLocale.getDisplayVariant(l), testLocale
+				.getDisplayVariant(l).equals("WIN32"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getISO3Country()
+	 */
+	public void test_getISO3Country() {
+		// Test for method java.lang.String java.util.Locale.getISO3Country()
+		assertTrue("Returned incorrect ISO3 country: "
+				+ testLocale.getISO3Country(), testLocale.getISO3Country()
+				.equals("CAN"));
+        
+        Locale l = new Locale("", "CD");
+        assertEquals("COD", l.getISO3Country());
+	}
+
+	/**
+	 * @tests java.util.Locale#getISO3Language()
+	 */
+	public void test_getISO3Language() {
+		// Test for method java.lang.String java.util.Locale.getISO3Language()
+		assertTrue("Returned incorrect ISO3 language: "
+				+ testLocale.getISO3Language(), testLocale.getISO3Language()
+				.equals("eng"));
+        
+        Locale l = new Locale("ae");
+        assertEquals("ave", l.getISO3Language());
+        
+        // Regression for Harmony-1146
+        
+        // Non-bug difference for HARMONY-5442
+        Locale l_CountryCS = new Locale("", "CS"); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("SCG", l_CountryCS.getISO3Country()); //$NON-NLS-1$
+        
+        // Regression for Harmony-1129
+        l = new Locale("ak", ""); //$NON-NLS-1$ //$NON-NLS-2$
+        assertEquals("aka", l.getISO3Language()); //$NON-NLS-1$
+	}
+
+	/**
+	 * @tests java.util.Locale#getISOCountries()
+	 */
+	public void test_getISOCountries() {
+		// Test for method java.lang.String []
+		// java.util.Locale.getISOCountries()
+		// Assumes all countries are 2 digits, and that there will always be
+		// 230 countries on the list...
+		String[] isoCountries = Locale.getISOCountries();
+		int length = isoCountries.length;
+		int familiarCount = 0;
+		for (int i = 0; i < length; i++) {
+			if (isoCountries[i].length() != 2) {
+				fail("Wrong format for ISOCountries.");
+			}
+			if (isoCountries[i].equals("CA") || isoCountries[i].equals("BB")
+					|| isoCountries[i].equals("US")
+					|| isoCountries[i].equals("KR"))
+				familiarCount++;
+		}
+		assertTrue("ISOCountries missing.", familiarCount == 4 && length > 230);
+	}
+
+	/**
+	 * @tests java.util.Locale#getISOLanguages()
+	 */
+	public void test_getISOLanguages() {
+		// Test for method java.lang.String []
+		// java.util.Locale.getISOLanguages()
+		// Assumes always at least 131 ISOlanguages...
+		String[] isoLang = Locale.getISOLanguages();
+		int length = isoLang.length;
+		
+		// Non-bug difference for HARMONY-5442
+		assertTrue(isoLang[length / 2].length() == 3);
+		assertTrue(isoLang[length / 2].toLowerCase().equals(isoLang[length / 2]));
+		assertTrue("Wrong number of ISOLanguages.", length > 130);
+	}
+
+	/**
+	 * @tests java.util.Locale#getLanguage()
+	 */
+	public void test_getLanguage() {
+		// Test for method java.lang.String java.util.Locale.getLanguage()
+		assertTrue("Returned incorrect language: " + testLocale.getLanguage(),
+				testLocale.getLanguage().equals("en"));
+	}
+
+	/**
+	 * @tests java.util.Locale#getVariant()
+	 */
+	public void test_getVariant() {
+		// Test for method java.lang.String java.util.Locale.getVariant()
+		assertTrue("Returned incorrect variant: " + testLocale.getVariant(),
+				testLocale.getVariant().equals("WIN32"));
+	}
+
+	/**
+	 * @tests java.util.Locale#setDefault(java.util.Locale)
+	 */
+	public void test_setDefaultLjava_util_Locale() {
+		// Test for method void java.util.Locale.setDefault(java.util.Locale)
+
+		Locale org = Locale.getDefault();
+		Locale.setDefault(l);
+		Locale x = Locale.getDefault();
+		Locale.setDefault(org);
+		assertEquals("Failed to set locale", "fr_CA_WIN32", x.toString());
+
+		Locale.setDefault(new Locale("tr", ""));
+		String res1 = "\u0069".toUpperCase();
+		String res2 = "\u0049".toLowerCase();
+		Locale.setDefault(org);
+		assertEquals("Wrong toUppercase conversion", "\u0130", res1);
+		assertEquals("Wrong toLowercase conversion", "\u0131", res2);
+	}
+
+	/**
+	 * @tests java.util.Locale#toString()
+	 */
+	public void test_toString() {
+		// Test for method java.lang.String java.util.Locale.toString()
+		assertEquals("Returned incorrect string representation", "en_CA_WIN32", testLocale
+				.toString());
+
+		Locale l = new Locale("en", "");
+		assertEquals("Wrong representation 1", "en", l.toString());
+		l = new Locale("", "CA");
+		assertEquals("Wrong representation 2", "_CA", l.toString());
+		
+		// Non-bug difference for HARMONY-5442
+		l = new Locale("", "CA", "var");
+		assertEquals("Wrong representation 2.5", "_CA_var", l.toString());
+		l = new Locale("en", "", "WIN");
+		assertEquals("Wrong representation 4", "en__WIN", l.toString());
+		l = new Locale("en", "CA");
+		assertEquals("Wrong representation 6", "en_CA", l.toString());
+		l = new Locale("en", "CA", "VAR");
+		assertEquals("Wrong representation 7", "en_CA_VAR", l.toString());
+        
+        l = new Locale("", "", "var");
+        assertEquals("Wrong representation 8", "", l.toString());
+
+	}
+    
+    // Regression Test for HARMONY-2953
+    public void test_getISO() {
+        Locale locale = new Locale("an");
+        assertEquals("arg", locale.getISO3Language());
+
+        locale = new Locale("PS");
+        assertEquals("pus", locale.getISO3Language());
+
+        List<String> languages = Arrays.asList(Locale.getISOLanguages());
+        assertTrue(languages.contains("ak"));
+        
+		// Non-bug difference for HARMONY-5442
+        List<String> countries = Arrays.asList(Locale.getISOCountries());
+        assertFalse(countries.contains("CS"));
+    }
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		defaultLocale = Locale.getDefault();
+		Locale.setDefault(Locale.US);
+		testLocale = new Locale("en", "CA", "WIN32");
+		l = new Locale("fr", "CA", "WIN32");
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+		Locale.setDefault(defaultLocale);
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatArgumentExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatArgumentExceptionTest.java
index d93b069..705b597 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatArgumentExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatArgumentExceptionTest.java
@@ -16,33 +16,20 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.MissingFormatArgumentException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(MissingFormatArgumentException.class) 
 public class MissingFormatArgumentExceptionTest extends TestCase {
 
     /**
      * @tests java.util.MissingFormatArgumentException#MissingFormatArgumentException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "MissingFormatArgumentException",
-        args = {java.lang.String.class}
-    )
     public void test_missingFormatArgumentException() {
-        assertNotNull(new MissingFormatArgumentException("String"));
 
         try {
             new MissingFormatArgumentException(null);
@@ -55,12 +42,6 @@
     /**
      * @tests java.util.MissingFormatArgumentException#getFormatSpecifier()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFormatSpecifier",
-        args = {}
-    )
     public void test_getFormatSpecifier() {
         String s = "MYTESTSTRING";
         MissingFormatArgumentException missingFormatArgumentException = new MissingFormatArgumentException(
@@ -71,12 +52,6 @@
     /**
      * @tests java.util.MissingFormatArgumentException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String s = "MYTESTSTRING";
         MissingFormatArgumentException missingFormatArgumentException = new MissingFormatArgumentException(
@@ -104,12 +79,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new MissingFormatArgumentException(
@@ -119,12 +88,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatWidthExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatWidthExceptionTest.java
index be94d1c..81fa2d7 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatWidthExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/MissingFormatWidthExceptionTest.java
@@ -15,33 +15,20 @@
  */
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.MissingFormatWidthException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(MissingFormatWidthException.class) 
 public class MissingFormatWidthExceptionTest extends TestCase {
 
     /**
      * @tests java.util.MissingFormatWidthException#MissingFormatWidthException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "MissingFormatWidthException",
-        args = {java.lang.String.class}
-    )
     public void test_missingFormatWidthException() {
-        assertNotNull(new MissingFormatWidthException("String"));
         try {
             new MissingFormatWidthException(null);
             fail("should throw NullPointerExcepiton");
@@ -53,12 +40,6 @@
     /**
      * @tests java.util.MissingFormatWidthException#getFormatSpecifier()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFormatSpecifier",
-        args = {}
-    )
     public void test_getFormatSpecifier() {
         String s = "MYTESTSTRING";
         MissingFormatWidthException missingFormatWidthException = new MissingFormatWidthException(
@@ -70,12 +51,6 @@
     /**
      * @tests java.util.MissingFormatWidthException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String s = "MYTESTSTRING";
         MissingFormatWidthException missingFormatWidthException = new MissingFormatWidthException(
@@ -103,12 +78,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new MissingFormatWidthException(
@@ -118,12 +87,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new MissingFormatWidthException(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java
index 562da42..d8f4cc4 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UUIDTest.java
@@ -17,30 +17,18 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.util.UUID;
 
 import org.apache.harmony.testframework.serialization.SerializationTest;
 
-@TestTargetClass(UUID.class) 
+import junit.framework.TestCase;
+
 public class UUIDTest extends TestCase {
 
     /**
      * @see UUID#UUID(long, long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UUID",
-        args = {long.class, long.class}
-    )
-    public void test_ConstructurJJ() {
+    public void test_ConstructorJJ() {
         UUID uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
         assertEquals(2, uuid.variant());
         assertEquals(1, uuid.version());
@@ -53,12 +41,6 @@
     /**
      * @see UUID#getLeastSignificantBits()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getLeastSignificantBits",
-        args = {}
-    )
     public void test_getLeastSignificantBits() {
         UUID uuid = new UUID(0, 0);
         assertEquals(0, uuid.getLeastSignificantBits());
@@ -71,12 +53,6 @@
     /**
      * @see UUID#getMostSignificantBits()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMostSignificantBits",
-        args = {}
-    )
     public void test_getMostSignificantBits() {
         UUID uuid = new UUID(0, 0);
         assertEquals(0, uuid.getMostSignificantBits());
@@ -89,12 +65,6 @@
     /**
      * @see UUID#version()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "version",
-        args = {}
-    )
     public void test_version() {
         UUID uuid = new UUID(0, 0);
         assertEquals(0, uuid.version());
@@ -113,12 +83,6 @@
     /**
      * @see UUID#variant()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "variant",
-        args = {}
-    )
     public void test_variant() {
         UUID uuid = new UUID(0, 0x0000000000000000L);
         assertEquals(0, uuid.variant());
@@ -152,12 +116,6 @@
     /**
      * @see UUID#timestamp()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "timestamp",
-        args = {}
-    )
     public void test_timestamp() {
         UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
         assertEquals(0x0, uuid.timestamp());
@@ -181,12 +139,6 @@
     /**
      * @see UUID#clockSequence()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clockSequence",
-        args = {}
-    )
     public void test_clockSequence() {
         UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
         assertEquals(0x0, uuid.clockSequence());
@@ -213,12 +165,6 @@
     /**
      * @see UUID#node()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "node",
-        args = {}
-    )
     public void test_node() {
         UUID uuid = new UUID(0x0000000000001000L, 0x8000000000000000L);
         assertEquals(0x0, uuid.node());
@@ -242,12 +188,6 @@
     /**
      * @see UUID#compareTo(UUID)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.util.UUID.class}
-    )
     public void test_compareTo() {
         UUID uuid1 = new UUID(0, 0);
         assertEquals(0, uuid1.compareTo(uuid1));
@@ -263,12 +203,6 @@
     /**
      * @see UUID#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         UUID uuid = new UUID(0, 0);
         assertEquals(0, uuid.hashCode());
@@ -280,12 +214,6 @@
     /**
      * @see UUID#equals(Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsObject() {
         UUID uuid1 = new UUID(0, 0);
         assertEquals(uuid1, uuid1);
@@ -308,12 +236,6 @@
     /**
      * @see UUID#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         UUID uuid = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
         String actual = uuid.toString();
@@ -327,12 +249,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
         SerializationTest.verifySelf(new UUID(0xf81d4fae7dec11d0L,
                 0xa76500a0c91e6bf6L));
@@ -341,12 +257,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
         SerializationTest.verifyGolden(this, new UUID(0xf81d4fae7dec11d0L,
                 0xa76500a0c91e6bf6L));
@@ -355,12 +265,6 @@
     /**
      * @see UUID#randomUUID()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "randomUUID",
-        args = {}
-    )
     public void test_randomUUID() {
         UUID uuid = UUID.randomUUID();
         assertEquals(2, uuid.variant());
@@ -370,12 +274,6 @@
     /**
      * @see UUID#nameUUIDFromBytes(byte[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "nameUUIDFromBytes",
-        args = {byte[].class}
-    )
     public void test_nameUUIDFromBytes() throws Exception {
         byte[] name = { (byte) 0x6b, (byte) 0xa7, (byte) 0xb8, (byte) 0x11,
                 (byte) 0x9d, (byte) 0xad, (byte) 0x11, (byte) 0xd1,
@@ -406,12 +304,6 @@
     /**
      * @see UUID#fromString(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "fromString",
-        args = {java.lang.String.class}
-    )
     public void test_fromString() {
         UUID actual = UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
         UUID expected = new UUID(0xf81d4fae7dec11d0L, 0xa76500a0c91e6bf6L);
@@ -464,108 +356,102 @@
         } catch (IllegalArgumentException e) {}
     }
 
-    /**
-     * @tests java.util.UUID#fromString(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "fromString",
-        args = {java.lang.String.class}
-    )
-    public void test_fromString_LString_Exception() {
+	/**
+	 * @tests java.util.UUID#fromString(String)
+	 */
+	public void test_fromString_LString_Exception() {
 
-        UUID uuid = UUID.fromString("0-0-0-0-0");
+		UUID uuid = UUID.fromString("0-0-0-0-0");
 
-        try {
-            uuid = UUID.fromString("0-0-0-0-");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("0-0-0-0-");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("-0-0-0-0-0");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("-0-0-0-0-0");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("-0-0-0-0");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("-0-0-0-0");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("-0-0-0-");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("-0-0-0-");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("0--0-0-0");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("0--0-0-0");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("0-0-0-0-");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("0-0-0-0-");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("-1-0-0-0-0");
-            fail("should throw IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("-1-0-0-0-0");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
 
-        uuid = UUID.fromString("123456789-0-0-0-0");
-        assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
-        assertEquals(0x0L, uuid.getLeastSignificantBits());
+		uuid = UUID.fromString("123456789-0-0-0-0");
+		assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
+		assertEquals(0x0L, uuid.getLeastSignificantBits());
 
-        uuid = UUID.fromString("111123456789-0-0-0-0");
-        assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
-        assertEquals(0x0L, uuid.getLeastSignificantBits());
+		uuid = UUID.fromString("111123456789-0-0-0-0");
+		assertEquals(0x2345678900000000L, uuid.getMostSignificantBits());
+		assertEquals(0x0L, uuid.getLeastSignificantBits());
 
-        uuid = UUID.fromString("7fffffffffffffff-0-0-0-0");
-        assertEquals(0xffffffff00000000L, uuid.getMostSignificantBits());
-        assertEquals(0x0L, uuid.getLeastSignificantBits());
+		uuid = UUID.fromString("7fffffffffffffff-0-0-0-0");
+		assertEquals(0xffffffff00000000L, uuid.getMostSignificantBits());
+		assertEquals(0x0L, uuid.getLeastSignificantBits());
 
-        try {
-            uuid = UUID.fromString("8000000000000000-0-0-0-0");
-            fail("should throw NumberFormatException");
-        } catch (NumberFormatException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("8000000000000000-0-0-0-0");
+			fail("should throw NumberFormatException");
+		} catch (NumberFormatException e) {
+			// expected
+		}
 
-        uuid = UUID
-                .fromString("7fffffffffffffff-7fffffffffffffff-7fffffffffffffff-0-0");
-        assertEquals(0xffffffffffffffffL, uuid.getMostSignificantBits());
-        assertEquals(0x0L, uuid.getLeastSignificantBits());
+		uuid = UUID
+				.fromString("7fffffffffffffff-7fffffffffffffff-7fffffffffffffff-0-0");
+		assertEquals(0xffffffffffffffffL, uuid.getMostSignificantBits());
+		assertEquals(0x0L, uuid.getLeastSignificantBits());
 
-        uuid = UUID.fromString("0-0-0-7fffffffffffffff-7fffffffffffffff");
-        assertEquals(0x0L, uuid.getMostSignificantBits());
-        assertEquals(0xffffffffffffffffL, uuid.getLeastSignificantBits());
+		uuid = UUID.fromString("0-0-0-7fffffffffffffff-7fffffffffffffff");
+		assertEquals(0x0L, uuid.getMostSignificantBits());
+		assertEquals(0xffffffffffffffffL, uuid.getLeastSignificantBits());
 
-        try {
-            uuid = UUID.fromString("0-0-0-8000000000000000-0");
-            fail("should throw NumberFormatException");
-        } catch (NumberFormatException e) {
-            // expected
-        }
+		try {
+			uuid = UUID.fromString("0-0-0-8000000000000000-0");
+			fail("should throw NumberFormatException");
+		} catch (NumberFormatException e) {
+			// expected
+		}
 
-        try {
-            uuid = UUID.fromString("0-0-0-0-8000000000000000");
-            fail("should throw NumberFormatException");
-        } catch (NumberFormatException e) {
-            // expected
-        }
-    }
+		try {
+			uuid = UUID.fromString("0-0-0-0-8000000000000000");
+			fail("should throw NumberFormatException");
+		} catch (NumberFormatException e) {
+			// expected
+		}
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatConversionExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatConversionExceptionTest.java
index 14ed171..262db4d 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatConversionExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatConversionExceptionTest.java
@@ -15,31 +15,19 @@
  */
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.UnknownFormatConversionException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(UnknownFormatConversionException.class) 
 public class UnknownFormatConversionExceptionTest extends TestCase {
 
     /**
      * @tests java.util.UnknownFormatConversionException#UnknownFormatConversionException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnknownFormatConversionException",
-        args = {java.lang.String.class}
-    )
     public void test_unknownFormatConversionException() {
 
         // RI 5.0 will not throw NullPointerException, it is the bug according
@@ -54,12 +42,6 @@
     /**
      * @tests java.util.UnknownFormatConversionException#getConversion()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getConversion",
-        args = {}
-    )
     public void test_getConversion() {
         String s = "MYTESTSTRING";
         UnknownFormatConversionException UnknownFormatConversionException = new UnknownFormatConversionException(
@@ -70,12 +52,6 @@
     /**
      * @tests java.util.UnknownFormatConversionException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String s = "MYTESTSTRING";
         UnknownFormatConversionException UnknownFormatConversionException = new UnknownFormatConversionException(
@@ -102,12 +78,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new UnknownFormatConversionException(
@@ -117,12 +87,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this,
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatFlagsExceptionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatFlagsExceptionTest.java
index c14cdee..3221cc5 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatFlagsExceptionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/UnknownFormatFlagsExceptionTest.java
@@ -16,31 +16,19 @@
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
 import java.io.Serializable;
 import java.util.UnknownFormatFlagsException;
 
+import junit.framework.TestCase;
+
 import org.apache.harmony.testframework.serialization.SerializationTest;
 import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
 
-@TestTargetClass(UnknownFormatFlagsException.class) 
 public class UnknownFormatFlagsExceptionTest extends TestCase {
 
     /**
      * @tests java.util.UnknownFormatFlagsException#UnknownFormatFlagsException(String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "UnknownFormatFlagsException",
-        args = {java.lang.String.class}
-    )
     public void test_unknownFormatFlagsException() {
 
         try {
@@ -49,18 +37,11 @@
         } catch (NullPointerException e) {
             // expected
         }
-        assertNotNull(new UnknownFormatFlagsException("String"));
     }
 
     /**
      * @tests java.util.UnknownFormatFlagsException#getFlags()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFlags",
-        args = {}
-    )
     public void test_getFlags() {
         String s = "MYTESTSTRING";
         UnknownFormatFlagsException UnknownFormatFlagsException = new UnknownFormatFlagsException(
@@ -71,12 +52,6 @@
     /**
      * @tests java.util.UnknownFormatFlagsException#getMessage()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMessage",
-        args = {}
-    )
     public void test_getMessage() {
         String s = "MYTESTSTRING";
         UnknownFormatFlagsException UnknownFormatFlagsException = new UnknownFormatFlagsException(
@@ -102,12 +77,6 @@
     /**
      * @tests serialization/deserialization.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void testSerializationSelf() throws Exception {
 
         SerializationTest.verifySelf(new UnknownFormatFlagsException(
@@ -117,12 +86,6 @@
     /**
      * @tests serialization/deserialization compatibility with RI.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "!SerializationGolden",
-        args = {}
-    )
     public void testSerializationCompatibility() throws Exception {
 
         SerializationTest.verifyGolden(this, new UnknownFormatFlagsException(
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/VectorTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/VectorTest.java
index 18cb550..82592b19 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/VectorTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/VectorTest.java
@@ -1,42 +1,1230 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Vector;
 
-@TestTargetClass(Vector.class) 
-public class VectorTest extends TestCase {
+import tests.support.Support_ListTest;
+
+public class VectorTest extends junit.framework.TestCase {
+
+	private Vector tVector = new Vector();
+
+	Object[] objArray;
+
+	private String vString = "[Test 0, Test 1, Test 2, Test 3, Test 4, Test 5, Test 6, Test 7, Test 8, Test 9, Test 10, Test 11, Test 12, Test 13, Test 14, Test 15, Test 16, Test 17, Test 18, Test 19, Test 20, Test 21, Test 22, Test 23, Test 24, Test 25, Test 26, Test 27, Test 28, Test 29, Test 30, Test 31, Test 32, Test 33, Test 34, Test 35, Test 36, Test 37, Test 38, Test 39, Test 40, Test 41, Test 42, Test 43, Test 44, Test 45, Test 46, Test 47, Test 48, Test 49, Test 50, Test 51, Test 52, Test 53, Test 54, Test 55, Test 56, Test 57, Test 58, Test 59, Test 60, Test 61, Test 62, Test 63, Test 64, Test 65, Test 66, Test 67, Test 68, Test 69, Test 70, Test 71, Test 72, Test 73, Test 74, Test 75, Test 76, Test 77, Test 78, Test 79, Test 80, Test 81, Test 82, Test 83, Test 84, Test 85, Test 86, Test 87, Test 88, Test 89, Test 90, Test 91, Test 92, Test 93, Test 94, Test 95, Test 96, Test 97, Test 98, Test 99]";
+
+	/**
+	 * @tests java.util.Vector#Vector()
+	 */
+	public void test_Constructor() {
+		// Test for method java.util.Vector()
+
+		Vector tv = new Vector(100);
+		for (int i = 0; i < 100; i++)
+			tv.addElement(new Integer(i));
+		new Support_ListTest("", tv).runTest();
+
+		tv = new Vector(200);
+		for (int i = -50; i < 150; i++)
+			tv.addElement(new Integer(i));
+		new Support_ListTest("", tv.subList(50, 150)).runTest();
+
+		Vector v = new Vector();
+		assertEquals("Vector creation failed", 0, v.size());
+		assertEquals("Wrong capacity", 10, v.capacity());
+	}
+
+	/**
+	 * @tests java.util.Vector#Vector(int)
+	 */
+	public void test_ConstructorI() {
+		// Test for method java.util.Vector(int)
+
+		Vector v = new Vector(100);
+		assertEquals("Vector creation failed", 0, v.size());
+		assertEquals("Wrong capacity", 100, v.capacity());
+	}
+
+	/**
+	 * @tests java.util.Vector#Vector(int, int)
+	 */
+	public void test_ConstructorII() {
+		// Test for method java.util.Vector(int, int)
+
+		Vector v = new Vector(2, 10);
+		v.addElement(new Object());
+		v.addElement(new Object());
+		v.addElement(new Object());
+
+		assertEquals("Failed to inc capacity by proper amount",
+				12, v.capacity());
+
+		Vector grow = new Vector(3, -1);
+		grow.addElement("one");
+		grow.addElement("two");
+		grow.addElement("three");
+		grow.addElement("four");
+		assertEquals("Wrong size", 4, grow.size());
+		assertEquals("Wrong capacity", 6, grow.capacity());
+        
+        Vector emptyVector = new Vector(0, 0);
+        emptyVector.addElement("one");
+        assertEquals("Wrong size", 1, emptyVector.size());
+        emptyVector.addElement("two");
+        emptyVector.addElement("three");
+        assertEquals("Wrong size", 3, emptyVector.size());
+
+        try {
+            Vector negativeVector = new Vector(-1, 0);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#Vector(java.util.Collection)
+	 */
+	public void test_ConstructorLjava_util_Collection() {
+		// Test for method java.util.Vector(java.util.Collection)
+		Collection l = new LinkedList();
+		for (int i = 0; i < 100; i++)
+			l.add("Test " + i);
+		Vector myVector = new Vector(l);
+		assertTrue("Vector is not correct size",
+				myVector.size() == objArray.length);
+		for (int counter = 0; counter < objArray.length; counter++)
+			assertTrue("Vector does not contain correct elements", myVector
+					.contains(((List) l).get(counter)));
+	}
+
+	/**
+	 * @tests java.util.Vector#add(int, java.lang.Object)
+	 */
+	public void test_addILjava_lang_Object() {
+		// Test for method void java.util.Vector.add(int, java.lang.Object)
+		Object o = new Object();
+		Object prev = tVector.get(45);
+		tVector.add(45, o);
+		assertTrue("Failed to add Object", tVector.get(45) == o);
+		assertTrue("Failed to fix-up existing indices", tVector.get(46) == prev);
+		assertEquals("Wrong size after add", 101, tVector.size());
+
+		prev = tVector.get(50);
+		tVector.add(50, null);
+		assertNull("Failed to add null", tVector.get(50));
+		assertTrue("Failed to fix-up existing indices after adding null",
+				tVector.get(51) == prev);
+		assertEquals("Wrong size after add", 102, tVector.size());
+	}
+
+	/**
+	 * @tests java.util.Vector#add(java.lang.Object)
+	 */
+	public void test_addLjava_lang_Object() {
+		// Test for method boolean java.util.Vector.add(java.lang.Object)
+		Object o = new Object();
+		tVector.add(o);
+		assertTrue("Failed to add Object", tVector.lastElement() == o);
+		assertEquals("Wrong size after add", 101, tVector.size());
+
+		tVector.add(null);
+		assertNull("Failed to add null", tVector.lastElement());
+		assertEquals("Wrong size after add", 102, tVector.size());
+	}
+
+	/**
+	 * @tests java.util.Vector#addAll(int, java.util.Collection)
+	 */
+	public void test_addAllILjava_util_Collection() {
+		// Test for method boolean java.util.Vector.addAll(int,
+		// java.util.Collection)
+		Collection l = new LinkedList();
+		for (int i = 0; i < 100; i++)
+			l.add("Test " + i);
+		Vector v = new Vector();
+		tVector.addAll(50, l);
+		for (int i = 50; i < 100; i++)
+			assertTrue("Failed to add all elements",
+					tVector.get(i) == ((List) l).get(i - 50));
+		v = new Vector();
+		v.add("one");
+		int r = 0;
+		try {
+			v.addAll(3, Arrays.asList(new String[] { "two", "three" }));
+		} catch (ArrayIndexOutOfBoundsException e) {
+			r = 1;
+		} catch (IndexOutOfBoundsException e) {
+			r = 2;
+		}
+		assertTrue("Invalid add: " + r, r == 1);
+		l = new LinkedList();
+		l.add(null);
+		l.add("gah");
+		l.add(null);
+		tVector.addAll(50, l);
+		assertNull("Wrong element at position 50--wanted null",
+				tVector.get(50));
+		assertEquals("Wrong element at position 51--wanted 'gah'", "gah", tVector
+				.get(51));
+		assertNull("Wrong element at position 52--wanted null",
+				tVector.get(52));
+        
+        try {
+            v.addAll(0, null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Excepted
+        }
+
+        try {
+            v.addAll(-1, null);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#addAll(java.util.Collection)
+	 */
+	public void test_addAllLjava_util_Collection() {
+		// Test for method boolean java.util.Vector.addAll(java.util.Collection)
+		Vector v = new Vector();
+		Collection l = new LinkedList();
+		for (int i = 0; i < 100; i++)
+			l.add("Test " + i);
+		v.addAll(l);
+		assertTrue("Failed to add all elements", tVector.equals(v));
+
+		v.addAll(l);
+		int vSize = tVector.size();
+		for (int counter = vSize - 1; counter >= 0; counter--)
+			assertTrue("Failed to add elements correctly", v.get(counter) == v
+					.get(counter + vSize));
+
+		l = new LinkedList();
+		l.add(null);
+		l.add("gah");
+		l.add(null);
+		tVector.addAll(l);
+		assertNull("Wrong element at 3rd last position--wanted null", tVector
+				.get(vSize));
+		assertEquals("Wrong element at 2nd last position--wanted 'gah'", "gah", tVector
+				.get(vSize + 1));
+		assertNull("Wrong element at last position--wanted null", tVector
+				.get(vSize + 2));
+        
+        try {
+            v.addAll(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#addElement(java.lang.Object)
+	 */
+	public void test_addElementLjava_lang_Object() {
+		// Test for method void java.util.Vector.addElement(java.lang.Object)
+		Vector v = vectorClone(tVector);
+		v.addElement("Added Element");
+		assertTrue("Failed to add element", v.contains("Added Element"));
+		assertEquals("Added Element to wrong slot", "Added Element", ((String) v.elementAt(100))
+				);
+		v.addElement(null);
+		assertTrue("Failed to add null", v.contains(null));
+		assertNull("Added null to wrong slot", v.elementAt(101));
+	}
+
+	/**
+	 * @tests java.util.Vector#addElement(java.lang.Object)
+	 */
+	public void test_addElementLjava_lang_Object_subtest0() {
+		// Test for method void java.util.Vector.addElement(java.lang.Object)
+		Vector v = vectorClone(tVector);
+		v.addElement("Added Element");
+		assertTrue("Failed to add element", v.contains("Added Element"));
+		assertEquals("Added Element to wrong slot", "Added Element", ((String) v.elementAt(100))
+				);
+		v.addElement(null);
+		assertTrue("Failed to add null", v.contains(null));
+		assertNull("Added null to wrong slot", v.elementAt(101));
+	}
+
+	/**
+	 * @tests java.util.Vector#capacity()
+	 */
+	public void test_capacity() {
+		// Test for method int java.util.Vector.capacity()
+
+		Vector v = new Vector(9);
+		assertEquals("Incorrect capacity returned", 9, v.capacity());
+	}
+
+	/**
+	 * @tests java.util.Vector#clear()
+	 */
+	public void test_clear() {
+		// Test for method void java.util.Vector.clear()
+		Vector orgVector = vectorClone(tVector);
+		tVector.clear();
+		assertEquals("a) Cleared Vector has non-zero size", 0, tVector.size());
+		Enumeration e = orgVector.elements();
+		while (e.hasMoreElements())
+			assertTrue("a) Cleared vector contained elements", !tVector
+					.contains(e.nextElement()));
+
+		tVector.add(null);
+		tVector.clear();
+		assertEquals("b) Cleared Vector has non-zero size", 0, tVector.size());
+		e = orgVector.elements();
+		while (e.hasMoreElements())
+			assertTrue("b) Cleared vector contained elements", !tVector
+					.contains(e.nextElement()));
+	}
+
+	/**
+	 * @tests java.util.Vector#clone()
+	 */
+	public void test_clone() {
+		// Test for method java.lang.Object java.util.Vector.clone()
+		tVector.add(25, null);
+		tVector.add(75, null);
+		Vector v = (Vector) tVector.clone();
+		Enumeration orgNum = tVector.elements();
+		Enumeration cnum = v.elements();
+
+		while (orgNum.hasMoreElements()) {
+			assertTrue("Not enough elements copied", cnum.hasMoreElements());
+			assertTrue("Vector cloned improperly, elements do not match",
+					orgNum.nextElement() == cnum.nextElement());
+		}
+		assertTrue("Not enough elements copied", !cnum.hasMoreElements());
+
+	}
+
+	/**
+	 * @tests java.util.Vector#contains(java.lang.Object)
+	 */
+	public void test_containsLjava_lang_Object() {
+		// Test for method boolean java.util.Vector.contains(java.lang.Object)
+		assertTrue("Did not find element", tVector.contains("Test 42"));
+		assertTrue("Found bogus element", !tVector.contains("Hello"));
+		assertTrue(
+				"Returned true looking for null in vector without null element",
+				!tVector.contains(null));
+		tVector.insertElementAt(null, 20);
+		assertTrue(
+				"Returned false looking for null in vector with null element",
+				tVector.contains(null));
+	}
+
+	/**
+	 * @tests java.util.Vector#containsAll(java.util.Collection)
+	 */
+	public void test_containsAllLjava_util_Collection() {
+		// Test for method boolean
+		// java.util.Vector.containsAll(java.util.Collection)
+		Collection s = new HashSet();
+		for (int i = 0; i < 100; i++)
+			s.add("Test " + i);
+
+		assertTrue("Returned false for valid collection", tVector
+				.containsAll(s));
+		s.add(null);
+		assertTrue("Returned true for invlaid collection containing null",
+				!tVector.containsAll(s));
+		tVector.add(25, null);
+		assertTrue("Returned false for valid collection containing null",
+				tVector.containsAll(s));
+		s = new HashSet();
+		s.add(new Object());
+		assertTrue("Returned true for invalid collection", !tVector
+				.containsAll(s));
+	}
+
+	/**
+	 * @tests java.util.Vector#copyInto(java.lang.Object[])
+	 */
+	public void test_copyInto$Ljava_lang_Object() {
+		// Test for method void java.util.Vector.copyInto(java.lang.Object [])
+
+		Object[] a = new Object[100];
+		tVector.setElementAt(null, 20);
+		tVector.copyInto(a);
+
+		for (int i = 0; i < 100; i++)
+			assertTrue("copyInto failed", a[i] == tVector.elementAt(i));
+	}
+
+	/**
+	 * @tests java.util.Vector#elementAt(int)
+	 */
+	public void test_elementAtI() {
+		// Test for method java.lang.Object java.util.Vector.elementAt(int)
+		assertEquals("Incorrect element returned", "Test 18", ((String) tVector
+				.elementAt(18)));
+		tVector.setElementAt(null, 20);
+		assertNull("Incorrect element returned--wanted null", tVector
+				.elementAt(20));
+
+	}
+
+	/**
+	 * @tests java.util.Vector#elements()
+	 */
+	public void test_elements() {
+		// Test for method java.util.Enumeration java.util.Vector.elements()
+		tVector.insertElementAt(null, 20);
+		Enumeration e = tVector.elements();
+		int i = 0;
+		while (e.hasMoreElements()) {
+			assertTrue("Enumeration returned incorrect element at pos: " + i, e
+					.nextElement() == tVector.elementAt(i));
+			i++;
+		}
+		assertTrue("Invalid enumeration", i == tVector.size());
+	}
+
+	/**
+	 * @tests java.util.Vector#elements()
+	 */
+	public void test_elements_subtest0() {
+		final int iterations = 10000;
+		final Vector v = new Vector();
+		Thread t1 = new Thread() {
+			public void run() {
+				for (int i = 0; i < iterations; i++) {
+					synchronized (v) {
+						v.addElement(String.valueOf(i));
+						v.removeElementAt(0);
+					}
+				}
+			}
+		};
+		t1.start();
+		for (int i = 0; i < iterations; i++) {
+			Enumeration en = v.elements();
+			try {
+				while (true) {
+					Object result = en.nextElement();
+					if (result == null) {
+						fail("Null result: " + i);
+					}
+				}
+			} catch (NoSuchElementException e) {
+			}
+		}
+	}
+
+	/**
+	 * @tests java.util.Vector#ensureCapacity(int)
+	 */
+	public void test_ensureCapacityI() {
+		// Test for method void java.util.Vector.ensureCapacity(int)
+
+		Vector v = new Vector(9);
+		v.ensureCapacity(20);
+		assertEquals("ensureCapacity failed to set correct capacity", 20, v
+				.capacity());
+		v = new Vector(100);
+		assertEquals("ensureCapacity reduced capacity", 100, v.capacity());
+        
+        v.ensureCapacity(150);
+        assertEquals(
+                "ensuieCapacity failed to set to be twice the old capacity",
+                200, v.capacity());
+
+        v = new Vector(9, -1);
+        v.ensureCapacity(20);
+        assertEquals("ensureCapacity failed to set to be minCapacity", 20, v
+                .capacity());
+        v.ensureCapacity(15);
+        assertEquals("ensureCapacity reduced capacity", 20, v.capacity());
+        v.ensureCapacity(35);
+        assertEquals(
+                "ensuieCapacity failed to set to be twice the old capacity",
+                40, v.capacity());
+
+        v = new Vector(9, 4);
+        v.ensureCapacity(11);
+        assertEquals("ensureCapacity failed to set correct capacity", 13, v
+                .capacity());
+        v.ensureCapacity(5);
+        assertEquals("ensureCapacity reduced capacity", 13, v.capacity());
+        v.ensureCapacity(20);
+        assertEquals(
+                "ensuieCapacity failed to set to be twice the old capacity",
+                20, v.capacity());
+	}
+
+	/**
+	 * @tests java.util.Vector#equals(java.lang.Object)
+	 */
+	public void test_equalsLjava_lang_Object() {
+		// Test for method boolean java.util.Vector.equals(java.lang.Object)
+		Vector v = new Vector();
+		for (int i = 0; i < 100; i++)
+			v.addElement("Test " + i);
+		assertTrue("a) Equal vectors returned false", tVector.equals(v));
+		v.addElement(null);
+		assertTrue("b) UnEqual vectors returned true", !tVector.equals(v));
+		tVector.addElement(null);
+		assertTrue("c) Equal vectors returned false", tVector.equals(v));
+		tVector.removeElementAt(22);
+		assertTrue("d) UnEqual vectors returned true", !tVector.equals(v));
+        assertTrue("e) Equal vectors returned false", tVector.equals(tVector));
+        assertFalse("f) UnEqual vectors returned true", tVector
+                .equals(new Object()));
+        assertFalse("g) Unequal vectors returned true", tVector.equals(null));
+	}
+
+	/**
+	 * @tests java.util.Vector#firstElement()
+	 */
+	public void test_firstElement() {
+		// Test for method java.lang.Object java.util.Vector.firstElement()
+		assertEquals("Returned incorrect firstElement", "Test 0", tVector.firstElement()
+				);
+		tVector.insertElementAt(null, 0);
+		assertNull("Returned incorrect firstElement--wanted null", tVector
+				.firstElement());
+        
+        Vector v = new Vector();
+        try {
+            v.firstElement();
+            fail("Should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#get(int)
+	 */
+	public void test_getI() {
+		// Test for method java.lang.Object java.util.Vector.get(int)
+		assertEquals("Get returned incorrect object", 
+				"Test 80", tVector.get(80));
+		tVector.add(25, null);
+		assertNull("Returned incorrect element--wanted null",
+				tVector.get(25));
+	}
+
+	/**
+	 * @tests java.util.Vector#hashCode()
+	 */
+	public void test_hashCode() {
+		// Test for method int java.util.Vector.hashCode()
+		int hashCode = 1; // one
+		tVector.insertElementAt(null, 20);
+		for (int i = 0; i < tVector.size(); i++) {
+			Object obj = tVector.elementAt(i);
+			hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
+		}
+		assertTrue("Incorrect hashCode returned.  Wanted: " + hashCode
+				+ " got: " + tVector.hashCode(), tVector.hashCode() == hashCode);
+	}
+
+	/**
+	 * @tests java.util.Vector#indexOf(java.lang.Object)
+	 */
+	public void test_indexOfLjava_lang_Object() {
+		// Test for method int java.util.Vector.indexOf(java.lang.Object)
+		assertEquals("Incorrect index returned", 10, tVector.indexOf("Test 10"));
+		assertEquals("Index returned for invalid Object", -1, tVector
+				.indexOf("XXXXXXXXXXX"));
+		tVector.setElementAt(null, 20);
+		tVector.setElementAt(null, 40);
+		assertTrue("Incorrect indexOf returned for null: "
+				+ tVector.indexOf(null), tVector.indexOf(null) == 20);
+	}
+
+	/**
+	 * @tests java.util.Vector#indexOf(java.lang.Object, int)
+	 */
+	public void test_indexOfLjava_lang_ObjectI() {
+		// Test for method int java.util.Vector.indexOf(java.lang.Object, int)
+		assertEquals("Failed to find correct index", tVector.indexOf("Test 98",
+				50), 98);
+		assertTrue("Found index of bogus element", (tVector.indexOf(
+				"Test 1001", 50) == -1));
+		tVector.setElementAt(null, 20);
+		tVector.setElementAt(null, 40);
+		tVector.setElementAt(null, 60);
+		assertTrue("a) Incorrect indexOf returned for null: "
+				+ tVector.indexOf(null, 25), tVector.indexOf(null, 25) == 40);
+		assertTrue("b) Incorrect indexOf returned for null: "
+				+ tVector.indexOf(null, 20), tVector.indexOf(null, 20) == 20);
+		try {
+			tVector.indexOf("Test 98", -1);
+			fail("should throw ArrayIndexOutOfBoundsException");
+		} catch (ArrayIndexOutOfBoundsException e) {
+
+		}
+		assertEquals(-1, tVector.indexOf("Test 98", 1000));
+		assertEquals(-1, tVector.indexOf("Test 98", Integer.MAX_VALUE));
+		assertEquals(-1, tVector.indexOf("Test 98", tVector.size()));
+		assertEquals(98, tVector.indexOf("Test 98", 0));
+		try {
+			tVector.indexOf("Test 98", Integer.MIN_VALUE);
+			fail("should throw ArrayIndexOutOfBoundsException");
+		} catch (ArrayIndexOutOfBoundsException e) {
+
+		}
+	}
+
+	/**
+	 * @tests java.util.Vector#insertElementAt(java.lang.Object, int)
+	 */
+	public void test_insertElementAtLjava_lang_ObjectI() {
+		// Test for method void
+		// java.util.Vector.insertElementAt(java.lang.Object, int)
+		Vector v = vectorClone(tVector);
+		String prevElement = (String) v.elementAt(99);
+		v.insertElementAt("Inserted Element", 99);
+		assertEquals("Element not inserted", "Inserted Element", ((String) v.elementAt(99))
+				);
+		assertTrue("Elements shifted incorrectly", ((String) v.elementAt(100))
+				.equals(prevElement));
+		v.insertElementAt(null, 20);
+		assertNull("null not inserted", v.elementAt(20));
+        
+        try {
+            tVector.insertElementAt("Inserted Element", -1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.insertElementAt(null, -1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.insertElementAt("Inserted Element", tVector.size() + 1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.insertElementAt(null, tVector.size() + 1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#isEmpty()
+	 */
+	public void test_isEmpty() {
+		// Test for method boolean java.util.Vector.isEmpty()Vector
+		Vector v = new java.util.Vector();
+		assertTrue("Empty vector returned false", v.isEmpty());
+		v.addElement(new Object());
+		assertTrue("non-Empty vector returned true", !v.isEmpty());
+	}
+
+	/**
+	 * @tests java.util.Vector#isEmpty()
+	 */
+	public void test_isEmpty_subtest0() {
+		final Vector v = new Vector();
+		v.addElement("initial");
+		Thread t1 = new Thread() {
+			public void run() {
+				while (!v.isEmpty())
+					;
+				v.addElement("final");
+			}
+		};
+		t1.start();
+		for (int i = 0; i < 10000; i++) {
+			synchronized (v) {
+				v.removeElementAt(0);
+				v.addElement(String.valueOf(i));
+			}
+			int size;
+			if ((size = v.size()) != 1) {
+				String result = "Size is not 1: " + size + " " + v;
+				// terminate the thread
+				v.removeAllElements();
+				fail(result);
+			}
+		}
+		// terminate the thread
+		v.removeElementAt(0);
+	}
+
+	/**
+	 * @tests java.util.Vector#lastElement()
+	 */
+	public void test_lastElement() {
+		// Test for method java.lang.Object java.util.Vector.lastElement()
+		assertEquals("Incorrect last element returned", "Test 99", tVector.lastElement()
+				);
+		tVector.addElement(null);
+		assertNull("Incorrect last element returned--wanted null", tVector
+				.lastElement());
+        
+        Vector vector = new Vector();
+        try {
+            vector.lastElement();
+            fail("Should throw NoSuchElementException");
+        } catch (NoSuchElementException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#lastIndexOf(java.lang.Object)
+	 */
+	public void test_lastIndexOfLjava_lang_Object() {
+		// Test for method int java.util.Vector.lastIndexOf(java.lang.Object)
+		Vector v = new Vector(9);
+		for (int i = 0; i < 9; i++)
+			v.addElement("Test");
+		v.addElement("z");
+		assertEquals("Failed to return correct index", 8, v.lastIndexOf("Test"));
+		tVector.setElementAt(null, 20);
+		tVector.setElementAt(null, 40);
+		assertTrue("Incorrect lastIndexOf returned for null: "
+				+ tVector.lastIndexOf(null), tVector.lastIndexOf(null) == 40);
+	}
+
+	/**
+	 * @tests java.util.Vector#lastIndexOf(java.lang.Object, int)
+	 */
+	public void test_lastIndexOfLjava_lang_ObjectI() {
+		// Test for method int java.util.Vector.lastIndexOf(java.lang.Object,
+		// int)
+		assertEquals("Failed to find object",
+				0, tVector.lastIndexOf("Test 0", 0));
+		assertTrue("Found Object outside of index", (tVector.lastIndexOf(
+				"Test 0", 10) > -1));
+		tVector.setElementAt(null, 20);
+		tVector.setElementAt(null, 40);
+		tVector.setElementAt(null, 60);
+		assertTrue("Incorrect lastIndexOf returned for null: "
+				+ tVector.lastIndexOf(null, 15),
+				tVector.lastIndexOf(null, 15) == -1);
+		assertTrue("Incorrect lastIndexOf returned for null: "
+				+ tVector.lastIndexOf(null, 45),
+				tVector.lastIndexOf(null, 45) == 40);
+
+		assertEquals(-1, tVector.lastIndexOf("Test 98", -1));
+		assertEquals(-1, tVector.lastIndexOf("Test 98", 0));
+		try {
+			assertEquals(-1, tVector.lastIndexOf("Test 98", 1000));
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+		}
+		try {
+			assertEquals(-1, tVector.lastIndexOf("Test 98", Integer.MAX_VALUE));
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+		}
+		try {
+			tVector.lastIndexOf("Test 98", tVector.size());
+			fail("should throw IndexOutOfBoundsException");
+		} catch (IndexOutOfBoundsException e) {
+		}
+		try {
+			tVector.indexOf("Test 98", Integer.MIN_VALUE);
+			fail("should throw ArrayIndexOutOfBoundsException");
+		} catch (ArrayIndexOutOfBoundsException e) {
+		}
+	}
+
+	/**
+	 * @tests java.util.Vector#remove(int)
+	 */
+	public void test_removeI() {
+		// Test for method java.lang.Object java.util.Vector.remove(int)
+		Object removeElement = tVector.get(36);
+        Object result = tVector.remove(36);
+		assertFalse("Contained element after remove", tVector
+				.contains("Test 36"));
+        assertEquals("Should return the element that was removed",
+                removeElement, result);
+		assertEquals("Failed to decrement size after remove",
+				99, tVector.size());
+		tVector.add(20, null);
+        removeElement = tVector.get(19);
+        result = tVector.remove(19);
+		assertNull("Didn't move null element over", tVector.get(19));
+        assertEquals("Should return the element that was removed",
+                removeElement, result);
+        removeElement = tVector.get(19);
+        result = tVector.remove(19);
+		assertNotNull("Didn't remove null element", tVector.get(19));
+        assertEquals("Should return the element that was removed",
+                removeElement, result);
+		assertEquals("Failed to decrement size after removing null", 98, tVector
+				.size());
+        
+        try {
+            tVector.remove(-1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.remove(tVector.size());
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#remove(java.lang.Object)
+	 */
+	public void test_removeLjava_lang_Object() {
+		// Test for method boolean java.util.Vector.remove(java.lang.Object)
+		tVector.remove("Test 0");
+		assertTrue("Contained element after remove", !tVector
+				.contains("Test 0"));
+		assertEquals("Failed to decrement size after remove",
+				99, tVector.size());
+		tVector.add(null);
+		tVector.remove(null);
+		assertTrue("Contained null after remove", !tVector.contains(null));
+		assertEquals("Failed to decrement size after removing null", 99, tVector
+				.size());
+	}
+
+	/**
+	 * @tests java.util.Vector#removeAll(java.util.Collection)
+	 */
+	public void test_removeAllLjava_util_Collection() {
+		// Test for method boolean
+		// java.util.Vector.removeAll(java.util.Collection)
+		Vector v = new Vector();
+		Collection l = new LinkedList();
+		for (int i = 0; i < 5; i++)
+			l.add("Test " + i);
+		v.addElement(l);
+
+		Collection s = new HashSet();
+		Object o;
+		s.add(o = v.firstElement());
+		v.removeAll(s);
+		assertTrue("Failed to remove items in collection", !v.contains(o));
+		v.removeAll(l);
+		assertTrue("Failed to remove all elements", v.isEmpty());
+
+		v.add(null);
+		v.add(null);
+		v.add("Boom");
+		v.removeAll(s);
+		assertEquals("Should not have removed any elements", 3, v.size());
+		l = new LinkedList();
+		l.add(null);
+		v.removeAll(l);
+		assertEquals("Should only have one element", 1, v.size());
+		assertEquals("Element should be 'Boom'", "Boom", v.firstElement());
+	}
+
+	/**
+	 * @tests java.util.Vector#removeAllElements()
+	 */
+	public void test_removeAllElements() {
+		// Test for method void java.util.Vector.removeAllElements()
+		Vector v = vectorClone(tVector);
+		v.removeAllElements();
+		assertEquals("Failed to remove all elements", 0, v.size());
+	}
+
+	/**
+	 * @tests java.util.Vector#removeElement(java.lang.Object)
+	 */
+	public void test_removeElementLjava_lang_Object() {
+		// Test for method boolean
+		// java.util.Vector.removeElement(java.lang.Object)
+		Vector v = vectorClone(tVector);
+		v.removeElement("Test 98");
+		assertEquals("Element not removed", "Test 99", ((String) v.elementAt(98))
+				);
+		assertTrue("Vector is wrong size after removal: " + v.size(),
+				v.size() == 99);
+		tVector.addElement(null);
+		v.removeElement(null);
+		assertTrue("Vector is wrong size after removing null: " + v.size(), v
+				.size() == 99);
+	}
+
+	/**
+	 * @tests java.util.Vector#removeElementAt(int)
+	 */
+	public void test_removeElementAtI() {
+		// Test for method void java.util.Vector.removeElementAt(int)
+		Vector v = vectorClone(tVector);
+        int size = v.size();
+		v.removeElementAt(50);
+		assertEquals("Failed to remove element", -1, v.indexOf("Test 50", 0));
+        assertEquals("Test 51", v.get(50));
+        assertEquals(size - 1, v.size());
+        
+		tVector.insertElementAt(null, 60);
+        assertNull(tVector.get(60));
+        size = tVector.size();
+		tVector.removeElementAt(60);
+		assertNotNull("Element at 60 should not be null after removal", tVector
+				.elementAt(60));
+        assertEquals(size - 1, tVector.size());
+
+        try {
+            tVector.removeElementAt(-1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.removeElementAt(tVector.size());
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+    
+    /**
+     * @tests {@link java.util.Vector#removeRange(int, int)}
+     */
+    public void test_removeRange() {
+        MockVector myVector = new MockVector();
+        myVector.removeRange(0, 0);
+
+        try {
+            myVector.removeRange(0, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        int[] data = { 1, 2, 3, 4 };
+        for (int i = 0; i < data.length; i++) {
+            myVector.add(i, data[i]);
+        }
+
+        myVector.removeRange(0, 2);
+        assertEquals(data[2], myVector.get(0));
+        assertEquals(data[3], myVector.get(1));
+
+        try {
+            myVector.removeRange(-1, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            myVector.removeRange(0, -1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            myVector.removeRange(1, 0);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            myVector.removeRange(2, 1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // Excepted
+        }
+    }
+
+	/**
+	 * @tests java.util.Vector#retainAll(java.util.Collection)
+	 */
+	public void test_retainAllLjava_util_Collection() {
+		// Test for method boolean
+		// java.util.Vector.retainAll(java.util.Collection)
+		Object o = tVector.firstElement();
+		tVector.add(null);
+		Collection s = new HashSet();
+		s.add(o);
+		s.add(null);
+		tVector.retainAll(s);
+		assertTrue("Retained items other than specified", tVector.size() == 2
+				&& tVector.contains(o) && tVector.contains(null));
+	}
+
+	/**
+	 * @tests java.util.Vector#set(int, java.lang.Object)
+	 */
+	public void test_setILjava_lang_Object() {
+		// Test for method java.lang.Object java.util.Vector.set(int,
+		// java.lang.Object)
+		Object o = new Object();
+        Object previous = tVector.get(23);
+        Object result = tVector.set(23, o);
+        assertEquals(
+                "Should return the element previously at the specified position",
+                previous, result);
+		assertTrue("Failed to set Object", tVector.get(23) == o);
+        
+        previous = tVector.get(0);
+        result = tVector.set(0, null);
+        assertEquals(
+                "Should return the element previously at the specified position",
+                previous, result);
+        assertNull("Failed to set Object", tVector.get(0));
+
+        try {
+            tVector.set(-1, o);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.set(-1, null);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.set(tVector.size(), o);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            tVector.set(tVector.size(), null);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#setElementAt(java.lang.Object, int)
+	 */
+	public void test_setElementAtLjava_lang_ObjectI() {
+		// Test for method void java.util.Vector.setElementAt(java.lang.Object,
+		// int)
+		Vector v = vectorClone(tVector);
+		v.setElementAt("Inserted Element", 99);
+		assertEquals("Element not set", "Inserted Element", ((String) v.elementAt(99))
+				);
+        
+        v.setElementAt(null, 0);
+        assertNull("Null element not set", v.elementAt(0));
+
+        try {
+            v.setElementAt("Inserted Element", -1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            v.setElementAt(null, -1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            v.setElementAt("Inserted Element", v.size());
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+
+        try {
+            v.setElementAt(null, v.size());
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#setSize(int)
+	 */
+	public void test_setSizeI() {
+		// Test for method void java.util.Vector.setSize(int)
+		Vector v = vectorClone(tVector);
+        int oldSize = v.size();
+        Object preElement = v.get(10);
+		v.setSize(10);
+		assertEquals("Failed to set size", 10, v.size());
+        assertEquals(
+                "All components at index newSize and greater should be discarded",
+                -1, v.indexOf(preElement));
+        try {
+            v.get(oldSize - 1);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted;
+        }
+
+        oldSize = v.size();
+        v.setSize(20);
+        assertEquals("Failed to set size", 20, v.size());
+        for (int i = oldSize; i < v.size(); i++) {
+            assertNull(v.get(i));
+        }
+
+        try {
+            v.setSize(-1);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Excepted
+        }
+	}
+
+	/**
+	 * @tests java.util.Vector#size()
+	 */
+	public void test_size() {
+		// Test for method int java.util.Vector.size()
+		assertEquals("Returned incorrect size", 100, tVector.size());
+
+		final Vector v = new Vector();
+		v.addElement("initial");
+		Thread t1 = new Thread() {
+			public void run() {
+				while (v.size() > 0)
+					;
+				v.addElement("final");
+			}
+		};
+		t1.start();
+		for (int i = 0; i < 10000; i++) {
+			synchronized (v) {
+				v.removeElementAt(0);
+				v.addElement(String.valueOf(i));
+			}
+			int size;
+			if ((size = v.size()) != 1) {
+				String result = "Size is not 1: " + size + " " + v;
+				// terminate the thread
+				v.removeAllElements();
+				fail(result);
+			}
+		}
+		// terminate the thread
+		v.removeElementAt(0);
+	}
+
+	/**
+	 * @tests java.util.Vector#subList(int, int)
+	 */
+	public void test_subListII() {
+		// Test for method java.util.List java.util.Vector.subList(int, int)
+		List sl = tVector.subList(10, 25);
+		assertEquals("Returned sublist of incorrect size", 15, sl.size());
+		for (int i = 10; i < 25; i++)
+			assertTrue("Returned incorrect sublist", sl
+					.contains(tVector.get(i)));
+
+		assertEquals("Not synchronized random access", "java.util.Collections$SynchronizedRandomAccessList", sl.getClass().getName()
+				);
+
+	}
+
+	/**
+	 * @tests java.util.Vector#toArray()
+	 */
+	public void test_toArray() {
+		// Test for method java.lang.Object [] java.util.Vector.toArray()
+		assertTrue("Returned incorrect array", Arrays.equals(objArray, tVector
+				.toArray()));
+	}
+
+	/**
+	 * @tests java.util.Vector#toArray(java.lang.Object[])
+	 */
+	public void test_toArray$Ljava_lang_Object() {
+		// Test for method java.lang.Object []
+		// java.util.Vector.toArray(java.lang.Object [])
+		Object[] o = new Object[1000];
+		Object f = new Object();
+		for (int i = 0; i < o.length; i++)
+			o[i] = f;
+		tVector.toArray(o);
+		assertNull("Failed to set slot to null", o[100]);
+		for (int i = 0; i < tVector.size(); i++)
+			assertTrue("Returned incorrect array", tVector.elementAt(i) == o[i]);
+	}
+
+
+
+    class SubVector<E> extends Vector<E> {
+
+        private static final long serialVersionUID = 1L;
+
+        public SubVector() {
+            super();
+        }
+
+        public synchronized boolean add(E obj) {
+            super.addElement(obj);
+            return true;
+        }
+
+        public synchronized void addElement(E obj) {
+            super.add(obj);
+        }
+
+        /**
+         * @tests java.util.Vector#add(Object)
+         */
+        @SuppressWarnings("nls")
+        public void test_add() {
+            SubVector<String> subvector = new SubVector<String>();
+            subvector.add("foo");
+            subvector.addElement("bar");
+            assertEquals("Expected two elements in vector", 2, subvector.size());
+        }
+
+    }
 
     /**
      * @tests java.util.Vector#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         // Ensure toString works with self-referencing elements.
         Vector<Object> vec = new Vector<Object>(3);
@@ -44,5 +1232,81 @@
         vec.add(new Object());
         vec.add(vec);
         assertNotNull(vec.toString());
+
+		// Test for method java.lang.String java.util.Vector.toString()
+		assertTrue("Incorrect String returned", tVector.toString().equals(
+				vString));
+
+		Vector v = new Vector();
+		v.addElement("one");
+		v.addElement(v);
+		v.addElement("3");
+		// test last element
+		v.addElement(v);
+		String result = v.toString();
+		assertTrue("should contain self ref", result.indexOf("(this") > -1);
+	}
+    
+    public void test_override_size() throws Exception {
+        Vector v = new Vector(); 
+        Vector testv = new MockVector();
+        // though size is overriden, it should passed without exception
+        testv.add(1);
+        testv.add(2);
+        testv.clear();
+        
+        testv.add(1);
+        testv.add(2);
+        v.add(1);
+        v.add(2);
+        // RI's bug here
+        assertTrue(testv.equals(v));
     }
+
+	/**
+	 * @tests java.util.Vector#trimToSize()
+	 */
+	public void test_trimToSize() {
+		// Test for method void java.util.Vector.trimToSize()
+		Vector v = new Vector(10);
+		v.addElement(new Object());
+		v.trimToSize();
+		assertEquals("Failed to trim capacity", 1, v.capacity());
+	}
+
+	protected Vector vectorClone(Vector s) {
+		return (Vector) s.clone();
+	}
+    
+    public class MockVector extends Vector{
+        @Override
+        public synchronized int size() {
+            return 0;
+        }
+        
+        public void removeRange(int start, int end) {
+            super.removeRange(start, end);
+        }
+    }
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		for (int i = 0; i < 100; i++) {
+			tVector.addElement("Test " + i);
+		}
+		objArray = new Object[100];
+		for (int i = 0; i < 100; i++) {
+			objArray[i] = "Test " + i;
+		}
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/WeakHashMapTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/WeakHashMapTest.java
index 9521641..02f0409 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/util/WeakHashMapTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/util/WeakHashMapTest.java
@@ -1,51 +1,163 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  */
 
 package org.apache.harmony.luni.tests.java.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
+import java.util.AbstractMap;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.WeakHashMap;
 
-@TestTargetClass(WeakHashMap.class) 
-public class WeakHashMapTest extends TestCase {
+import tests.support.Support_MapTest2;
 
+public class WeakHashMapTest extends junit.framework.TestCase {
+	class MockMap extends AbstractMap {
+		public Set entrySet() {
+			return null;
+		}
+		public int size(){
+			return 0;
+		}
+	}
+
+	Object[] keyArray = new Object[100];
+
+	Object[] valueArray = new Object[100];
+
+	WeakHashMap whm;
+	
     Object[] KEY_ARRAY;
 
     Object[] VALUE_ARRAY;
 
+	/**
+	 * @tests java.util.WeakHashMap#WeakHashMap()
+	 */
+	public void test_Constructor() {
+		// Test for method java.util.WeakHashMap()
+		new Support_MapTest2(new WeakHashMap()).runTest();
+
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		for (int i = 0; i < 100; i++)
+			assertTrue("Incorrect value retrieved",
+					whm.get(keyArray[i]) == valueArray[i]);
+
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#WeakHashMap(int)
+	 */
+	public void test_ConstructorI() {
+		// Test for method java.util.WeakHashMap(int)
+		whm = new WeakHashMap(50);
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		for (int i = 0; i < 100; i++)
+			assertTrue("Incorrect value retrieved",
+					whm.get(keyArray[i]) == valueArray[i]);
+
+		WeakHashMap empty = new WeakHashMap(0);
+		assertNull("Empty weakhashmap access", empty.get("nothing"));
+		empty.put("something", "here");
+		assertTrue("cannot get element", empty.get("something") == "here");
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#WeakHashMap(int, float)
+	 */
+	public void test_ConstructorIF() {
+		// Test for method java.util.WeakHashMap(int, float)
+		whm = new WeakHashMap(50, 0.5f);
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		for (int i = 0; i < 100; i++)
+			assertTrue("Incorrect value retrieved",
+					whm.get(keyArray[i]) == valueArray[i]);
+
+		WeakHashMap empty = new WeakHashMap(0, 0.75f);
+		assertNull("Empty hashtable access", empty.get("nothing"));
+		empty.put("something", "here");
+		assertTrue("cannot get element", empty.get("something") == "here");
+	}
+	
+	/**
+	 * @tests java.util.WeakHashMap#WeakHashMap(java.util.Map)
+	 */
+	public void test_ConstructorLjava_util_Map() {
+        Map mockMap = new MockMap();
+        WeakHashMap map = new WeakHashMap(mockMap);
+        assertEquals("Size should be 0", 0, map.size());
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#clear()
+	 */
+	public void test_clear() {
+		// Test for method boolean java.util.WeakHashMap.clear()
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		whm.clear();
+		assertTrue("Cleared map should be empty", whm.isEmpty());
+		for (int i = 0; i < 100; i++)
+			assertNull("Cleared map should only return null", whm
+					.get(keyArray[i]));
+
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#containsKey(java.lang.Object)
+	 */
+	public void test_containsKeyLjava_lang_Object() {
+		// Test for method boolean java.util.WeakHashMap.containsKey()
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		for (int i = 0; i < 100; i++)
+			assertTrue("Should contain referenced key", whm
+					.containsKey(keyArray[i]));
+		keyArray[25] = null;
+		keyArray[50] = null;
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#containsValue(java.lang.Object)
+	 */
+	public void test_containsValueLjava_lang_Object() {
+		// Test for method boolean java.util.WeakHashMap.containsValue()
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		for (int i = 0; i < 100; i++)
+			assertTrue("Should contain referenced value", whm
+					.containsValue(valueArray[i]));
+		keyArray[25] = null;
+		keyArray[50] = null;
+	}
+
     /**
      * @tests java.util.WeakHashMap#entrySet()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "entrySet",
-        args = {}
-    )
     public void test_entrySet() {
         WeakHashMap<Object, Object> weakMap = new WeakHashMap<Object, Object>();
         KEY_ARRAY = new Object[100];
@@ -131,4 +243,240 @@
         assertTrue("Assert 8:  iterator not empty", !entrySet.iterator()
                 .hasNext());
     }
+    
+	/**
+	 * @tests java.util.WeakHashMap#entrySet()
+	 */
+	public void test_entrySet_2() {
+		// Test for method java.util.Set java.util.WeakHashMap.entrySet()
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+		List keys = Arrays.asList(keyArray);
+		List values = Arrays.asList(valueArray);
+		Set entrySet = whm.entrySet();
+		assertTrue("Incorrect number of entries returned--wanted 100, got: "
+				+ entrySet.size(), entrySet.size() == 100);
+		Iterator it = entrySet.iterator();
+		while (it.hasNext()) {
+			Map.Entry entry = (Map.Entry) it.next();
+			assertTrue("Invalid map entry returned--bad key", keys
+					.contains(entry.getKey()));
+			assertTrue("Invalid map entry returned--bad key", values
+					.contains(entry.getValue()));
+		}
+		keys = null;
+		values = null;
+		keyArray[50] = null;
+
+		int count = 0;
+		do {
+			System.gc();
+			System.gc();
+			Runtime.getRuntime().runFinalization();
+			count++;
+		} while (count <= 5 && entrySet.size() == 100);
+
+		assertTrue(
+				"Incorrect number of entries returned after gc--wanted 99, got: "
+						+ entrySet.size(), entrySet.size() == 99);
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#get(java.lang.Object)
+	 */
+	public void test_getLjava_lang_Object() {
+		// Test for method java.lang.Object
+		// java.util.WeakHashMap.get(java.lang.Object)
+		assertTrue("Used to test", true);
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#isEmpty()
+	 */
+	public void test_isEmpty() {
+		// Test for method boolean java.util.WeakHashMap.isEmpty()
+		whm = new WeakHashMap();
+		assertTrue("New map should be empty", whm.isEmpty());
+		Object myObject = new Object();
+		whm.put(myObject, myObject);
+		assertTrue("Map should not be empty", !whm.isEmpty());
+		whm.remove(myObject);
+		assertTrue("Map with elements removed should be empty", whm.isEmpty());
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#put(java.lang.Object, java.lang.Object)
+	 */
+	public void test_putLjava_lang_ObjectLjava_lang_Object() {
+		// Test for method java.lang.Object
+		// java.util.WeakHashMap.put(java.lang.Object, java.lang.Object)
+		WeakHashMap map = new WeakHashMap();
+		map.put(null, "value"); // add null key
+		System.gc();
+		System.runFinalization();
+		map.remove("nothing"); // Cause objects in queue to be removed
+		assertEquals("null key was removed", 1, map.size());
+	}
+    
+    /**
+     * @tests java.util.WeakHashMap#putAll(java.util.Map)
+     */
+    public void test_putAllLjava_util_Map() {
+        Map mockMap=new MockMap();
+        WeakHashMap map = new WeakHashMap();
+        map.putAll(mockMap);
+        assertEquals("Size should be 0", 0, map.size());
+    }
+
+	/**
+	 * @tests java.util.WeakHashMap#remove(java.lang.Object)
+	 */
+	public void test_removeLjava_lang_Object() {
+		// Test for method java.lang.Object
+		// java.util.WeakHashMap.remove(java.lang.Object)
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+
+		assertTrue("Remove returned incorrect value",
+				whm.remove(keyArray[25]) == valueArray[25]);
+		assertNull("Remove returned incorrect value",
+				whm.remove(keyArray[25]));
+		assertEquals("Size should be 99 after remove", 99, whm.size());
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#size()
+	 */
+	public void test_size() {
+		// Test for method int java.util.WeakHashMap.size()
+		assertTrue("Used to test", true);
+	}
+
+	/**
+	 * @tests java.util.WeakHashMap#keySet()
+	 */
+	public void test_keySet() {
+		// Test for method java.util.Set java.util.WeakHashMap.keySet()
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+
+		List keys = Arrays.asList(keyArray);
+		List values = Arrays.asList(valueArray);
+
+		Set keySet = whm.keySet();
+		assertEquals("Incorrect number of keys returned,", 100, keySet.size());
+		Iterator it = keySet.iterator();
+		while (it.hasNext()) {
+			Object key = it.next();
+			assertTrue("Invalid map entry returned--bad key", keys
+					.contains(key));
+		}
+		keys = null;
+		values = null;
+		keyArray[50] = null;
+
+		int count = 0;
+		do {
+			System.gc();
+			System.gc();
+			Runtime.getRuntime().runFinalization();
+			count++;
+		} while (count <= 5 && keySet.size() == 100);
+
+		assertEquals("Incorrect number of keys returned after gc,", 99, keySet
+				.size());
+	}
+
+    /**
+     * Regression test for HARMONY-3883
+     * @tests java.util.WeakHashMap#keySet()
+     */
+    public void test_keySet_hasNext() {
+        WeakHashMap map = new WeakHashMap();
+        ConstantHashClass cl = new ConstantHashClass(2);
+        map.put(new ConstantHashClass(1), null);
+        map.put(cl, null);
+        map.put(new ConstantHashClass(3), null);
+        Iterator iter = map.keySet().iterator();
+        iter.next();
+        iter.next();
+        System.gc();
+        assertFalse("Wrong hasNext() value", iter.hasNext());
+    }
+
+    static class ConstantHashClass {
+        private int id = 0;
+
+        public ConstantHashClass(int id) {
+            this.id = id;
+        }
+
+        public int hashCode() {
+            return 0;
+        }
+
+        public String toString() {
+            return "ConstantHashClass[id=" + id + "]";
+        }
+    }
+
+
+	/**
+	 * @tests java.util.WeakHashMap#values()
+	 */
+	public void test_values() {
+		// Test for method java.util.Set java.util.WeakHashMap.values()
+		whm = new WeakHashMap();
+		for (int i = 0; i < 100; i++)
+			whm.put(keyArray[i], valueArray[i]);
+
+		List keys = Arrays.asList(keyArray);
+		List values = Arrays.asList(valueArray);
+
+		Collection valuesCollection = whm.values();
+		assertEquals("Incorrect number of keys returned,", 100,
+				valuesCollection.size());
+		Iterator it = valuesCollection.iterator();
+		while (it.hasNext()) {
+			Object value = it.next();
+			assertTrue("Invalid map entry returned--bad value", values
+					.contains(value));
+		}
+		keys = null;
+		values = null;
+		keyArray[50] = null;
+
+		int count = 0;
+		do {
+			System.gc();
+			System.gc();
+			Runtime.getRuntime().runFinalization();
+			count++;
+		} while (count <= 5 && valuesCollection.size() == 100);
+
+		assertEquals("Incorrect number of keys returned after gc,", 99,
+				valuesCollection.size());
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		for (int i = 0; i < 100; i++) {
+			keyArray[i] = new Object();
+			valueArray[i] = new Object();
+		}
+
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+	}
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/util/Base64Test.java b/luni/src/test/java/org/apache/harmony/luni/tests/util/Base64Test.java
index 1795745..70318ed 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/util/Base64Test.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/util/Base64Test.java
@@ -15,12 +15,7 @@
  *  limitations under the License.
  */
 
-package org.apache.harmony.luni.tests.util; 
-
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass; 
+package org.apache.harmony.luni.tests.util;
 
 import org.apache.harmony.luni.util.Base64;
 
@@ -30,19 +25,12 @@
 
 /**
  * Base64 encoder/decoder test.
- */ 
-@TestTargetClass(Base64.class)
+ */
 public class Base64Test extends TestCase {
 
     /**
      * Checks the result on empty parameter.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "decode",
-        args = {byte[].class}
-    )    
     public static void testDecodeEmpty() throws Exception {
         // Regression for HARMONY-1513
         byte[] result = Base64.decode(new byte[0]);
@@ -53,9 +41,5 @@
     public static Test suite() {
         return new TestSuite(Base64Test.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/util/NYITest.java b/luni/src/test/java/org/apache/harmony/luni/tests/util/NYITest.java
index b30501e..2c8d450 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/util/NYITest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/util/NYITest.java
@@ -17,11 +17,6 @@
 
 package org.apache.harmony.luni.tests.util;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
@@ -33,16 +28,8 @@
 /**
  * Testing the NYI framework code.
  */
-// well this should be the past now.
-@TestTargetClass(NotImplementedException.class)
 public class NYITest extends TestCase {
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NotImplementedException",
-        args = {java.io.PrintStream.class}
-    )      
     public void testNYI() throws UnsupportedEncodingException {
         ByteArrayOutputStream bos = new ByteArrayOutputStream(400);
         PrintStream stream = new PrintStream(bos, true, "UTF-8");
diff --git a/luni/src/test/java/tests/AllTests.java b/luni/src/test/java/tests/AllTests.java
index 864a3ed..fdea653 100644
--- a/luni/src/test/java/tests/AllTests.java
+++ b/luni/src/test/java/tests/AllTests.java
@@ -30,7 +30,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         
         // Harmony-written test suites (often with Android tests added in).
         suite.addTest(tests.annotation.AllTests.suite());
@@ -65,6 +65,8 @@
         suite.addTest(java.text.AllTests.suite());
         suite.addTest(java.util.AllTests.suite());
         suite.addTest(javax.xml.parsers.AllTests.suite());
+        // disable until hangs are resolved in our JSSE implementation
+        // suite.addTest(javax.net.ssl.AllTests.suite());
         suite.addTest(org.apache.harmony.luni.platform.AllTests.suite());
         suite.addTest(org.json.AllTests.suite());
         suite.addTest(tests.api.org.apache.harmony.kernel.dalvik.AllTests.suite());
diff --git a/luni/src/test/java/tests/TestSuiteFactory.java b/luni/src/test/java/tests/TestSuiteFactory.java
deleted file mode 100644
index 98f998c..0000000
--- a/luni/src/test/java/tests/TestSuiteFactory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests;
-
-import junit.framework.TestSuite;
-
-/**
- * This is about to go away...
- */
-public class TestSuiteFactory {
-    
-    public static TestSuite createTestSuite(String name) {
-        return new TestSuite(name);
-    }
-
-    public static TestSuite createTestSuite() {
-        return new TestSuite();    
-    }
-    
-}
diff --git a/luni/src/test/java/tests/api/java/io/AllTests.java b/luni/src/test/java/tests/api/java/io/AllTests.java
index 2747ab2..0bc062d 100644
--- a/luni/src/test/java/tests/api/java/io/AllTests.java
+++ b/luni/src/test/java/tests/api/java/io/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.java.io;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.java.io;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(BufferedInputStreamTest.class);
diff --git a/luni/src/test/java/tests/api/java/io/FileTest.java b/luni/src/test/java/tests/api/java/io/FileTest.java
index adcaccd..573c923 100644
--- a/luni/src/test/java/tests/api/java/io/FileTest.java
+++ b/luni/src/test/java/tests/api/java/io/FileTest.java
@@ -2154,9 +2154,6 @@
                 args = {}
         )
     })
-    @KnownFailure("canWrite() returns true even when a file is marked " +
-            "read-only (Test 2). It is also possible to open this file " +
-            "for writing (Test 3).")
     public void test_setReadOnly() {
         // Test for method java.io.File.setReadOnly()
 
@@ -2441,6 +2438,7 @@
     )
     @AndroidOnly("This test only runs on Android because it instantiates " +
             "a second Dalvik VM.")
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void test_deleteOnExit() throws IOException, InterruptedException {
         String cts = System.getProperty("java.io.tmpdir");
         File dir = new File(cts + "/hello");
diff --git a/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java b/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java
index ea1b7c3..825bb0b 100644
--- a/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java
+++ b/luni/src/test/java/tests/api/java/io/ObjectStreamClassTest.java
@@ -17,17 +17,21 @@
 
 package tests.api.java.io;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
+import java.io.File;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 import java.io.ObjectStreamClass;
 import java.io.ObjectStreamField;
 import java.io.Serializable;
+import java.net.URL;                                                                                                                 
+import java.net.URLClassLoader; 
+import java.lang.reflect.Proxy;
 
-@TestTargetClass(ObjectStreamClass.class) 
-public class ObjectStreamClassTest extends junit.framework.TestCase {
+import junit.framework.TestCase;
+
+public class ObjectStreamClassTest extends TestCase {
 
     static class DummyClass implements Serializable {
         private static final long serialVersionUID = 999999999999999L;
@@ -36,44 +40,29 @@
 
         int ham = 9999;
 
-        public static long getUID() {
-            return serialVersionUID;
-        }
-    }
-
+		public static long getUID() {
+			return serialVersionUID;
+		}
+	}
+    
     /**
      * @tests java.io.ObjectStreamClass#forClass()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "forClass",
-        args = {}
-    )      
     public void test_forClass() {
-        // Test for method java.lang.Class java.io.ObjectStreamClass.forClass()
         // Need to test during serialization to be sure an instance is
         // returned
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
-        assertTrue("forClass returned an object: " + osc.forClass(), osc
-                .forClass().equals(DummyClass.class));
+        assertEquals("forClass returned an object: " + osc.forClass(),
+                DummyClass.class, osc.forClass()); 
     }
 
     /**
      * @tests java.io.ObjectStreamClass#getField(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getField",
-        args = {java.lang.String.class}
-    )     
     public void test_getFieldLjava_lang_String() {
-        // Test for method java.io.ObjectStreamField
-        // java.io.ObjectStreamClass.getField(java.lang.String)
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
-        assertEquals("getField did not return correct field", 'J', osc.getField("bam")
-                .getTypeCode());
+        assertEquals("getField did not return correct field", 'J', osc
+                .getField("bam").getTypeCode());
         assertNull("getField did not null for non-existent field", osc
                 .getField("wham"));
     }
@@ -81,15 +70,7 @@
     /**
      * @tests java.io.ObjectStreamClass#getFields()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getFields",
-        args = {}
-    )     
     public void test_getFields() {
-        // Test for method java.io.ObjectStreamField []
-        // java.io.ObjectStreamClass.getFields()
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
         ObjectStreamField[] osfArray = osc.getFields();
         assertTrue(
@@ -100,31 +81,18 @@
     /**
      * @tests java.io.ObjectStreamClass#getName()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getName",
-        args = {}
-    )    
     public void test_getName() {
-        // Test for method java.lang.String java.io.ObjectStreamClass.getName()
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
-        assertTrue("getName returned incorrect name: " + osc.getName(), osc
-                .getName().equals(
-                        "tests.api.java.io.ObjectStreamClassTest$DummyClass"));
+        assertEquals(
+                "getName returned incorrect name: " + osc.getName(),
+                "tests.api.java.io.ObjectStreamClassTest$DummyClass", // android-changed
+                osc.getName());
     }
 
     /**
      * @tests java.io.ObjectStreamClass#getSerialVersionUID()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getSerialVersionUID",
-        args = {}
-    )    
     public void test_getSerialVersionUID() {
-        // Test for method long java.io.ObjectStreamClass.getSerialVersionUID()
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
         assertTrue("getSerialversionUID returned incorrect uid: "
                 + osc.getSerialVersionUID() + " instead of "
@@ -132,114 +100,164 @@
                 .getUID());
     }
 
+    static class SyntheticTest implements Serializable {
+        private int i;
+
+        private class X implements Serializable {
+            public int get() {
+                return i;
+            }
+        }
+
+        public X foo() {
+            return new X();
+        }
+    }
+
+    /**
+     * @tests java.io.ObjectStreamClass#getSerialVersionUID()
+     */
+    public void test_getSerialVersionUID_inner_private_class() {
+        ObjectStreamClass osc1 = ObjectStreamClass.lookup(SyntheticTest.class);
+        assertEquals("SyntheticTest unexpected UID: "
+                + osc1.getSerialVersionUID(), -7784078941584535183L, osc1
+                .getSerialVersionUID());
+
+        ObjectStreamClass osc2 = ObjectStreamClass
+                .lookup(SyntheticTest.X.class);
+        assertEquals("SyntheticTest.X unexpected UID: "
+                + osc2.getSerialVersionUID(), -7703000075736397332L, osc2
+                .getSerialVersionUID());
+    }
+
+    /**
+     * @tests java.io.ObjectStreamClass#getSerialVersionUID()
+     */
+    public void test_getSerialVersionUID_classloader() throws Exception {
+        File file = new File(
+                "resources/org/apache/harmony/luni/tests/ObjectStreamClassTest.jar");
+        ClassLoader loader = new URLClassLoader(new URL[] { file.toURL() },
+                null);
+        Class cl1 = Class.forName("Test1$TestVarArgs", false, loader);
+        ObjectStreamClass osc1 = ObjectStreamClass.lookup(cl1);
+        assertEquals("Test1$TestVarArgs unexpected UID: "
+                + osc1.getSerialVersionUID(), -6051121963037986215L, osc1
+                .getSerialVersionUID());
+
+        Class cl2 = Class.forName("Test1$TestBridge", false, loader);
+        ObjectStreamClass osc2 = ObjectStreamClass.lookup(cl2);
+        assertEquals("Test1$TestBridge unexpected UID: "
+                + osc2.getSerialVersionUID(), 568585976855071180L, osc2
+                .getSerialVersionUID());
+    }
+
     /**
      * @tests java.io.ObjectStreamClass#lookup(java.lang.Class)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "lookup",
-        args = {java.lang.Class.class}
-    )        
     public void test_lookupLjava_lang_Class() {
-        // Test for method java.io.ObjectStreamClass
-        // java.io.ObjectStreamClass.lookup(java.lang.Class)
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
-        assertTrue("lookup returned wrong class: " + osc.getName(), osc
-                .getName().equals(
-                        "tests.api.java.io.ObjectStreamClassTest$DummyClass"));
+        assertEquals(
+                "lookup returned wrong class: " + osc.getName(),
+                "tests.api.java.io.ObjectStreamClassTest$DummyClass", // android-changed
+                osc.getName());
     }
 
     /**
      * @tests java.io.ObjectStreamClass#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )    
     public void test_toString() {
-        // Test for method java.lang.String java.io.ObjectStreamClass.toString()
         ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
         String oscString = osc.toString();
+
         // The previous test was more specific than the spec so it was replaced
         // with the test below
         assertTrue("toString returned incorrect string: " + osc.toString(),
                 oscString.indexOf("serialVersionUID") >= 0
                         && oscString.indexOf("999999999999999L") >= 0);
-        ;
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "lookup",
-        args = {java.lang.Class.class}
-    )    
+
     public void testSerialization() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(ObjectStreamClass.class);
+        ObjectStreamClass osc = ObjectStreamClass
+                .lookup(ObjectStreamClass.class);
         assertEquals(0, osc.getFields().length);
     }
+
+    public void test_specialTypes() {
+        Class<?> proxyClass = Proxy.getProxyClass(this.getClass()
+                .getClassLoader(), new Class[] { Runnable.class });
+
+        ObjectStreamClass proxyStreamClass = ObjectStreamClass
+                .lookup(proxyClass);
+
+        assertEquals("Proxy classes should have zero serialVersionUID", 0,
+                proxyStreamClass.getSerialVersionUID());
+        ObjectStreamField[] proxyFields = proxyStreamClass.getFields();
+        assertEquals("Proxy classes should have no serialized fields", 0,
+                proxyFields.length);
+
+        ObjectStreamClass enumStreamClass = ObjectStreamClass
+                .lookup(Thread.State.class);
+
+        assertEquals("Enum classes should have zero serialVersionUID", 0,
+                enumStreamClass.getSerialVersionUID());
+        ObjectStreamField[] enumFields = enumStreamClass.getFields();
+        assertEquals("Enum classes should have no serialized fields", 0,
+                enumFields.length);
+    }
+    
+        /**
+     * @since 1.6 
+     */
+    static class NonSerialzableClass {
+        private static final long serialVersionUID = 1l;
+        public static long getUID() {
+            return serialVersionUID;
+        }
+    }
     
     /**
-     * Sets up the fixture, for example, open a network connection. This method
-     * is called before a test is executed.
+     * @since 1.6
      */
-    protected void setUp() {
-    }
+    static class ExternalizableClass implements Externalizable {
 
-    /**
-     * Tears down the fixture, for example, close a network connection. This
-     * method is called after a test is executed.
-     */
-    protected void tearDown() {
-    }
+        private static final long serialVersionUID = -4285635779249689129L;
 
-// BEGIN android-added
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies serialization.",
-        method = "!Serialization",
-        args = {}
-    )
-    public void testFooSerialVersionUid() {
-        assertEquals(-5887964677443030867L, Foo.serialVersionUID());
-    }
-
-    /**
-     * An arbitrary class which deliberately tickles various factors affecting
-     * serialVersionUID calculation.
-     */
-    static abstract class Foo implements Cloneable, Serializable {
-
-        /** All fields except "private static|transient", which these aren't. */
-        private final String name = "foo";
-        static final long now;
-
-        /** Presence of static initializer has an affect. */
-        static {
-            now = System.currentTimeMillis();
+        public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
+            throw new ClassNotFoundException();
         }
 
-        /** Non-private constructors. */
-        Foo() {}
-        protected Foo(int ignored) {}
-
-        /** Non-private methods. */
-        synchronized static int foo() { return 0; }
-        static int bar() { return 0; }
-        abstract void tee();
-        protected native synchronized boolean bob();
-        protected synchronized void tim() {}
-
-        /** Calculates Foo's default serialVersionUID. */
-        static long serialVersionUID() {
-            return ObjectStreamClass.lookup(Foo.class).getSerialVersionUID();
+        public void writeExternal(ObjectOutput output) throws IOException {
+            throw new IOException();
         }
-    }
+        
+	}
+	
+    /**
+     * @tests java.io.ObjectStreamClass#lookupAny(java.lang.Class)
+     * @since 1.6
+     */
+    public void test_lookupAnyLjava_lang_Class() {
+        // Test for method java.io.ObjectStreamClass
+        // java.io.ObjectStreamClass.lookupAny(java.lang.Class)
+        ObjectStreamClass osc = ObjectStreamClass.lookupAny(DummyClass.class);
+        assertEquals("lookup returned wrong class: " + osc.getName(),
+                "tests.api.java.io.ObjectStreamClassTest$DummyClass", osc  // android-changed
+                        .getName());
+        
+        osc = ObjectStreamClass.lookupAny(NonSerialzableClass.class);
+        assertEquals("lookup returned wrong class: " + osc.getName(),
+                "tests.api.java.io.ObjectStreamClassTest$NonSerialzableClass", // android-changed
+                osc.getName());
+        
+        osc = ObjectStreamClass.lookupAny(ExternalizableClass.class);        
+        assertEquals("lookup returned wrong class: " + osc.getName(),
+                "tests.api.java.io.ObjectStreamClassTest$ExternalizableClass", // android-changed
+                osc.getName());
 
-    public static void main(String[] args) {
-        System.out.println(Foo.serialVersionUID());
+        osc = ObjectStreamClass.lookup(NonSerialzableClass.class);
+        assertNull(osc);
+        
     }
-// END android-added
+    
+    
 }
diff --git a/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java b/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
index c6dd60f..a5dcc34 100644
--- a/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
+++ b/luni/src/test/java/tests/api/java/io/PipedInputStreamTest.java
@@ -20,123 +20,94 @@
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-@TestTargetClass(PipedInputStream.class) 
 public class PipedInputStreamTest extends junit.framework.TestCase {
 
     private final int BUFFER_SIZE = 1024;
 
-    static class PWriter implements Runnable {
-        PipedOutputStream pos;
+	static class PWriter implements Runnable {
+		PipedOutputStream pos;
 
-        public byte bytes[];
+		public byte bytes[];
 
-        public void run() {
-            try {
-                pos.write(bytes);   
-                synchronized (this) {
-                    notify();
-                }
-            } catch (Exception e) {
-                e.printStackTrace(System.out);
-                System.out.println("Error while running the writer thread.");
-            }
-        }
+		public void run() {
+			try {
+				pos.write(bytes);
+				synchronized (this) {
+					notify();
+				}
+			} catch (IOException e) {
+				e.printStackTrace(System.out);
+				System.out.println("Could not write bytes");
+			}
+		}
 
-        public PWriter(PipedOutputStream pout, int nbytes) {
-            pos = pout;
-            bytes = new byte[nbytes];
-            for (int i = 0; i < bytes.length; i++)
-                bytes[i] = (byte) (System.currentTimeMillis() % 9);
-        }
-    }
+		public PWriter(PipedOutputStream pout, int nbytes) {
+			pos = pout;
+			bytes = new byte[nbytes];
+			for (int i = 0; i < bytes.length; i++) {
+				bytes[i] = (byte) (System.currentTimeMillis() % 9);
+		    }
+		}
+	}
 
-    static class PWriter2 implements Runnable {
-        PipedOutputStream pos;
+	Thread t;
 
-        public boolean keepRunning = true;
+	PWriter pw;
 
-        public void run() {
-            try {
-                pos.write(42);
-                pos.close();
-                while (keepRunning) {
-                    Thread.sleep(1000);
-                }
-            } catch (Exception e) {
-                e.printStackTrace(System.out);
-                System.out.println("Error while running the writer thread.");
-            }
-        }
+	PipedInputStream pis;
 
-        public PWriter2(PipedOutputStream pout) {
-            pos = pout;
-        }
-    }
+	PipedOutputStream pos;
 
-    Thread t;
+	/**
+	 * @tests java.io.PipedInputStream#PipedInputStream()
+	 */
+	public void test_Constructor() {
+		// Test for method java.io.PipedInputStream()
+		// Used in tests
+	}
 
-    PWriter pw;
-
-    PipedInputStream pis;
-
-    PipedOutputStream pos;
-
-    /**
-     * @tests java.io.PipedInputStream#PipedInputStream()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PipedInputStream",
-        args = {}
-    )
-    public void test_Constructor() throws IOException {
-        pis = new PipedInputStream();
-        assertEquals("There should not be any bytes available. ", 0, pis.available());
-        pis.close();
-    }
-
-    /**
-     * @tests java.io.PipedInputStream#PipedInputStream(java.io.PipedOutputStream)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PipedInputStream",
-        args = {java.io.PipedOutputStream.class}
-    )
-    public void test_ConstructorLjava_io_PipedOutputStream() throws IOException {
-        pos = new PipedOutputStream(new PipedInputStream());
-        
-        try {
-            pis = new PipedInputStream(pos);
-            fail("IOException expected since the output stream is already connected.");
-        } catch (IOException e) {
-            // Expected.
-        }
-        
+	/**
+	 * @tests java.io.PipedInputStream#PipedInputStream(java.io.PipedOutputStream)
+	 */
+	public void test_ConstructorLjava_io_PipedOutputStream() throws Exception {
+        // Test for method java.io.PipedInputStream(java.io.PipedOutputStream)
         pis = new PipedInputStream(new PipedOutputStream());
-        assertEquals("There should not be any bytes available. ", 0, pis.available());
-        
-        pis.close();
-        pos.close();
+        pis.available();
+    }
+
+
+    /**
+     * @test java.io.PipedInputStream#read()
+     */
+    public void test_readException() throws IOException {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
+
+        try {
+            pis.connect(pos);
+            t = new Thread(pw = new PWriter(pos, 1000));
+            t.start();
+            assertTrue(t.isAlive());
+            while (true) {
+                pis.read();
+                t.interrupt();
+            }
+        } catch (IOException e) {
+            if (!e.getMessage().contains("Write end dead") && !e.getMessage().contains("Pipe broken")) { // android-changed
+                throw e;
+            }
+        } finally {
+            try {
+                pis.close();
+                pos.close();
+            } catch (IOException ee) {}
+        }
     }
 
     /**
      * @tests java.io.PipedInputStream#available()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "No IOException checking because it is never thrown in the source code.",
-        method = "available",
-        args = {}
-    )
     public void test_available() throws Exception {
-        // Test for method int java.io.PipedInputStream.available()
         pis = new PipedInputStream();
         pos = new PipedOutputStream();
 
@@ -147,62 +118,48 @@
         synchronized (pw) {
             pw.wait(10000);
         }
-        assertEquals("Test 1: Incorrect number of bytes available. ",
-                     1000, pis.available());
+        assertTrue("Available returned incorrect number of bytes: "
+                + pis.available(), pis.available() == 1000);
 
         PipedInputStream pin = new PipedInputStream();
         PipedOutputStream pout = new PipedOutputStream(pin);
         // Writing another byte would cause the write to wait
         // for a read before returning
-        for (int i = 0; i < BUFFER_SIZE; i++)
+        for (int i = 0; i < BUFFER_SIZE; i++) {
             pout.write(i);
-        assertEquals("Test 2: Incorrect number of bytes available. ", 
-                     BUFFER_SIZE, pin.available());
+        }
+        assertEquals("Incorrect available count", BUFFER_SIZE , pin.available());
     }
 
-    /**
-     * @tests java.io.PipedInputStream#close()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "No IOException checking because it is never thrown in the source code.",
-        method = "close",
-        args = {}
-    )
-    public void test_close() throws IOException {
-        // Test for method void java.io.PipedInputStream.close()
-        pis = new PipedInputStream();
-        pos = new PipedOutputStream();
+	/**
+	 * @tests java.io.PipedInputStream#close()
+	 */
+	public void test_close() throws IOException {
+		// Test for method void java.io.PipedInputStream.close()
+		pis = new PipedInputStream();
+		pos = new PipedOutputStream();
         pis.connect(pos);
         pis.close();
-        try {
-            pos.write((byte) 127);
-            fail("IOException expected.");
-        } catch (IOException e) {
-            // The spec for PipedInput says an exception should be thrown if
-            // a write is attempted to a closed input. The PipedOuput spec
-            // indicates that an exception should be thrown only when the
-            // piped input thread is terminated without closing
-            return;
-        }
-    }
+		try {
+			pos.write((byte) 127);
+            fail("Failed to throw expected exception");
+		} catch (IOException e) {
+			// The spec for PipedInput saya an exception should be thrown if
+			// a write is attempted to a closed input. The PipedOuput spec
+			// indicates that an exception should be thrown only when the
+			// piped input thread is terminated without closing
+			return;
+		}
+	}
 
-    /**
-     * @tests java.io.PipedInputStream#connect(java.io.PipedOutputStream)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "connect",
-        args = {java.io.PipedOutputStream.class}
-    )
-    public void test_connectLjava_io_PipedOutputStream() throws Exception {
-        // Test for method void
-        // java.io.PipedInputStream.connect(java.io.PipedOutputStream)
+	/**
+	 * @tests java.io.PipedInputStream#connect(java.io.PipedOutputStream)
+	 */
+	public void test_connectLjava_io_PipedOutputStream() throws Exception {
         pis = new PipedInputStream();
         pos = new PipedOutputStream();
-        assertEquals("Test 1: Not-connected pipe returned more than zero available bytes. ", 
-                     0, pis.available());
+        assertEquals("Non-conected pipe returned non-zero available bytes", 0,
+                pis.available());
 
         pis.connect(pos);
         t = new Thread(pw = new PWriter(pos, 1000));
@@ -211,142 +168,50 @@
         synchronized (pw) {
             pw.wait(10000);
         }
-        assertEquals("Test 2: Unexpected number of bytes available. ", 
-                     1000, pis.available());
-
-        try {
-            pis.connect(pos);
-            fail("Test 3: IOException expected when reconnecting the pipe.");
-        } catch (IOException e) {
-            // Expected.
-        }
-        
-        pis.close();
-        pos.close();
+        assertEquals("Available returned incorrect number of bytes", 1000, pis
+                .available());
     }
 
-    /**
-     * @tests java.io.PipedInputStream#read()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "read",
-        args = {}
-    )
-    public void test_read() throws Exception {
+	/**
+	 * @tests java.io.PipedInputStream#read()
+	 */
+	public void test_read() throws Exception {
         pis = new PipedInputStream();
         pos = new PipedOutputStream();
 
-        try {
-            pis.read();
-            fail("Test 1: IOException expected since the stream is not connected.");
-        } catch (IOException e) {
-            // Expected.
-        }
-        
         pis.connect(pos);
-        t = new Thread(pw = new PWriter(pos, 100));
+        t = new Thread(pw = new PWriter(pos, 1000));
         t.start();
 
         synchronized (pw) {
-            pw.wait(5000);
+            pw.wait(10000);
         }
-        assertEquals("Test 2: Unexpected number of bytes available. ", 
-                     100, pis.available());
-        
-        for (int i = 0; i < 100; i++) {
-            assertEquals("Test 3: read() returned incorrect byte. ", 
-                         pw.bytes[i], (byte) pis.read());
-        }
-
-        try {
-            pis.read();
-            fail("Test 4: IOException expected since the thread that has " +
-                 "written to the pipe is no longer alive.");
-        } catch (IOException e) {
-            // Expected.
-        }
-
-        pis.close();
-        try {
-            pis.read();
-            fail("Test 5: IOException expected since the stream is closed.");
-        } catch (IOException e) {
-            // Expected.
-        }
+        assertEquals("Available returned incorrect number of bytes", 1000, pis
+                .available());
+        assertEquals("read returned incorrect byte", pw.bytes[0], (byte) pis
+                .read());
     }
 
-    /**
-     * @tests java.io.PipedInputStream#read()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks that read returns -1 if the PipedOutputStream connected to this PipedInputStream is closed.",
-        method = "read",
-        args = {}
-    )
-    public void test_read_2() throws Exception {
-        Thread writerThread;
-        PWriter2 pwriter;
-        
-        pos = new PipedOutputStream(); 
-        pis = new PipedInputStream(pos);
-        writerThread = new Thread(pwriter = new PWriter2(pos));
-        writerThread.start();
+	/**
+	 * @tests java.io.PipedInputStream#read(byte[], int, int)
+	 */
+	public void test_read$BII() throws Exception {
+        pis = new PipedInputStream();
+        pos = new PipedOutputStream();
 
-        synchronized (pwriter) {
-            pwriter.wait(5000);
-        }
-        pis.read();
-        assertEquals("Test 1: No more data indication expected. ", -1, pis.read());
-        pwriter.keepRunning = false;
-        
-        pis.close();
-    }
+        pis.connect(pos);
+        t = new Thread(pw = new PWriter(pos, 1000));
+        t.start();
 
-    /**
-     * @tests java.io.PipedInputStream#read(byte[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Tests read from unconnected, connected and closed pipe.",
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
-    public void test_read$BII() throws Exception {
         byte[] buf = new byte[400];
-        pis = new PipedInputStream();
-        pos = new PipedOutputStream();
-
-        try {
-            pis.read(buf, 0, 10);
-            fail("Test 1: IOException expected since the stream is not connected.");
-        } catch (IOException e) {
-            // Expected.
-        }
-        
-        pis.connect(pos);
-        t = new Thread(pw = new PWriter(pos, 1000));
-        t.start();
-
         synchronized (pw) {
             pw.wait(10000);
         }
-        assertEquals("Test 2: Unexpected number of bytes available. ",
-                     1000, pis.available());
+        assertTrue("Available returned incorrect number of bytes: "
+                + pis.available(), pis.available() == 1000);
         pis.read(buf, 0, 400);
         for (int i = 0; i < 400; i++) {
-            assertEquals("Test 3: read() returned incorrect byte. ", 
-                         pw.bytes[i], buf[i]);
-        }
-        
-        pis.close();
-        try {
-            pis.read(buf, 0, 10);
-            fail("Test 4: IOException expected since the stream is closed.");
-        } catch (IOException e) {
-            // Expected.
+            assertEquals("read returned incorrect byte[]", pw.bytes[i], buf[i]);
         }
     }
 
@@ -354,20 +219,14 @@
      * @tests java.io.PipedInputStream#read(byte[], int, int)
      * Regression for HARMONY-387
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Tests illegal length argument.",
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_read$BII_2() throws IOException {
         PipedInputStream obj = new PipedInputStream();
         try {
             obj.read(new byte[0], 0, -1);
-            fail("IndexOutOfBoundsException expected.");
+            fail("IndexOutOfBoundsException expected");
         } catch (IndexOutOfBoundsException t) {
             assertEquals(
-                    "IndexOutOfBoundsException rather than a subclass expected.",
+                    "IndexOutOfBoundsException rather than a subclass expected",
                     IndexOutOfBoundsException.class, t.getClass());
         }
     }
@@ -375,46 +234,34 @@
     /**
      * @tests java.io.PipedInputStream#read(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Tests illegal offset argument.",
-        method = "read",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_read$BII_3() throws IOException {
         PipedInputStream obj = new PipedInputStream();
         try {
-            obj.read(new byte[10], -1, 1);
-            fail("IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-            assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
+            obj.read(new byte[0], -1, 0);
+            fail("IndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException t) {
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException t) {
         }
+    }
+
+    /**
+     * @tests java.io.PipedInputStream#read(byte[], int, int)
+     */
+    public void test_read$BII_4() throws IOException {
+        PipedInputStream obj = new PipedInputStream();
         try {
-            obj.read(new byte[10], 0, -1);
-            fail("IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-            assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
-        }
-        try {
-            obj.read(new byte[10], 9, 2);
-            fail("IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-            assertTrue(e.getClass().equals(IndexOutOfBoundsException.class));
+            obj.read(new byte[0], -1, -1);
+            fail("IndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException t) {
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException t) {
         }
     }
 
     /**
      * @tests java.io.PipedInputStream#receive(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "receive",
-        args = {int.class}
-    )
     public void test_receive() throws IOException {
         pis = new PipedInputStream();
         pos = new PipedOutputStream();
@@ -425,13 +272,13 @@
 
             boolean pass = false;
 
-            boolean readerAlive = true;
+            volatile boolean readerAlive = true;
 
             public void run() {
                 try {
                     pos.write(1);
                     while (readerAlive) {
-                        Thread.sleep(100);
+                        ;
                     }
                     try {
                         pos.write(new byte[BUFFER_SIZE]);
@@ -442,9 +289,6 @@
                         pass = true;
                     }
                 } catch (IOException e) {
-                    // ignore
-                } catch (InterruptedException e) {
-                    // ignore
                 }
             }
         }
@@ -458,7 +302,8 @@
                 try {
                     pis.read();
                     pass = true;
-                } catch (IOException e) {}
+                } catch (IOException e) {
+                }
             }
         }
         ;
@@ -466,12 +311,14 @@
         Thread readThread = new Thread(readRunnable);
         writeThread.start();
         readThread.start();
-        while (readThread.isAlive())
+        while (readThread.isAlive()) {
             ;
+        }
         writeRunnable.readerAlive = false;
         assertTrue("reader thread failed to read", readRunnable.pass);
-        while (writeThread.isAlive())
+        while (writeThread.isAlive()) {
             ;
+        }
         assertTrue("writer thread failed to recognize dead reader",
                 writeRunnable.pass);
 
@@ -502,7 +349,8 @@
             try {
                 // wait for thread t to get to the call to pis.receive
                 Thread.sleep(100);
-            } catch (InterruptedException e) {}
+            } catch (InterruptedException e) {
+            }
             // now we close
             pos.close();
         }
@@ -517,17 +365,87 @@
                 myRun.pass);
     }
 
-    /**
-     * Tears down the fixture, for example, close a network connection. This
-     * method is called after a test is executed.
-     */
-    protected void tearDown() throws Exception {
-        try {
-            if (t != null) {
-                t.interrupt();
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() throws Exception {
+		try {
+			if (t != null) {
+				t.interrupt();
             }
-        } catch (Exception ignore) {
-        }
+		} catch (Exception ignore) {
+		}
         super.tearDown();
+	}
+	
+	    
+     /**
+     * @tests java.io.PipedInputStream#PipedInputStream(java.io.PipedOutputStream,
+     *        int)
+     * @since 1.6
+     */
+    public void test_Constructor_LPipedOutputStream_I() throws Exception {
+        // Test for method java.io.PipedInputStream(java.io.PipedOutputStream,
+        // int)
+        MockPipedInputStream mpis = new MockPipedInputStream(
+                new PipedOutputStream(), 100);
+        int bufferLength = mpis.bufferLength();
+        assertEquals(100, bufferLength);
+        
+        try {
+            pis = new PipedInputStream(null, -1);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        
+        try {
+            pis = new PipedInputStream(null, 0);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.io.PipedInputStream#PipedInputStream(int)
+     * @since 1.6
+     */
+    public void test_Constructor_I() throws Exception {
+        // Test for method java.io.PipedInputStream(int)
+        MockPipedInputStream mpis = new MockPipedInputStream(100);
+        int bufferLength = mpis.bufferLength();
+        assertEquals(100, bufferLength);
+
+        try {
+            pis = new PipedInputStream(-1);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        
+        try {
+            pis = new PipedInputStream(0);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+	
+    static class MockPipedInputStream extends PipedInputStream {
+
+        public MockPipedInputStream(java.io.PipedOutputStream src,
+                int bufferSize) throws IOException {
+            super(src, bufferSize);
+        }
+
+        public MockPipedInputStream(int bufferSize) {
+            super(bufferSize);
+        }
+
+        public int bufferLength() {
+            return super.buffer.length;
+        }
     }
 }
diff --git a/luni/src/test/java/tests/api/java/io/PipedReaderTest.java b/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
index f67790b..edbb5f5 100644
--- a/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
+++ b/luni/src/test/java/tests/api/java/io/PipedReaderTest.java
@@ -17,17 +17,13 @@
 
 package tests.api.java.io;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass; 
-
 import java.io.IOException;
 import java.io.PipedReader;
 import java.io.PipedWriter;
 
-@TestTargetClass(PipedReader.class) 
-public class PipedReaderTest extends junit.framework.TestCase {
+import junit.framework.TestCase;
+
+public class PipedReaderTest extends TestCase {
 
     static class PWriter implements Runnable {
         public PipedWriter pw;
@@ -57,29 +53,6 @@
         }
     }
 
-    static class PWriter2 implements Runnable {
-        PipedWriter pw;
-
-        public boolean keepRunning = true;
-
-        public void run() {
-            try {
-                pw.write('H');
-                pw.close();
-                while (keepRunning) {
-                    Thread.sleep(1000);
-                }
-            } catch (Exception e) {
-                e.printStackTrace(System.out);
-                System.out.println("Error while running the writer thread.");
-            }
-        }
-
-        public PWriter2(PipedWriter writer) {
-            pw = writer;
-        }
-    }
-    
     PipedReader preader;
 
     PWriter pwriter;
@@ -89,88 +62,80 @@
     /**
      * @tests java.io.PipedReader#PipedReader()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PipedReader",
-        args = {}
-    )
     public void test_Constructor() {
-        preader = new PipedReader();
-        assertNotNull(preader);
-        try {
-            preader.close();
-        } catch (IOException e) {
-            fail("Unexpeceted IOException");
-        }
+        // Used in test
     }
 
     /**
      * @tests java.io.PipedReader#PipedReader(java.io.PipedWriter)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PipedReader",
-        args = {java.io.PipedWriter.class}
-    )
     public void test_ConstructorLjava_io_PipedWriter() throws IOException {
-        // Test for method java.io.PipedReader(java.io.PipedWriter)
+        preader = new PipedReader(new PipedWriter());
+    }
+    
+    /**
+     * @tests java.io.PipedReader#PipedReader(java.io.PipedWriter,
+     *        int)
+     * @since 1.6
+     */
+    public void test_Constructor_LPipedWriter_I() throws Exception {
+        // Test for method java.io.PipedReader(java.io.PipedWriter,
+        // int)
         try {
-            preader = new PipedReader(new PipedWriter());
-        } catch (Exception e) {
-            fail("Test 1: Constructor failed: " + e.getMessage());
+            preader = new PipedReader(null, -1);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
         }
-        preader.close();
-            
-        PipedWriter pw = new PipedWriter(new PipedReader());
+        
         try {
-            preader = new PipedReader(pw);
-            fail("Test 2: IOException expected because the writer is already connected.");
-        } catch (IOException e) {
-            // Expected.
+            preader = new PipedReader(null, 0);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.io.PipedReader#PipedReader(int)
+     * @since 1.6
+     */
+    public void test_Constructor_I() throws Exception {
+        // Test for method java.io.PipedReader(int)
+        try {
+            preader = new PipedReader(-1);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        
+        try {
+            preader = new PipedReader(0);
+            fail("Should throw IllegalArgumentException"); //$NON-NLS-1$
+        } catch (IllegalArgumentException e) {
+            // expected
         }
     }
 
     /**
      * @tests java.io.PipedReader#close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "No IOException checking because it is never thrown in the source code.",
-        method = "close",
-        args = {}
-    )
     public void test_close() throws Exception {
-        // Test for method void java.io.PipedReader.close()
         char[] c = null;
         preader = new PipedReader();
         t = new Thread(new PWriter(preader), "");
         t.start();
         Thread.sleep(500); // Allow writer to start
         c = new char[11];
-        preader.read(c, 0, 5);
+        preader.read(c, 0, 11);
         preader.close();
-        
-        try {
-            preader.read(c, 0, 5);
-            fail("IOException expected because the reader is closed.");
-        } catch (IOException e) {
-            // Expected.
-        }
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
     }
 
     /**
      * @tests java.io.PipedReader#connect(java.io.PipedWriter)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "connect",
-        args = {java.io.PipedWriter.class}
-    )
     public void test_connectLjava_io_PipedWriter() throws Exception {
-        // Test for method void java.io.PipedReader.connect(java.io.PipedWriter)
         char[] c = null;
 
         preader = new PipedReader();
@@ -181,26 +146,19 @@
         c = new char[11];
         preader.read(c, 0, 11);
 
-        assertEquals("Test 1: Wrong characters read. ", "Hello World", new String(c));
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
         try {
-            preader.connect(new PipedWriter());
-            fail("Test 2: IOException expected because the reader is already connected.");
+            preader.connect(pwriter.pw);
+            fail("Failed to throw exception connecting to pre-connected reader");
         } catch (IOException e) {
-            // Expected.
+            // Expected
         }
     }
 
     /**
      * @tests java.io.PipedReader#read()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "read",
-        args = {}
-    )
-    public void test_read_1() throws Exception {
-        // Test for method int java.io.PipedReader.read()
+    public void test_read() throws Exception {
         char[] c = null;
         preader = new PipedReader();
         t = new Thread(new PWriter(preader), "");
@@ -210,62 +168,13 @@
         for (int i = 0; i < c.length; i++) {
             c[i] = (char) preader.read();
         }
-        assertEquals("Test 1: Wrong characters read. ", "Hello World", new String(c));
-        
-        try {
-            preader.read();
-            fail("Test 2: IOException expected since the thread that has " +
-                 "written to the pipe is no longer alive.");
-        } catch (IOException e) {
-            // Expected.
-        }
-        
-        preader.close();
-        try {
-            preader.read();
-            fail("Test 3: IOException expected.");
-        } catch (IOException e) {
-            // Expected.
-        }
-    }
-
-    /**
-     * @tests java.io.PipedReader#read()
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks that read() returns -1 if the PipedWriter connectedto this PipedReader is closed.",
-        method = "read",
-        args = {}
-    )
-    public void test_read_2() throws Exception {
-        Thread writerThread;
-        PipedWriter pw;
-        PWriter2 pwriter;
-
-        preader = new PipedReader();
-        pw = new PipedWriter(preader);
-        
-        writerThread = new Thread(pwriter = new PWriter2(pw), "PWriter2");
-        writerThread.start();
-        Thread.sleep(500); // Allow writer to start
-        
-        preader.read();
-        assertEquals("Test 1: No more data indication expected. ", -1, preader.read());
-        pwriter.keepRunning = false;
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
     }
 
     /**
      * @tests java.io.PipedReader#read(char[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "IOException checking missed.",
-        method = "read",
-        args = {char[].class, int.class, int.class}
-    )
-    public void test_read$CII_1() throws Exception {
-        // Test for method int java.io.PipedReader.read(char [], int, int)
+    public void test_read$CII() throws Exception {
         char[] c = null;
         preader = new PipedReader();
         t = new Thread(new PWriter(preader), "");
@@ -278,121 +187,231 @@
             n = preader.read(c, x, 11 - x);
             x = x + n;
         }
-        assertEquals("Test 1: Wrong characters read. ", "Hello World", new String(c));
-
-        preader.close();
+        assertEquals("Read incorrect chars", "Hello World", new String(c));
         try {
+            preader.close();
             preader.read(c, 8, 7);
-            fail("Test 2: IOException expected.");
+            fail("Failed to throw exception reading from closed reader");
         } catch (IOException e) {
-            // Expected.
+            // Expected
         }
     }
 
     /**
      * @tests java.io.PipedReader#read(char[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "read",
-        args = {char[].class, int.class, int.class}
-    )
-    public void test_read$CII_Exception() throws IOException{
+    public void test_read$CII_2() throws IOException {
+        // Regression for HARMONY-387
         PipedWriter pw = new PipedWriter();
-        PipedReader obj = new PipedReader(pw);
+        PipedReader obj = null;
         try {
-            obj.read(new char[10], 0, -1);
-            fail("IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected.
-        }
-        try {
-            obj.read(new char[10], -1, 1);
-            fail("IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected.
-        }
-        try {
-            obj.read(new char[10], 2, 9);
-            fail("IndexOutOfBoundsException expected.");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected.
-        }
-        try {
-            obj.read(null, 0, 1);
-            fail("NullPointerException expected.");
-        } catch (NullPointerException e) {
-            // Expected.
+            obj = new PipedReader(pw);
+            obj.read(new char[0], (int) 0, (int) -1);
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException t) {
+            assertEquals(
+                    "IndexOutOfBoundsException rather than a subclass expected",
+                    IndexOutOfBoundsException.class, t.getClass());
         }
     }
 
     /**
-     * @tests java.io.PipedReader#read()
+     * @tests java.io.PipedReader#read(char[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Checks that read() returns -1 if the PipedWriter connectedto this PipedReader is closed.",
-        method = "read",
-        args = {}
-    )
-    public void test_read$CII_2() throws Exception {
-        Thread writerThread;
-        PipedWriter pw;
-        PWriter2 pwriter;
-        char[] c = new char[1];
+    public void test_read$CII_3() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader obj = null;
+        try {
+            obj = new PipedReader(pw);
+            obj.read(new char[0], (int) -1, (int) 0);
+            fail("IndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException t) {
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException t) {
+            // Expected
+        }
+    }
 
-        preader = new PipedReader();
-        pw = new PipedWriter(preader);
-        
-        writerThread = new Thread(pwriter = new PWriter2(pw), "PWriter2");
-        writerThread.start();
-        Thread.sleep(500); // Allow writer to start
-        
-        preader.read(c, 0, 1);
-        assertEquals("Test 1: No more data indication expected. ", 
-                     -1, preader.read(c, 0, 1));
-        pwriter.keepRunning = false;
+    /**
+     * @tests java.io.PipedReader#read(char[], int, int)
+     */
+    public void test_read$CII_4() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader obj = null;
+        try {
+            obj = new PipedReader(pw);
+            obj.read(new char[0], (int) -1, (int) -1);
+            fail("IndexOutOfBoundsException expected");
+        } catch (ArrayIndexOutOfBoundsException t) {
+            fail("IndexOutOfBoundsException expected");
+        } catch (IndexOutOfBoundsException t) {
+            // Expected
+        }
+    }
+
+    /**
+     * @tests java.io.PipedReader#read(char[], int, int)
+     */
+    public void test_read_$CII_IOException() throws IOException {
+        PipedWriter pw = new PipedWriter();
+        PipedReader pr = new PipedReader(pw);
+        char[] buf = null;
+        pr.close();
+        try {
+            pr.read(buf, 0, 10);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pr = new PipedReader();
+        buf = null;
+        pr.close();
+        try {
+            pr.read(buf, 0, 10);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        buf = new char[10];
+        pr.close();
+        try {
+            pr.read(buf, -1, 0);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        buf = new char[10];
+        pr.close();
+        try {
+            pr.read(buf, 0, -1);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        buf = new char[10];
+        pr.close();
+        try {
+            pr.read(buf, 1, 10);
+            fail("Should throws IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        pr.close();
+        try {
+            pr.read(new char[0], -1, -1);
+            fail("should throw IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        pr.close();
+        try {
+            pr.read(null, 0, 1);
+            fail("should throw IOException"); //$NON-NLS-1$
+        } catch (IOException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        try {
+            pr.read(null, -1, 1);
+            fail("should throw IndexOutOfBoundsException"); //$NON-NLS-1$
+        } catch (NullPointerException expected) { // android-added
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        try {
+            pr.read(null, 0, -1);
+            fail("should throw NullPointerException"); //$NON-NLS-1$
+        } catch (NullPointerException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        try {
+            pr.read(new char[10], 11, 0);
+            fail("should throw IndexOutOfBoundsException"); //$NON-NLS-1$
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
+
+        pw = new PipedWriter();
+        pr = new PipedReader(pw);
+        try {
+            pr.read(null, 1, 0);
+            fail("should throw NullPointerException"); //$NON-NLS-1$
+        } catch (NullPointerException e) {
+            // expected
+        } finally {
+            pw = null;
+            pr = null;
+        }
     }
 
     /**
      * @tests java.io.PipedReader#ready()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "ready",
-        args = {}
-    )
     public void test_ready() throws Exception {
-        // Test for method boolean java.io.PipedReader.ready()
         char[] c = null;
         preader = new PipedReader();
-        
-        try {
-            preader.ready();
-            fail("Test 1: IOException expected.");
-        } catch (IOException e) {
-            // Expected.
-        }
-        
         t = new Thread(new PWriter(preader), "");
         t.start();
         Thread.sleep(500); // Allow writer to start
-        assertTrue("Test 2: Reader should be ready", preader.ready());
+        assertTrue("Reader should be ready", preader.ready());
         c = new char[11];
         for (int i = 0; i < c.length; i++)
             c[i] = (char) preader.read();
-        assertFalse("Test 3: Reader should not be ready after reading all chars",
+        assertFalse("Reader should not be ready after reading all chars",
                 preader.ready());
-        
-        preader.close();
-        try {
-            preader.ready();
-            fail("Test 4: IOException expected.");
-        } catch (IOException e) {
-            // Expected.
-        }
     }
 
     /**
diff --git a/luni/src/test/java/tests/api/java/io/PrintStreamTest.java b/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
index fed1aed..f8f885b 100644
--- a/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
+++ b/luni/src/test/java/tests/api/java/io/PrintStreamTest.java
@@ -19,6 +19,7 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
 import java.io.DataInputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -26,255 +27,99 @@
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.UnsupportedEncodingException;
-import java.util.IllegalFormatException;
 import java.util.Locale;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
-import tests.support.Support_Locale;
-
-@TestTargetClass(PrintStream.class) 
 public class PrintStreamTest extends junit.framework.TestCase {
 
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
     byte[] ibuf = new byte[4096];
     
     private File testFile = null;
+    
     private String testFilePath = null;
 
     public String fileString = "Test_All_Tests\nTest_java_io_BufferedInputStream\nTest_java_io_BufferedOutputStream\nTest_java_io_ByteArrayInputStream\nTest_java_io_ByteArrayOutputStream\nTest_java_io_DataInputStream\nTest_java_io_File\nTest_java_io_FileDescriptor\nTest_java_io_FileInputStream\nTest_java_io_FileNotFoundException\nTest_java_io_FileOutputStream\nTest_java_io_FilterInputStream\nTest_java_io_FilterOutputStream\nTest_java_io_InputStream\nTest_java_io_IOException\nTest_java_io_OutputStream\nTest_PrintStream\nTest_java_io_RandomAccessFile\nTest_java_io_SyncFailedException\nTest_java_lang_AbstractMethodError\nTest_java_lang_ArithmeticException\nTest_java_lang_ArrayIndexOutOfBoundsException\nTest_java_lang_ArrayStoreException\nTest_java_lang_Boolean\nTest_java_lang_Byte\nTest_java_lang_Character\nTest_java_lang_Class\nTest_java_lang_ClassCastException\nTest_java_lang_ClassCircularityError\nTest_java_lang_ClassFormatError\nTest_java_lang_ClassLoader\nTest_java_lang_ClassNotFoundException\nTest_java_lang_CloneNotSupportedException\nTest_java_lang_Double\nTest_java_lang_Error\nTest_java_lang_Exception\nTest_java_lang_ExceptionInInitializerError\nTest_java_lang_Float\nTest_java_lang_IllegalAccessError\nTest_java_lang_IllegalAccessException\nTest_java_lang_IllegalArgumentException\nTest_java_lang_IllegalMonitorStateException\nTest_java_lang_IllegalThreadStateException\nTest_java_lang_IncompatibleClassChangeError\nTest_java_lang_IndexOutOfBoundsException\nTest_java_lang_InstantiationError\nTest_java_lang_InstantiationException\nTest_java_lang_Integer\nTest_java_lang_InternalError\nTest_java_lang_InterruptedException\nTest_java_lang_LinkageError\nTest_java_lang_Long\nTest_java_lang_Math\nTest_java_lang_NegativeArraySizeException\nTest_java_lang_NoClassDefFoundError\nTest_java_lang_NoSuchFieldError\nTest_java_lang_NoSuchMethodError\nTest_java_lang_NullPointerException\nTest_java_lang_Number\nTest_java_lang_NumberFormatException\nTest_java_lang_Object\nTest_java_lang_OutOfMemoryError\nTest_java_lang_RuntimeException\nTest_java_lang_SecurityManager\nTest_java_lang_Short\nTest_java_lang_StackOverflowError\nTest_java_lang_String\nTest_java_lang_StringBuffer\nTest_java_lang_StringIndexOutOfBoundsException\nTest_java_lang_System\nTest_java_lang_Thread\nTest_java_lang_ThreadDeath\nTest_java_lang_ThreadGroup\nTest_java_lang_Throwable\nTest_java_lang_UnknownError\nTest_java_lang_UnsatisfiedLinkError\nTest_java_lang_VerifyError\nTest_java_lang_VirtualMachineError\nTest_java_lang_vm_Image\nTest_java_lang_vm_MemorySegment\nTest_java_lang_vm_ROMStoreException\nTest_java_lang_vm_VM\nTest_java_lang_Void\nTest_java_net_BindException\nTest_java_net_ConnectException\nTest_java_net_DatagramPacket\nTest_java_net_DatagramSocket\nTest_java_net_DatagramSocketImpl\nTest_java_net_InetAddress\nTest_java_net_NoRouteToHostException\nTest_java_net_PlainDatagramSocketImpl\nTest_java_net_PlainSocketImpl\nTest_java_net_Socket\nTest_java_net_SocketException\nTest_java_net_SocketImpl\nTest_java_net_SocketInputStream\nTest_java_net_SocketOutputStream\nTest_java_net_UnknownHostException\nTest_java_util_ArrayEnumerator\nTest_java_util_Date\nTest_java_util_EventObject\nTest_java_util_HashEnumerator\nTest_java_util_Hashtable\nTest_java_util_Properties\nTest_java_util_ResourceBundle\nTest_java_util_tm\nTest_java_util_Vector\n";
     
     private static class MockPrintStream extends PrintStream {
 
-        public MockPrintStream(String fileName) throws FileNotFoundException {
-            super(fileName);
-        }
-        
-        public MockPrintStream(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
-            super(fileName, csn);
-        }
-        
-        public MockPrintStream(OutputStream os) {
-            super(os);
-        }
+		public MockPrintStream(String fileName) throws FileNotFoundException {
+			super(fileName);
+		}
+		
+		public MockPrintStream(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
+			super(fileName, csn);
+		}
+		
+		public MockPrintStream(OutputStream os) {
+			super(os);
+		}
         
         @Override
-        public void setError() {
-            super.setError();
+        public void clearError() {
+            super.clearError();
         }
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintStream",
-        args = {java.io.File.class}
-    )
-    public void test_Constructor_Ljava_io_File() throws IOException {
-        PrintStream tobj;
-
-        tobj = new PrintStream(testFile);
-        assertNotNull(tobj);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintStream(testFile);
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
-        File file = new File("/invalidDirectory/Dummy");
-        try {
-            tobj = new PrintStream(file);
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
+        
+		@Override
+		public void setError() {
+			super.setError();
+		}
     }
     
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintStream",
-        args = {java.io.File.class, java.lang.String.class}
-    )
-    public void test_Constructor_Ljava_io_File_Ljava_lang_String() throws Exception {
-        PrintStream tobj;
-
-        tobj = new PrintStream(testFile, "utf-8");
-        assertNotNull(tobj);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintStream(testFile, "utf-8");
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
-        File file = new File("/invalidDirectory/Dummy");
-        try {
-            tobj = new PrintStream(file, "utf-8");
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-
-        try {
-            tobj = new PrintStream(testFile, "invalidEncoding");
-            fail("UnsupportedEncodingException not thrown.");
-        } catch (UnsupportedEncodingException e) {
-            // expected
-        }
-    }
-
     /**
      * @tests {@link java.io.PrintStream#PrintStream(String)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintStream",
-        args = {java.lang.String.class}
-    )
     public void test_Constructor_Ljava_lang_String() throws IOException {
-        PrintStream tobj;
-
-        tobj = new PrintStream(testFilePath);
-        assertNotNull(tobj);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintStream(testFilePath);
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
-        try {
-            tobj = new PrintStream("/invalidDirectory/Dummy");
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-    }
+    	MockPrintStream os = new MockPrintStream(testFilePath);
+    	assertNotNull(os);
+    	os.close();
+	}
     
     /**
      * @tests {@link java.io.PrintStream#PrintStream(String, String)}
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintStream",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void test_Constructor_Ljava_lang_String_Ljava_lang_String() throws Exception {
-        PrintStream tobj;
-
-        tobj = new PrintStream(testFilePath, "utf-8");
-        assertNotNull(tobj);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintStream(testFilePath, "utf-8");
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
-        try {
-            tobj = new PrintStream("/invalidDirectory/", "utf-8");
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-
-        try {
-            tobj = new PrintStream(testFilePath, "invalidEncoding");
-            fail("UnsupportedEncodingException not thrown.");
-        } catch (UnsupportedEncodingException e) {
-            // expected
-        }
+    	MockPrintStream os = new MockPrintStream(testFilePath, "utf-8");
+    	assertNotNull(os);
+    	os.close();
     }
 
     /**
      * @tests java.io.PrintStream#PrintStream(java.io.OutputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintStream",
-        args = {java.io.OutputStream.class}
-    )
     public void test_ConstructorLjava_io_OutputStream() throws Exception {
         // Test for method java.io.PrintStream(java.io.OutputStream)
-        PrintStream os = new PrintStream(baos);
+        PrintStream os = new PrintStream(bos);
         os.print(2345.76834720202);
         os.close();
 
         // regression for HARMONY-1195
         try {
-            os = new PrintStream(baos, true, null);
+            os = new PrintStream(bos, true, null);
             fail("Should throw NPE");
         } catch (NullPointerException e) {}
     }
 
     /**
-     * @throws FileNotFoundException 
      * @tests java.io.PrintStream#PrintStream(java.io.OutputStream, boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "Passing FALSE for autoFlush not tested.",
-        method = "PrintStream",
-        args = {java.io.OutputStream.class, boolean.class}
-    )
-    public void test_ConstructorLjava_io_OutputStreamZ() throws FileNotFoundException {
-        PrintStream tobj;
-
-        tobj = new PrintStream(baos, true);
-        tobj.println(2345.76834720202);
-        assertTrue("Bytes not written", baos.size() > 0);
-        tobj.close();
-
-//        tobj = new PrintStream(bos, false);
-//        tobj.println(2345.76834720202);
-//        assertEquals("Bytes should not be written, yet", 0, bos.size());
-//        tobj.flush();
-//        assertTrue("Bytes not written", bos.size() > 0);
-//        tobj.close();
-
-//        FileOutputStream fos = new FileOutputStream(testFile);
-//
-//        tobj = new PrintStream(fos, true);
-//        tobj.println(2345.76834720202);
-//        assertTrue("Bytes not written", testFile.length() > 0);
-//        tobj.close();
-//
-//        tobj = new PrintStream(fos, false);
-//        tobj.println(2345.76834720202);
-//        assertTrue("Bytes not written", testFile.length() > 0);
-//        tobj.close();
-//
+    public void test_ConstructorLjava_io_OutputStreamZ() {
+        // Test for method java.io.PrintStream(java.io.OutputStream, boolean)
+        PrintStream os = new PrintStream(bos);
+        os.println(2345.76834720202);
+        os.flush();
+        assertTrue("Bytes not written", bos.size() > 0);
+        os.close();
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintStream",
-        args = {java.io.OutputStream.class, boolean.class, java.lang.String.class}
-    )
-    public void test_ConstructorLjava_io_OutputStream_Z_Ljava_lang_String() {
-        PrintStream tobj;
-
-        tobj = new PrintStream(baos, true);
-        tobj.println(2345.76834720202);
-        assertTrue("Bytes not written", baos.size() > 0);
-        tobj.close();
-
+    /**
+     * @tests java.io.PrintStream#PrintStream(java.io.OutputStream, boolean, String)
+     */
+    public void test_ConstructorLjava_io_OutputStreamZLjava_lang_String() {
         try {
-            tobj = new PrintStream(baos, true, "invalidEncoding");
-            fail("UnsupportedEncodingException not thrown.");
+            new PrintStream(new ByteArrayOutputStream(), false,
+                    "%Illegal_name!");
+            fail("Expected UnsupportedEncodingException");
         } catch (UnsupportedEncodingException e) {
             // expected
         }
@@ -283,12 +128,6 @@
     /**
      * @tests java.io.PrintStream#checkError()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkError",
-        args = {}
-    )
     public void test_checkError() throws Exception {
         // Test for method boolean java.io.PrintStream.checkError()
         PrintStream os = new PrintStream(new OutputStream() {
@@ -307,77 +146,57 @@
     }
 
     /**
-     * @tests java.io.PrintStream#setError()
+     * @tests {@link java.io.PrintStream#clearError()} 
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "setError",
-        args = {}
-    )
-    public void test_setError() throws Exception {
-        MockPrintStream os = new MockPrintStream(new ByteArrayOutputStream());
-        assertFalse("Test 1: Error flag should not be set.", os.checkError());
+    public void test_clearError() throws FileNotFoundException {        
+        MockPrintStream os = new MockPrintStream(testFilePath);     
+        assertFalse(os.checkError());
         os.setError();
-        assertTrue("Test 2: Error flag should be set.", os.checkError());
+        assertTrue(os.checkError());
+        os.clearError();
+        assertFalse(os.checkError());
+        os.close();
     }
     
     /**
      * @tests java.io.PrintStream#close()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
     public void test_close() throws Exception {
         // Test for method void java.io.PrintStream.close()
-        PrintStream os = new PrintStream(baos);
+        PrintStream os = new PrintStream(bos);
         os.close();
-        baos.close();
+        bos.close();
     }
 
     /**
      * @tests java.io.PrintStream#flush()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "flush",
-        args = {}
-    )
     public void test_flush() throws Exception {
         // Test for method void java.io.PrintStream.flush()
-        PrintStream os = new PrintStream(baos);
+        PrintStream os = new PrintStream(bos);
         os.print(fileString.substring(0, 501));
         os.flush();
-        assertEquals("Bytes not written after flush", 501, baos.size());
-        baos.close();
+        assertEquals("Bytes not written after flush", 501, bos.size());
+        bos.close();
         os.close();
     }
 
     /**
      * @tests java.io.PrintStream#print(char[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {char[].class}
-    )
     public void test_print$C() {
         // Test for method void java.io.PrintStream.print(char [])
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         try {
             os.print((char[]) null);
             fail("NPE expected");
         } catch (NullPointerException ok) {}
 
-        os = new PrintStream(baos, true);
+        os = new PrintStream(bos, true);
         char[] sc = new char[4000];
         fileString.getChars(0, fileString.length(), sc, 0);
         os.print(sc);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         os.close();
 
         byte[] rbytes = new byte[4000];
@@ -389,35 +208,24 @@
     /**
      * @tests java.io.PrintStream#print(char)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {char.class}
-    )
-    public void test_printC() {
+    public void test_printC() throws Exception {
         // Test for method void java.io.PrintStream.print(char)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print('t');
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        assertEquals("Incorrect char written", 't', bis.read());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
+        assertEquals("Incorrect char written", 't', isr.read());
     }
 
     /**
      * @tests java.io.PrintStream#print(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {double.class}
-    )
     public void test_printD() {
         // Test for method void java.io.PrintStream.print(double)
         byte[] rbuf = new byte[100];
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print(2345.76834720202);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         bis.read(rbuf, 0, 16);
         assertEquals("Incorrect double written", "2345.76834720202",
                 new String(rbuf, 0, 16));
@@ -426,19 +234,13 @@
     /**
      * @tests java.io.PrintStream#print(float)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {float.class}
-    )
     public void test_printF() {
         // Test for method void java.io.PrintStream.print(float)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         byte rbuf[] = new byte[10];
         os.print(29.08764f);
         os.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         bis.read(rbuf, 0, 8);
         assertEquals("Incorrect float written", "29.08764", new String(rbuf, 0,
                 8));
@@ -448,18 +250,12 @@
     /**
      * @tests java.io.PrintStream#print(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {int.class}
-    )
     public void test_printI() {
         // Test for method void java.io.PrintStream.print(int)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print(768347202);
         byte[] rbuf = new byte[18];
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         bis.read(rbuf, 0, 9);
         assertEquals("Incorrect int written", "768347202", new String(rbuf, 0,
                 9));
@@ -468,19 +264,13 @@
     /**
      * @tests java.io.PrintStream#print(long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {long.class}
-    )
     public void test_printJ() {
         // Test for method void java.io.PrintStream.print(long)
         byte[] rbuf = new byte[100];
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print(9875645283333L);
         os.close();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         bis.read(rbuf, 0, 13);
         assertEquals("Incorrect long written", "9875645283333", new String(
                 rbuf, 0, 13));
@@ -489,25 +279,19 @@
     /**
      * @tests java.io.PrintStream#print(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {java.lang.Object.class}
-    )
     public void test_printLjava_lang_Object() throws Exception {
         // Test for method void java.io.PrintStream.print(java.lang.Object)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print((Object) null);
         os.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte[] nullbytes = new byte[4];
         bis.read(nullbytes, 0, 4);
         assertEquals("null should be written", "null", new String(nullbytes, 0,
                 4));
 
         bis.close();
-        baos.close();
+        bos.close();
         os.close();
 
         ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
@@ -522,24 +306,18 @@
     /**
      * @tests java.io.PrintStream#print(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {java.lang.String.class}
-    )
     public void test_printLjava_lang_String() throws Exception {
         // Test for method void java.io.PrintStream.print(java.lang.String)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print((String) null);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte[] nullbytes = new byte[4];
         bis.read(nullbytes, 0, 4);
         assertEquals("null should be written", "null", new String(nullbytes, 0,
                 4));
 
         bis.close();
-        baos.close();
+        bos.close();
         os.close();
 
         ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
@@ -555,17 +333,11 @@
     /**
      * @tests java.io.PrintStream#print(boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {boolean.class}
-    )
     public void test_printZ() throws Exception {
         // Test for method void java.io.PrintStream.print(boolean)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.print(true);
-        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(baos
+        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bos
                 .toByteArray()));
 
         assertTrue("Incorrect boolean written", dis.readBoolean());
@@ -574,38 +346,28 @@
     /**
      * @tests java.io.PrintStream#println()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {}
-    )
-    public void test_println() {
+    public void test_println() throws Exception {
         // Test for method void java.io.PrintStream.println()
         char c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println("");
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        assertTrue("Newline not written", (c = (char) bis.read()) == '\r'
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
+        assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
                 || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(char[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {char[].class}
-    )
-    public void test_println$C() {
+    public void test_println$C() throws Exception {
         // Test for method void java.io.PrintStream.println(char [])
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         char[] sc = new char[4000];
         fileString.getChars(0, fileString.length(), sc, 0);
         os.println(sc);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         byte[] rbytes = new byte[4000];
         bis.read(rbytes, 0, fileString.length());
         assertEquals("Incorrect char[] written", fileString, new String(rbytes,
@@ -618,7 +380,7 @@
         // hit a new line.
         int r;
         boolean newline = false;
-        while ((r = bis.read()) != -1) {
+        while ((r = isr.read()) != -1) {
             if (r == '\r' || r == '\n')
                 newline = true;
         }
@@ -628,244 +390,165 @@
     /**
      * @tests java.io.PrintStream#println(char)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {char.class}
-    )
-    public void test_printlnC() {
+    public void test_printlnC() throws Exception {
         // Test for method void java.io.PrintStream.println(char)
         int c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println('t');
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        assertEquals("Incorrect char written", 't', bis.read());
-        assertTrue("Newline not written", (c = bis.read()) == '\r' || c == '\n');
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
+        assertEquals("Incorrect char written", 't', isr.read());
+        assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {double.class}
-    )
-    public void test_printlnD() {
+    public void test_printlnD() throws Exception {
         // Test for method void java.io.PrintStream.println(double)
         int c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println(2345.76834720202);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         byte[] rbuf = new byte[100];
         bis.read(rbuf, 0, 16);
         assertEquals("Incorrect double written", "2345.76834720202",
                 new String(rbuf, 0, 16));
-        assertTrue("Newline not written", (c = bis.read()) == '\r' || c == '\n');
+        assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(float)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {float.class}
-    )
-    public void test_printlnF() {
+    public void test_printlnF() throws Exception {
         // Test for method void java.io.PrintStream.println(float)
         int c;
         byte[] rbuf = new byte[100];
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println(29.08764f);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         bis.read(rbuf, 0, 8);
         assertEquals("Incorrect float written", "29.08764", new String(rbuf, 0,
                 8));
-        assertTrue("Newline not written", (c = bis.read()) == '\r' || c == '\n');
+        assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {int.class}
-    )
-    public void test_printlnI() {
+    public void test_printlnI() throws Exception {
         // Test for method void java.io.PrintStream.println(int)
         int c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println(768347202);
         byte[] rbuf = new byte[100];
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         bis.read(rbuf, 0, 9);
         assertEquals("Incorrect int written", "768347202", new String(rbuf, 0,
                 9));
-        assertTrue("Newline not written", (c = bis.read()) == '\r' || c == '\n');
+        assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {long.class}
-    )
-    public void test_printlnJ() {
+    public void test_printlnJ() throws Exception {
         // Test for method void java.io.PrintStream.println(long)
         int c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println(9875645283333L);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         byte[] rbuf = new byte[100];
         bis.read(rbuf, 0, 13);
         assertEquals("Incorrect long written", "9875645283333", new String(
                 rbuf, 0, 13));
-        assertTrue("Newline not written", (c = bis.read()) == '\r' || c == '\n');
+        assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {java.lang.Object.class}
-    )
-    public void test_printlnLjava_lang_Object() {
+    public void test_printlnLjava_lang_Object() throws Exception {
         // Test for method void java.io.PrintStream.println(java.lang.Object)
         char c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println(new java.util.Vector());
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         byte[] rbytes = new byte[2];
         bis.read(rbytes, 0, 2);
         assertEquals("Incorrect Vector written", "[]", new String(rbytes, 0, 2));
-        assertTrue("Newline not written", (c = (char) bis.read()) == '\r'
+        assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
                 || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {java.lang.String.class}
-    )
-    public void test_printlnLjava_lang_String() {
+    public void test_printlnLjava_lang_String() throws Exception {
         // Test for method void java.io.PrintStream.println(java.lang.String)
         char c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println("Hello World");
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         byte rbytes[] = new byte[100];
         bis.read(rbytes, 0, 11);
         assertEquals("Incorrect string written", "Hello World", new String(
                 rbytes, 0, 11));
-        assertTrue("Newline not written", (c = (char) bis.read()) == '\r'
+        assertTrue("Newline not written", (c = (char) isr.read()) == '\r'
                 || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#println(boolean)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {boolean.class}
-    )
-    public void test_printlnZ() {
+    public void test_printlnZ() throws Exception {
         // Test for method void java.io.PrintStream.println(boolean)
         int c;
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.println(true);
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        InputStreamReader isr = new InputStreamReader(bis);
         byte[] rbuf = new byte[100];
         bis.read(rbuf, 0, 4);
         assertEquals("Incorrect boolean written", "true",
                 new String(rbuf, 0, 4));
-        assertTrue("Newline not written", (c = bis.read()) == '\r' || c == '\n');
+        assertTrue("Newline not written", (c = isr.read()) == '\r' || c == '\n');
     }
 
     /**
      * @tests java.io.PrintStream#write(byte[], int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {byte[].class, int.class, int.class}
-    )
     public void test_write$BII() {
         // Test for method void java.io.PrintStream.write(byte [], int, int)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.write(fileString.getBytes(), 0, fileString.length());
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte rbytes[] = new byte[4000];
         bis.read(rbytes, 0, fileString.length());
         assertTrue("Incorrect bytes written", new String(rbytes, 0, fileString
                 .length()).equals(fileString));
-        
-        try {
-            os.write(rbytes, -1, 1);
-            fail("IndexOutOfBoundsException should have been thrown.");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
-        
-        try {
-            os.write(rbytes, 0, -1);
-            fail("IndexOutOfBoundsException should have been thrown.");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
-        
-        try {
-            os.write(rbytes, 1, rbytes.length);
-            fail("IndexOutOfBoundsException should have been thrown.");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
     }
 
     /**
      * @tests java.io.PrintStream#write(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {int.class}
-    )
     public void test_writeI() {
         // Test for method void java.io.PrintStream.write(int)
-        PrintStream os = new PrintStream(baos, true);
+        PrintStream os = new PrintStream(bos, true);
         os.write('t');
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         assertEquals("Incorrect char written", 't', bis.read());
     }
 
     /**
      * @tests java.io.PrintStream#append(char)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {char.class}
-    )
     public void test_appendChar() throws IOException {
         char testChar = ' ';
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -879,12 +562,6 @@
     /**
      * @tests java.io.PrintStream#append(CharSequence)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class}
-    )
     public void test_appendCharSequence() {
         String testString = "My Test String";
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -898,12 +575,6 @@
     /**
      * @tests java.io.PrintStream#append(CharSequence, int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class, int.class, int.class}
-    )
     public void test_appendCharSequenceIntInt() {
         String testString = "My Test String";
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -911,269 +582,82 @@
         printStream.append(testString, 1, 3);
         printStream.flush();
         assertEquals(testString.substring(1, 3), out.toString());
-        try {
-            printStream.append(testString, 4, 100);
-            fail("IndexOutOfBoundsException not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
-        try {
-            printStream.append(testString, 100, 1);
-            fail("IndexOutOfBoundsException not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
         printStream.close();
     }
 
     /**
      * @tests java.io.PrintStream#format(java.lang.String, java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_formatLjava_lang_String$Ljava_lang_Object() {
-        PrintStream tobj;
-
-        tobj = new PrintStream(baos, false);
-        tobj.format("%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        PrintStream os = new PrintStream(bos, false);
+        os.format("%s %s", "Hello", "World");
+        os.flush();
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte[] rbytes = new byte[11];
         bis.read(rbytes, 0, rbytes.length);
         assertEquals("Wrote incorrect string", "Hello World",
                 new String(rbytes));
 
-        baos.reset();
-        tobj = new PrintStream(baos);
-        tobj.format("%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        try {
-            tobj.format("%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format("%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format("%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
     }
 
     /**
      * @tests java.io.PrintStream#format(java.util.Locale, java.lang.String,
      *        java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
-        Locale[] requiredLocales = {Locale.US, Locale.GERMANY};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        PrintStream tobj;
-
-        tobj = new PrintStream(baos, false);
-        tobj.format(Locale.US, "%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        PrintStream os = new PrintStream(bos, false);
+        os.format(Locale.US, "%s %s", "Hello", "World");
+        os.flush();
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte[] rbytes = new byte[11];
         bis.read(rbytes, 0, rbytes.length);
         assertEquals("Wrote incorrect string", "Hello World",
                 new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        tobj.format(Locale.GERMANY, "%1$.3G; %1$.5f; 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1,23E+04; 12345,67800; 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        tobj.format(Locale.US, "%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        try {
-            tobj.format(Locale.US, "%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format(Locale.US, "%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format(Locale.US, "%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
     }
 
     /**
      * @tests java.io.PrintStream#printf(java.lang.String, java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "printf",
-        args = {java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_printfLjava_lang_String$Ljava_lang_Object() {
-        PrintStream tobj;
-
-        tobj = new PrintStream(baos, false);
-        tobj.printf("%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        PrintStream os = new PrintStream(bos, false);
+        os.printf("%s %s", "Hello", "World");
+        os.flush();
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte[] rbytes = new byte[11];
         bis.read(rbytes, 0, rbytes.length);
         assertEquals("Wrote incorrect string", "Hello World",
                 new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        tobj.printf("%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        try {
-            tobj.printf("%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf("%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf("%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
     }
 
     /**
      * @tests java.io.PrintStream#printf(java.util.Locale, java.lang.String,
      *        java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "printf",
-        args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
-        Locale[] requiredLocales = {Locale.US, Locale.GERMANY};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        PrintStream tobj;
-
-        tobj = new PrintStream(baos, false);
-        tobj.printf(Locale.US, "%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        PrintStream os = new PrintStream(bos, false);
+        os.printf(Locale.US, "%s %s", "Hello", "World");
+        os.flush();
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
         byte[] rbytes = new byte[11];
         bis.read(rbytes, 0, rbytes.length);
         assertEquals("Wrote incorrect string", "Hello World",
                 new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        tobj.printf(Locale.GERMANY, "%1$.3G; %1$.5f; 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1,23E+04; 12345,67800; 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        tobj.printf(Locale.US, "%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintStream(baos);
-        try {
-            tobj.printf(Locale.US, "%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf(Locale.US, "%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf(Locale.US, "%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        testFile = File.createTempFile("test", null);
-        testFilePath = testFile.getAbsolutePath();
-    }
+	@Override
+	protected void setUp() throws Exception {		
+		super.setUp();
+		testFile = File.createTempFile("test", null);
+		testFilePath = testFile.getAbsolutePath();
+	}
 
-    @Override
-    protected void tearDown() throws Exception {
-        testFile.delete();
-        testFile = null;
-        testFilePath = null;
-        super.tearDown();
-    }
+	@Override
+	protected void tearDown() throws Exception {
+		testFile.delete();
+		testFile = null;
+		testFilePath = null;
+		super.tearDown();
+	}
     
     
 }
diff --git a/luni/src/test/java/tests/api/java/io/PrintWriterTest.java b/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
index 59d83eb..0cf53a4 100644
--- a/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
+++ b/luni/src/test/java/tests/api/java/io/PrintWriterTest.java
@@ -21,1287 +21,758 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.util.IllegalFormatException;
+import java.nio.charset.Charset;
 import java.util.Locale;
 
-import tests.support.Support_Locale;
 import tests.support.Support_StringReader;
 import tests.support.Support_StringWriter;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 
-@TestTargetClass(PrintWriter.class) 
 public class PrintWriterTest extends junit.framework.TestCase {
 
-    private static class MockPrintWriter extends PrintWriter {
+	static class Bogus {
+		public String toString() {
+			return "Bogus";
+		}
+	}
+    
+    /**
+     * @since 1.6
+     */
+    static class MockPrintWriter extends PrintWriter {
 
-        public MockPrintWriter(OutputStream os) {
-            super(os);
+        public MockPrintWriter(OutputStream out, boolean autoflush) {
+            super(out, autoflush);
         }
-        
+
         @Override
-        public void setError() {
-            super.setError();
+        public void clearError() {
+            super.clearError();
         }
+
     }
 
-    static class Bogus {
-        public String toString() {
-            return "Bogus";
-        }
-    }
+	PrintWriter pw;
 
-    private File testFile = null;
-    private String testFilePath = null;
+	ByteArrayOutputStream bao;
 
-    PrintWriter pw;
+	ByteArrayInputStream bai;
 
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+	BufferedReader br;
 
-    ByteArrayInputStream bai;
+	/**
+	 * @tests java.io.PrintWriter#PrintWriter(java.io.OutputStream)
+	 */
+	public void test_ConstructorLjava_io_OutputStream() {
+		// Test for method java.io.PrintWriter(java.io.OutputStream)
+		String s;
+		pw.println("Random Chars");
+		pw.write("Hello World");
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+			assertTrue("Incorrect string written/read: " + s, s
+					.equals("Random Chars"));
+			s = br.readLine();
+			assertTrue("Incorrect string written/read: " + s, s
+					.equals("Hello World"));
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+	}
 
-    BufferedReader br;
+	/**
+	 * @tests java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
+	 */
+	public void test_ConstructorLjava_io_OutputStreamZ() {
+		// Test for method java.io.PrintWriter(java.io.OutputStream, boolean)
+		String s;
+		pw = new PrintWriter(bao, true);
+		pw.println("Random Chars");
+		pw.write("Hello World");
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+			assertTrue("Incorrect string written/read: " + s, s
+					.equals("Random Chars"));
+			pw.flush();
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+			assertTrue("Incorrect string written/read: " + s, s
+					.equals("Random Chars"));
+			s = br.readLine();
+			assertTrue("Incorrect string written/read: " + s, s
+					.equals("Hello World"));
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+	}
 
-    /**
-     * @tests java.io.PrintWriter#PrintWriter(java.io.OutputStream)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.io.OutputStream.class}
-    )
-    public void test_ConstructorLjava_io_OutputStream() {
-        // Test for method java.io.PrintWriter(java.io.OutputStream)
-        String s;
-        pw = new PrintWriter(baos);
-        pw.println("Random Chars");
-        pw.write("Hello World");
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-            assertTrue("Incorrect string written/read: " + s, s
-                    .equals("Random Chars"));
-            s = br.readLine();
-            assertTrue("Incorrect string written/read: " + s, s
-                    .equals("Hello World"));
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-    }
+	/**
+	 * @tests java.io.PrintWriter#PrintWriter(java.io.Writer)
+	 */
+	public void test_ConstructorLjava_io_Writer() {
+		// Test for method java.io.PrintWriter(java.io.Writer)
+		Support_StringWriter sw;
+		pw = new PrintWriter(sw = new Support_StringWriter());
+		pw.print("Hello");
+		pw.flush();
+		assertEquals("Failed to construct proper writer", 
+				"Hello", sw.toString());
+	}
 
-    /**
-     * @tests java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.io.OutputStream.class, boolean.class}
-    )
-    public void test_ConstructorLjava_io_OutputStreamZ() {
-        // Test for method java.io.PrintWriter(java.io.OutputStream, boolean)
-        String s;
-        pw = new PrintWriter(baos, true);
-        pw.println("Random Chars");
-        pw.write("Hello World");
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-            assertTrue("Incorrect string written/read: " + s, s
-                    .equals("Random Chars"));
-            pw.flush();
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-            assertTrue("Incorrect string written/read: " + s, s
-                    .equals("Random Chars"));
-            s = br.readLine();
-            assertTrue("Incorrect string written/read: " + s, s
-                    .equals("Hello World"));
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-    }
-
-    /**
-     * @tests java.io.PrintWriter#PrintWriter(java.io.Writer)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.io.Writer.class}
-    )
-    public void test_ConstructorLjava_io_Writer() {
-        // Test for method java.io.PrintWriter(java.io.Writer)
-        Support_StringWriter sw;
-        pw = new PrintWriter(sw = new Support_StringWriter());
-        pw.print("Hello");
-        pw.flush();
-        assertEquals("Failed to construct proper writer", 
-                "Hello", sw.toString());
-    }
-
-    /**
-     * @tests java.io.PrintWriter#PrintWriter(java.io.Writer, boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.io.Writer.class, boolean.class}
-    )
-    public void test_ConstructorLjava_io_WriterZ() {
-        // Test for method java.io.PrintWriter(java.io.Writer, boolean)
-        Support_StringWriter sw;
-        pw = new PrintWriter(sw = new Support_StringWriter(), true);
-        pw.print("Hello");
-        // Auto-flush should have happened
-        assertEquals("Failed to construct proper writer", 
-                "Hello", sw.toString());
-    }
+	/**
+	 * @tests java.io.PrintWriter#PrintWriter(java.io.Writer, boolean)
+	 */
+	public void test_ConstructorLjava_io_WriterZ() {
+		// Test for method java.io.PrintWriter(java.io.Writer, boolean)
+		Support_StringWriter sw;
+		pw = new PrintWriter(sw = new Support_StringWriter(), true);
+		pw.print("Hello");
+		// Auto-flush should have happened
+		assertEquals("Failed to construct proper writer", 
+				"Hello", sw.toString());
+	}
 
     /**
      * @tests java.io.PrintWriter#PrintWriter(java.io.File)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.io.File.class}
-    )
     public void test_ConstructorLjava_io_File() throws Exception {
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(testFile);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintWriter(testFile);
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
-        File file = new File("/invalidDirectory/Dummy");
+        File file = File.createTempFile(getClass().getName(), null);
         try {
-            tobj = new PrintWriter(file);
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
+            PrintWriter writer = new PrintWriter(file);
+            writer.close();
+        } finally {
+            file.delete();
         }
     }
 
     /**
      * @tests java.io.PrintWriter#PrintWriter(java.io.File, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.io.File.class, java.lang.String.class}
-    )
     public void test_ConstructorLjava_io_File_Ljava_lang_String() throws Exception {
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(testFile, "utf-8");
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintWriter(testFile, "utf-8");
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
-        File file = new File("/invalidDirectory/Dummy");
+        File file = File.createTempFile(getClass().getName(), null);
         try {
-            tobj = new PrintWriter(file, "utf-8");
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-
-        try {
-            tobj = new PrintWriter(testFile, "invalidEncoding");
-            fail("UnsupportedEncodingException not thrown.");
-        } catch (UnsupportedEncodingException e) {
-            // expected
+            PrintWriter writer = new PrintWriter(file, 
+                    Charset.defaultCharset().name());
+            writer.close();
+        } finally {
+            file.delete();
         }
     }
 
     /**
      * @tests java.io.PrintWriter#PrintWriter(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() throws Exception {
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(testFilePath);
-        assertNotNull(tobj);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintWriter(testFilePath);
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
+        File file = File.createTempFile(getClass().getName(), null);
         try {
-            tobj = new PrintWriter("/invalidDirectory/Dummy");
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
+            PrintWriter writer = new PrintWriter(file.getPath());
+            writer.close();
+        } finally {
+            file.delete();
         }
     }
 
     /**
      * @tests java.io.PrintWriter#PrintWriter(java.lang.String, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "PrintWriter",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String_Ljava_lang_String() throws Exception {
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(testFilePath, "utf-8");
-        assertNotNull(tobj);
-        tobj.write(1);
-        tobj.close();
-        assertEquals("output file has wrong length", 1, testFile.length());
-        tobj = new PrintWriter(testFilePath, "utf-8");
-        assertNotNull(tobj);
-        tobj.close();
-        assertEquals("output file should be empty", 0, testFile.length());
-
+        File file = File.createTempFile(getClass().getName(), null);
         try {
-            tobj = new PrintWriter("/invalidDirectory/", "utf-8");
-            fail("FileNotFoundException not thrown.");
-        } catch (FileNotFoundException e) {
-            // expected
-        }
-
-        try {
-            tobj = new PrintWriter(testFilePath, "invalidEncoding");
-            fail("UnsupportedEncodingException not thrown.");
-        } catch (UnsupportedEncodingException e) {
-            // expected
+            PrintWriter writer = new PrintWriter(file.getPath(), 
+                    Charset.defaultCharset().name());
+            writer.close();
+        } finally {
+            file.delete();
         }
     }
 
-    /**
-     * @tests java.io.PrintWriter#checkError()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "checkError",
-        args = {}
-    )
-    public void test_checkError() {
-        // Test for method boolean java.io.PrintWriter.checkError()
-        pw.close();
-        pw.print(490000000000.08765);
-        assertTrue("Failed to return error", pw.checkError());
-    }
+	/**
+	 * @tests java.io.PrintWriter#checkError()
+	 */
+	public void test_checkError() {
+		// Test for method boolean java.io.PrintWriter.checkError()
+		pw.close();
+		pw.print(490000000000.08765);
+		assertTrue("Failed to return error", pw.checkError());
+	}
 
     /**
-     * @tests java.io.PrintStream#setError()
+     * @tests java.io.PrintWriter#clearError()
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "setError",
-        args = {}
-    )
-    public void test_setError() throws Exception {
-        MockPrintWriter os = new MockPrintWriter(new ByteArrayOutputStream());
-        assertFalse("Test 1: Error flag should not be set.", os.checkError());
-        os.setError();
-        assertTrue("Test 2: Error flag should be set.", os.checkError());
+    public void test_clearError() {
+        // Test for method boolean java.io.PrintWriter.clearError()
+        MockPrintWriter mpw = new MockPrintWriter(new ByteArrayOutputStream(), false);
+        mpw.close();
+        mpw.print(490000000000.08765);
+        assertTrue("Failed to return error", mpw.checkError());
+        mpw.clearError();
+        assertFalse("Internal error state has not be cleared", mpw.checkError());
     }
     
-    /**
-     * @tests java.io.PrintWriter#close()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "close",
-        args = {}
-    )
-    public void test_close() {
-        // Test for method void java.io.PrintWriter.close()
-        pw.close();
-        pw.println("l");
-        assertTrue("Write on closed stream failed to generate error", pw
-                .checkError());
-    }
+	/**
+	 * @tests java.io.PrintWriter#close()
+	 */
+	public void test_close() {
+		// Test for method void java.io.PrintWriter.close()
+		pw.close();
+		pw.println("l");
+		assertTrue("Write on closed stream failed to generate error", pw
+				.checkError());
+	}
 
-    /**
-     * @tests java.io.PrintWriter#flush()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "flush",
-        args = {}
-    )
-    public void test_flush() {
-        // Test for method void java.io.PrintWriter.flush()
-        final double dub = 490000000000.08765;
-        pw.print(dub);
-        pw.flush();
-        assertTrue("Failed to flush", new String(baos.toByteArray())
-                .equals(String.valueOf(dub)));
-    }
+	/**
+	 * @tests java.io.PrintWriter#flush()
+	 */
+	public void test_flush() {
+		// Test for method void java.io.PrintWriter.flush()
+		final double dub = 490000000000.08765;
+		pw.print(dub);
+		pw.flush();
+		assertTrue("Failed to flush", new String(bao.toByteArray())
+				.equals(String.valueOf(dub)));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(char[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {char[].class}
-    )
-    public void test_print$C() {
-        // Test for method void java.io.PrintWriter.print(char [])
-        String s = null;
-        char[] schars = new char[11];
-        "Hello World".getChars(0, 11, schars, 0);
-        pw.print(schars);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char[] string: " + s, s
-                .equals("Hello World"));
-        int r = 0;
-        try {
-            pw.print((char[]) null);
-        } catch (NullPointerException e) {
-            r = 1;
-        }
-        assertEquals("null pointer exception for printing null char[] is not caught",
-                1, r);
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(char[])
+	 */
+	public void test_print$C() {
+		// Test for method void java.io.PrintWriter.print(char [])
+		String s = null;
+		char[] schars = new char[11];
+		"Hello World".getChars(0, 11, schars, 0);
+		pw.print(schars);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char[] string: " + s, s
+				.equals("Hello World"));
+		int r = 0;
+		try {
+			pw.print((char[]) null);
+		} catch (NullPointerException e) {
+			r = 1;
+		}
+		assertEquals("null pointer exception for printing null char[] is not caught",
+				1, r);
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(char)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {char.class}
-    )
-    public void test_printC() {
-        // Test for method void java.io.PrintWriter.print(char)
-        pw.print('c');
-        pw.flush();
-        assertEquals("Wrote incorrect char string", "c", new String(baos.toByteArray())
-                );
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(char)
+	 */
+	public void test_printC() {
+		// Test for method void java.io.PrintWriter.print(char)
+		pw.print('c');
+		pw.flush();
+		assertEquals("Wrote incorrect char string", "c", new String(bao.toByteArray())
+				);
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {double.class}
-    )
-    public void test_printD() {
-        // Test for method void java.io.PrintWriter.print(double)
-        final double dub = 490000000000.08765;
-        pw.print(dub);
-        pw.flush();
-        assertTrue("Wrote incorrect double string", new String(baos
-                .toByteArray()).equals(String.valueOf(dub)));
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(double)
+	 */
+	public void test_printD() {
+		// Test for method void java.io.PrintWriter.print(double)
+		final double dub = 490000000000.08765;
+		pw.print(dub);
+		pw.flush();
+		assertTrue("Wrote incorrect double string", new String(bao
+				.toByteArray()).equals(String.valueOf(dub)));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {float.class}
-    )
-    public void test_printF() {
-        // Test for method void java.io.PrintWriter.print(float)
-        final float flo = 49.08765f;
-        pw.print(flo);
-        pw.flush();
-        assertTrue("Wrote incorrect float string",
-                new String(baos.toByteArray()).equals(String.valueOf(flo)));
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(float)
+	 */
+	public void test_printF() {
+		// Test for method void java.io.PrintWriter.print(float)
+		final float flo = 49.08765f;
+		pw.print(flo);
+		pw.flush();
+		assertTrue("Wrote incorrect float string",
+				new String(bao.toByteArray()).equals(String.valueOf(flo)));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {int.class}
-    )
-    public void test_printI() {
-        // Test for method void java.io.PrintWriter.print(int)
-        pw.print(4908765);
-        pw.flush();
-        assertEquals("Wrote incorrect int string", "4908765", new String(baos.toByteArray())
-                );
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(int)
+	 */
+	public void test_printI() {
+		// Test for method void java.io.PrintWriter.print(int)
+		pw.print(4908765);
+		pw.flush();
+		assertEquals("Wrote incorrect int string", "4908765", new String(bao.toByteArray())
+				);
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {long.class}
-    )
-    public void test_printJ() {
-        // Test for method void java.io.PrintWriter.print(long)
-        pw.print(49087650000L);
-        pw.flush();
-        assertEquals("Wrote incorrect long string", "49087650000", new String(baos.toByteArray())
-                );
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(long)
+	 */
+	public void test_printJ() {
+		// Test for method void java.io.PrintWriter.print(long)
+		pw.print(49087650000L);
+		pw.flush();
+		assertEquals("Wrote incorrect long string", "49087650000", new String(bao.toByteArray())
+				);
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(java.lang.Object)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {java.lang.Object.class}
-    )
-    public void test_printLjava_lang_Object() {
-        // Test for method void java.io.PrintWriter.print(java.lang.Object)
-        pw.print((Object) null);
-        pw.flush();
-        assertEquals("Did not write null", "null", new String(baos.toByteArray()));
-        baos.reset();
+	/**
+	 * @tests java.io.PrintWriter#print(java.lang.Object)
+	 */
+	public void test_printLjava_lang_Object() {
+		// Test for method void java.io.PrintWriter.print(java.lang.Object)
+		pw.print((Object) null);
+		pw.flush();
+		assertEquals("Did not write null", "null", new String(bao.toByteArray())
+				);
+		bao.reset();
 
-        pw.print(new Bogus());
-        pw.flush();
-        assertEquals("Wrote in incorrect Object string", "Bogus", new String(baos
-                .toByteArray()));
-    }
+		pw.print(new Bogus());
+		pw.flush();
+		assertEquals("Wrote in incorrect Object string", "Bogus", new String(bao
+				.toByteArray()));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {java.lang.String.class}
-    )
-    public void test_printLjava_lang_String() {
-        // Test for method void java.io.PrintWriter.print(java.lang.String)
-        pw.print((String) null);
-        pw.flush();
-        assertEquals("did not write null", "null", new String(baos.toByteArray()));
-        baos.reset();
+	/**
+	 * @tests java.io.PrintWriter#print(java.lang.String)
+	 */
+	public void test_printLjava_lang_String() {
+		// Test for method void java.io.PrintWriter.print(java.lang.String)
+		pw.print((String) null);
+		pw.flush();
+		assertEquals("did not write null", "null", new String(bao.toByteArray())
+				);
+		bao.reset();
 
-        pw.print("Hello World");
-        pw.flush();
-        assertEquals("Wrote incorrect  string", "Hello World", new String(baos.toByteArray()));
-    }
+		pw.print("Hello World");
+		pw.flush();
+		assertEquals("Wrote incorrect  string", "Hello World", new String(bao.toByteArray())
+				);
+	}
 
-    /**
-     * @tests java.io.PrintWriter#print(boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "print",
-        args = {boolean.class}
-    )
-    public void test_printZ() {
-        // Test for method void java.io.PrintWriter.print(boolean)
-        pw.print(true);
-        pw.flush();
-        assertEquals("Wrote in incorrect boolean string", "true", new String(baos
-                .toByteArray()));
-    }
+	/**
+	 * @tests java.io.PrintWriter#print(boolean)
+	 */
+	public void test_printZ() {
+		// Test for method void java.io.PrintWriter.print(boolean)
+		pw.print(true);
+		pw.flush();
+		assertEquals("Wrote in incorrect boolean string", "true", new String(bao
+				.toByteArray()));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {}
-    )
-    public void test_println() {
-        // Test for method void java.io.PrintWriter.println()
-        String s;
-        pw.println("Blarg");
-        pw.println();
-        pw.println("Bleep");
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-            assertTrue("Wrote incorrect line: " + s, s.equals("Blarg"));
-            s = br.readLine();
-            assertTrue("Wrote incorrect line: " + s, s.equals(""));
-            s = br.readLine();
-            assertTrue("Wrote incorrect line: " + s, s.equals("Bleep"));
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-    }
+	/**
+	 * @tests java.io.PrintWriter#println()
+	 */
+	public void test_println() {
+		// Test for method void java.io.PrintWriter.println()
+		String s;
+		pw.println("Blarg");
+		pw.println();
+		pw.println("Bleep");
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+			assertTrue("Wrote incorrect line: " + s, s.equals("Blarg"));
+			s = br.readLine();
+			assertTrue("Wrote incorrect line: " + s, s.equals(""));
+			s = br.readLine();
+			assertTrue("Wrote incorrect line: " + s, s.equals("Bleep"));
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(char[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {char[].class}
-    )
-    public void test_println$C() {
-        // Test for method void java.io.PrintWriter.println(char [])
-        String s = null;
-        char[] schars = new char[11];
-        "Hello World".getChars(0, 11, schars, 0);
-        pw.println("Random Chars");
-        pw.println(schars);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char[] string: " + s, s
-                .equals("Hello World"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(char[])
+	 */
+	public void test_println$C() {
+		// Test for method void java.io.PrintWriter.println(char [])
+		String s = null;
+		char[] schars = new char[11];
+		"Hello World".getChars(0, 11, schars, 0);
+		pw.println("Random Chars");
+		pw.println(schars);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char[] string: " + s, s
+				.equals("Hello World"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(char)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {char.class}
-    )
-    public void test_printlnC() {
-        // Test for method void java.io.PrintWriter.println(char)
-        String s = null;
-        pw.println("Random Chars");
-        pw.println('c');
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            s = br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char string: " + s, s.equals("c"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(char)
+	 */
+	public void test_printlnC() {
+		// Test for method void java.io.PrintWriter.println(char)
+		String s = null;
+		pw.println("Random Chars");
+		pw.println('c');
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			s = br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char string: " + s, s.equals("c"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(double)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {double.class}
-    )
-    public void test_printlnD() {
-        // Test for method void java.io.PrintWriter.println(double)
-        String s = null;
-        final double dub = 4000000000000000.657483;
-        pw.println("Random Chars");
-        pw.println(dub);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect double string: " + s, s.equals(String
-                .valueOf(dub)));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(double)
+	 */
+	public void test_printlnD() {
+		// Test for method void java.io.PrintWriter.println(double)
+		String s = null;
+		final double dub = 4000000000000000.657483;
+		pw.println("Random Chars");
+		pw.println(dub);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect double string: " + s, s.equals(String
+				.valueOf(dub)));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(float)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {float.class}
-    )
-    public void test_printlnF() {
-        // Test for method void java.io.PrintWriter.println(float)
-        String s;
-        final float flo = 40.4646464f;
-        pw.println("Random Chars");
-        pw.println(flo);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-            assertTrue("Wrote incorrect float string: " + s + " wanted: "
-                    + String.valueOf(flo), s.equals(String.valueOf(flo)));
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
+	/**
+	 * @tests java.io.PrintWriter#println(float)
+	 */
+	public void test_printlnF() {
+		// Test for method void java.io.PrintWriter.println(float)
+		String s;
+		final float flo = 40.4646464f;
+		pw.println("Random Chars");
+		pw.println(flo);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+			assertTrue("Wrote incorrect float string: " + s + " wanted: "
+					+ String.valueOf(flo), s.equals(String.valueOf(flo)));
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
 
-    }
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {int.class}
-    )
-    public void test_printlnI() {
-        // Test for method void java.io.PrintWriter.println(int)
-        String s = null;
-        pw.println("Random Chars");
-        pw.println(400000);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect int string: " + s, s.equals("400000"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(int)
+	 */
+	public void test_printlnI() {
+		// Test for method void java.io.PrintWriter.println(int)
+		String s = null;
+		pw.println("Random Chars");
+		pw.println(400000);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect int string: " + s, s.equals("400000"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(long)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {long.class}
-    )
-    public void test_printlnJ() {
-        // Test for method void java.io.PrintWriter.println(long)
-        String s = null;
-        pw.println("Random Chars");
-        pw.println(4000000000000L);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect long string: " + s, s
-                .equals("4000000000000"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(long)
+	 */
+	public void test_printlnJ() {
+		// Test for method void java.io.PrintWriter.println(long)
+		String s = null;
+		pw.println("Random Chars");
+		pw.println(4000000000000L);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect long string: " + s, s
+				.equals("4000000000000"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(java.lang.Object)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {java.lang.Object.class}
-    )
-    public void test_printlnLjava_lang_Object() {
-        // Test for method void java.io.PrintWriter.println(java.lang.Object)
-        String s = null;
-        pw.println("Random Chars");
-        pw.println(new Bogus());
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect Object string: " + s, s.equals("Bogus"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(java.lang.Object)
+	 */
+	public void test_printlnLjava_lang_Object() {
+		// Test for method void java.io.PrintWriter.println(java.lang.Object)
+		String s = null;
+		pw.println("Random Chars");
+		pw.println(new Bogus());
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect Object string: " + s, s.equals("Bogus"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {java.lang.String.class}
-    )
-    public void test_printlnLjava_lang_String() {
-        // Test for method void java.io.PrintWriter.println(java.lang.String)
-        String s = null;
-        pw.println("Random Chars");
-        pw.println("Hello World");
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect string: " + s, s.equals("Hello World"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(java.lang.String)
+	 */
+	public void test_printlnLjava_lang_String() {
+		// Test for method void java.io.PrintWriter.println(java.lang.String)
+		String s = null;
+		pw.println("Random Chars");
+		pw.println("Hello World");
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect string: " + s, s.equals("Hello World"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#println(boolean)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "println",
-        args = {boolean.class}
-    )
-    public void test_printlnZ() {
-        // Test for method void java.io.PrintWriter.println(boolean)
-        String s = null;
-        pw.println("Random Chars");
-        pw.println(false);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect boolean string: " + s, s.equals("false"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#println(boolean)
+	 */
+	public void test_printlnZ() {
+		// Test for method void java.io.PrintWriter.println(boolean)
+		String s = null;
+		pw.println("Random Chars");
+		pw.println(false);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect boolean string: " + s, s.equals("false"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#write(char[])
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {char[].class}
-    )
-    public void test_write$C() {
-        // Test for method void java.io.PrintWriter.write(char [])
-        String s = null;
-        char[] schars = new char[11];
-        "Hello World".getChars(0, 11, schars, 0);
-        pw.println("Random Chars");
-        pw.write(schars);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test: " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char[] string: " + s, s
-                .equals("Hello World"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#write(char[])
+	 */
+	public void test_write$C() {
+		// Test for method void java.io.PrintWriter.write(char [])
+		String s = null;
+		char[] schars = new char[11];
+		"Hello World".getChars(0, 11, schars, 0);
+		pw.println("Random Chars");
+		pw.write(schars);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test: " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char[] string: " + s, s
+				.equals("Hello World"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#write(char[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "write",
-        args = {char[].class, int.class, int.class}
-    )
-    public void test_write$CII() {
-        // Test for method void java.io.PrintWriter.write(char [], int, int)
-        String s = null;
-        char[] schars = new char[11];
-        "Hello World".getChars(0, 11, schars, 0);
-        pw.println("Random Chars");
-        pw.write(schars, 6, 5);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char[] string: " + s, s.equals("World"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#write(char[], int, int)
+	 */
+	public void test_write$CII() {
+		// Test for method void java.io.PrintWriter.write(char [], int, int)
+		String s = null;
+		char[] schars = new char[11];
+		"Hello World".getChars(0, 11, schars, 0);
+		pw.println("Random Chars");
+		pw.write(schars, 6, 5);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char[] string: " + s, s.equals("World"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#write(char[], int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "write",
-        args = {char[].class, int.class, int.class}
-    )
-    public void test_write$CII_Exception() {
-        // Test for method void java.io.PrintWriter.write(char [], int, int)
-        char[] chars = new char[10];
-        try {
-            pw.write(chars, 0, -1);
-            fail("IndexOutOfBoundsException was not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-        try {
-            pw.write(chars, -1, 1);
-            fail("IndexOutOfBoundsException was not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-        try {
-            pw.write(chars, 10, 1);
-            fail("IndexOutOfBoundsException was not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // Expected
-        }
-    }
+	/**
+	 * @tests java.io.PrintWriter#write(int)
+	 */
+	public void test_writeI() throws IOException {
+		// Test for method void java.io.PrintWriter.write(int)
+		char[] cab = new char[3];
+		pw.write('a');
+		pw.write('b');
+		pw.write('c');
+		pw.flush();
+		InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(bao.toByteArray()));
+		cab[0] = (char) isr.read();
+		cab[1] = (char) isr.read();
+		cab[2] = (char) isr.read();
+		assertTrue("Wrote incorrect ints", cab[0] == 'a' && cab[1] == 'b'
+				&& cab[2] == 'c');
 
-    /**
-     * @tests java.io.PrintWriter#write(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {int.class}
-    )
-    public void test_writeI() {
-        // Test for method void java.io.PrintWriter.write(int)
-        char[] cab = new char[3];
-        pw.write('a');
-        pw.write('b');
-        pw.write('c');
-        pw.flush();
-        bai = new ByteArrayInputStream(baos.toByteArray());
-        cab[0] = (char) bai.read();
-        cab[1] = (char) bai.read();
-        cab[2] = (char) bai.read();
-        assertTrue("Wrote incorrect ints", cab[0] == 'a' && cab[1] == 'b'
-                && cab[2] == 'c');
+	}
 
-    }
+	/**
+	 * @tests java.io.PrintWriter#write(java.lang.String)
+	 */
+	public void test_writeLjava_lang_String() {
+		// Test for method void java.io.PrintWriter.write(java.lang.String)
+		String s = null;
+		pw.println("Random Chars");
+		pw.write("Hello World");
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char[] string: " + s, s
+				.equals("Hello World"));
+	}
 
-    /**
-     * @tests java.io.PrintWriter#write(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {java.lang.String.class}
-    )
-    public void test_writeLjava_lang_String() {
-        // Test for method void java.io.PrintWriter.write(java.lang.String)
-        String s = null;
-        pw.println("Random Chars");
-        pw.write("Hello World");
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char[] string: " + s, s
-                .equals("Hello World"));
-    }
+	/**
+	 * @tests java.io.PrintWriter#write(java.lang.String, int, int)
+	 */
+	public void test_writeLjava_lang_StringII() {
+		// Test for method void java.io.PrintWriter.write(java.lang.String, int,
+		// int)
+		String s = null;
+		pw.println("Random Chars");
+		pw.write("Hello World", 6, 5);
+		pw.flush();
+		try {
+			br = new BufferedReader(new Support_StringReader(bao.toString()));
+			br.readLine();
+			s = br.readLine();
+		} catch (IOException e) {
+			fail("IOException during test : " + e.getMessage());
+		}
+		assertTrue("Wrote incorrect char[] string: " + s, s.equals("World"));
+	}
+	
+	/**
+	 * @tests java.io.PrintWriter#append(char)
+	 */
+	public void test_appendChar() {
+	char testChar = ' ';
+	ByteArrayOutputStream out = new ByteArrayOutputStream();
+	PrintWriter printWriter = new PrintWriter(out);
+	printWriter.append(testChar);
+	printWriter.flush();
+	assertEquals(String.valueOf(testChar),out.toString());
+	printWriter.close();
+	}
+	/**
+	 * @tests java.io.PrintWriter#append(CharSequence)
+	 */
+	public void test_appendCharSequence() {
+		
+		String testString = "My Test String";
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		PrintWriter printWriter = new PrintWriter(out);
+		printWriter.append(testString);
+		printWriter.flush();
+		assertEquals(testString, out.toString());
+		printWriter.close();	
 
-    /**
-     * @tests java.io.PrintWriter#write(java.lang.String, int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "write",
-        args = {java.lang.String.class, int.class, int.class}
-    )
-    public void test_writeLjava_lang_StringII() {
-        // Test for method void java.io.PrintWriter.write(java.lang.String, int,
-        // int)
-        String s = null;
-        pw.println("Random Chars");
-        pw.write("Hello World", 6, 5);
-        pw.flush();
-        try {
-            br = new BufferedReader(new Support_StringReader(baos.toString()));
-            br.readLine();
-            s = br.readLine();
-        } catch (IOException e) {
-            fail("IOException during test : " + e.getMessage());
-        }
-        assertTrue("Wrote incorrect char[] string: " + s, s.equals("World"));
-    }
-    
-    /**
-     * @tests java.io.PrintWriter#append(char)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {char.class}
-    )
-    public void test_appendChar() {
-    char testChar = ' ';
-    ByteArrayOutputStream out = new ByteArrayOutputStream();
-    PrintWriter printWriter = new PrintWriter(out);
-    printWriter.append(testChar);
-    printWriter.flush();
-    assertEquals(String.valueOf(testChar),out.toString());
-    printWriter.close();
-    }
-    /**
-     * @tests java.io.PrintWriter#append(CharSequence)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class}
-    )
-    public void test_appendCharSequence() {
-        
-        String testString = "My Test String";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        PrintWriter printWriter = new PrintWriter(out);
-        printWriter.append(testString);
-        printWriter.flush();
-        assertEquals(testString, out.toString());
-        printWriter.close();    
+	}
 
-    }
+	/**
+	 *  @tests java.io.PrintWriter#append(CharSequence, int, int)
+	 */
+	public void test_appendCharSequenceIntInt() {
+		String testString = "My Test String";
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		PrintWriter printWriter = new PrintWriter(out);
+		printWriter.append(testString, 1, 3);
+		printWriter.flush();
+		assertEquals(testString.substring(1, 3), out.toString());
+		printWriter.close();
 
-    /**
-     *  @tests java.io.PrintWriter#append(CharSequence, int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "append",
-        args = {java.lang.CharSequence.class, int.class, int.class}
-    )
-    public void test_appendCharSequenceIntInt() {
-        String testString = "My Test String";
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        PrintWriter printWriter = new PrintWriter(out);
-        printWriter.append(testString, 1, 3);
-        printWriter.flush();
-        assertEquals(testString.substring(1, 3), out.toString());
-        try {
-            printWriter.append(testString, 4, 100);
-            fail("IndexOutOfBoundsException not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
-        try {
-            printWriter.append(testString, 100, 1);
-            fail("IndexOutOfBoundsException not thrown");
-        } catch (IndexOutOfBoundsException e) {
-            // expected
-        }
-        printWriter.close();
-    }
+	}
 
     /**
      * @tests java.io.PrintWriter#format(java.lang.String, java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_formatLjava_lang_String$Ljava_lang_Object() {
-        PrintWriter tobj;
-        
-        tobj = new PrintWriter(baos, false);
-        tobj.format("%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        byte[] rbytes = new byte[11];
-        bis.read(rbytes, 0, rbytes.length);
-        assertEquals("Wrote incorrect string", "Hello World",
-                new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        tobj.format("%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        try {
-            tobj.format("%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format("%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format("%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
+        pw.format("%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World", 
+                new String(bao.toByteArray()));
     }
 
     /**
      * @tests java.io.PrintWriter#format(java.util.Locale, java.lang.String, java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "format",
-        args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_formatLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
-        Locale[] requiredLocales = {Locale.US, Locale.GERMANY};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(baos, false);
-        tobj.format(Locale.US, "%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        byte[] rbytes = new byte[11];
-        bis.read(rbytes, 0, rbytes.length);
-        assertEquals("Wrote incorrect string", "Hello World",
-                new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        tobj.format(Locale.GERMANY, "%1$.3G; %1$.5f; 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1,23E+04; 12345,67800; 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        tobj.format(Locale.US, "%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        try {
-            tobj.format(Locale.US, "%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format(Locale.US, "%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.format(Locale.US, "%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
+        pw.format(Locale.US, "%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World", 
+                new String(bao.toByteArray()));
     }
 
     /**
      * @tests java.io.PrintWriter#printf(java.lang.String, java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "printf",
-        args = {java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_printfLjava_lang_String$Ljava_lang_Object() {
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(baos, false);
-        tobj.printf("%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        byte[] rbytes = new byte[11];
-        bis.read(rbytes, 0, rbytes.length);
-        assertEquals("Wrote incorrect string", "Hello World",
-                new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        tobj.printf("%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        try {
-            tobj.printf("%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf("%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf("%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
+        pw.printf("%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World", 
+                new String(bao.toByteArray()));
     }
 
     /**
      * @tests java.io.PrintWriter#printf(java.util.Locale, java.lang.String, java.lang.Object...)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "printf",
-        args = {java.util.Locale.class, java.lang.String.class, java.lang.Object[].class}
-    )
     public void test_printfLjava_util_Locale_Ljava_lang_String_$Ljava_lang_Object() {
-        Locale[] requiredLocales = {Locale.US, Locale.GERMANY};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        PrintWriter tobj;
-
-        tobj = new PrintWriter(baos, false);
-        tobj.printf(Locale.US, "%s %s", "Hello", "World");
-        tobj.flush();
-        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
-        byte[] rbytes = new byte[11];
-        bis.read(rbytes, 0, rbytes.length);
-        assertEquals("Wrote incorrect string", "Hello World",
-                new String(rbytes));
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        tobj.printf(Locale.GERMANY, "%1$.3G; %1$.5f; 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1,23E+04; 12345,67800; 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        tobj.printf(Locale.US, "%1$.3G, %1$.5f, 0%2$xx", 12345.678, 123456);
-        tobj.flush();
-        assertEquals("Wrong output!", "1.23E+04, 12345.67800, 01e240x", new String(baos.toByteArray()));
-        tobj.close();
-
-        baos.reset();
-        tobj = new PrintWriter(baos);
-        try {
-            tobj.printf(Locale.US, "%1$.3G, %1$x", 12345.678);
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf(Locale.US, "%s %q", "Hello", "World");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
-
-        try {
-            tobj.printf(Locale.US, "%s %s", "Hello");
-            fail("IllegalFormatException not thrown");
-        } catch (IllegalFormatException e) {
-            // expected
-        }
+        pw.printf(Locale.US, "%s %s", "Hello", "World");
+        pw.flush();
+        assertEquals("Wrote incorrect string", "Hello World", 
+                new String(bao.toByteArray()));
     }
 
-    /**
-     * Sets up the fixture, for example, open a network connection. This method
-     * is called before a test is executed.
-     */
-    @Override
-    protected void setUp() throws Exception {
-        testFile = File.createTempFile("test", null);
-        testFilePath = testFile.getAbsolutePath();
-        pw = new PrintWriter(baos, false);
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		bao = new ByteArrayOutputStream();
+		pw = new PrintWriter(bao, false);
 
-    }
+	}
 
-    /**
-     * Tears down the fixture, for example, close a network connection. This
-     * method is called after a test is executed.
-     */
-    @Override
-    protected void tearDown() throws Exception {
-        testFile.delete();
-        testFile = null;
-        testFilePath = null;
-        try {
-            pw.close();
-        } catch (Exception e) {
-        }
-    }
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+		try {
+			pw.close();
+		} catch (Exception e) {
+		}
+	}
 }
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
index a8621a1..ebfe013 100644
--- a/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest1.java
@@ -1354,7 +1354,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("nested writeReplace is not handled")
     public void test_18_28_writeObject() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.lang.Object)
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
index d3bbc29..71da321 100644
--- a/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest2.java
@@ -1419,7 +1419,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("Executed replacement when it should not: class java.lang.String")
     public void test_18_57_writeObject() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1457,7 +1456,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("Executed replacement when it should not: class java.lang.String")
     public void test_18_58_writeObject() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.lang.Object)
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
index ba83ab6..f704819 100644
--- a/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest3.java
@@ -1483,7 +1483,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("Serialization of SimpleDateFormat object fails")
     public void test_18_113_writeObject() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.lang.Object)
@@ -1552,7 +1551,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("Serialization of NumberFormat object fails")
     public void test_18_115_writeObject() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.lang.Object)
diff --git a/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java b/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
index 3b1a063..61399fa 100644
--- a/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
+++ b/luni/src/test/java/tests/api/java/io/SerializationStressTest4.java
@@ -2667,6 +2667,7 @@
         method = "!Serialization",
         args = {}
     )
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void test_writeObject_Proxy()
             throws ClassNotFoundException, IOException {
 
@@ -2849,7 +2850,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("deserialization of a date fomat field seems to fail")
     public void test_writeObject_DateFormat_Field() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.text.DateFormat.Field)
@@ -2894,7 +2894,6 @@
         method = "!Serialization",
         args = {}
     )
-    @KnownFailure("deserialization of a number fomat field seems to fail")
     public void test_writeObject_NumberFormat_Field() {
         // Test for method void
         // java.io.ObjectOutputStream.writeObject(java.text.NumberFormat.Field)
diff --git a/luni/src/test/java/tests/api/java/lang/AllTests.java b/luni/src/test/java/tests/api/java/lang/AllTests.java
index 5a70224..26e313c 100644
--- a/luni/src/test/java/tests/api/java/lang/AllTests.java
+++ b/luni/src/test/java/tests/api/java/lang/AllTests.java
@@ -24,13 +24,8 @@
  * TODO Type description
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Test for java.lang");
+        TestSuite suite = new TestSuite("Test for java.lang");
 
         // $JUnit-BEGIN$
         
diff --git a/luni/src/test/java/tests/api/java/lang/ref/AllTests.java b/luni/src/test/java/tests/api/java/lang/ref/AllTests.java
index 75b7b9f..a21d3d8 100644
--- a/luni/src/test/java/tests/api/java/lang/ref/AllTests.java
+++ b/luni/src/test/java/tests/api/java/lang/ref/AllTests.java
@@ -24,13 +24,8 @@
  * TODO Type description
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Test for java.lang.ref");
+        TestSuite suite = new TestSuite("Test for java.lang.ref");
 
         // $JUnit-BEGIN$
         
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/AllTests.java b/luni/src/test/java/tests/api/java/lang/reflect/AllTests.java
index bba0915..dd427e1 100644
--- a/luni/src/test/java/tests/api/java/lang/reflect/AllTests.java
+++ b/luni/src/test/java/tests/api/java/lang/reflect/AllTests.java
@@ -24,13 +24,8 @@
  * TODO Type description
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Test for java.lang.reflect");
+        TestSuite suite = new TestSuite("Test for java.lang.reflect");
 
         // $JUnit-BEGIN$
         suite.addTestSuite(AccessibleObjectTest.class);
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java
index 8919652..f09d5cf 100644
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java
+++ b/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java
@@ -169,6 +169,7 @@
         )
     })
     @SuppressWarnings("unchecked")
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void testMultipleBoundedWildcardUnEquality() throws Exception {
         Class<? extends MultipleBoundedWildcardUnEquality> clazz = MultipleBoundedWildcardUnEquality.class;
 
@@ -238,6 +239,7 @@
         )
     })
     @SuppressWarnings("unchecked")
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void testMultipleBoundedWildcard() throws Exception {
         Class<? extends MultipleBoundedWildcardEquality> clazz = MultipleBoundedWildcardEquality.class;
 
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java
index 7db5dbe..052e3172 100644
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java
+++ b/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java
@@ -201,6 +201,7 @@
         args = {}
     )
     @SuppressWarnings("unchecked")
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void testSimpleInheritance() throws Exception {
         Class<? extends SimpleInheritance> clazz = SimpleInheritance.class;
         TypeVariable<Class> subTypeVariable = getTypeParameter(clazz);
diff --git a/luni/src/test/java/tests/api/java/net/AllTests.java b/luni/src/test/java/tests/api/java/net/AllTests.java
index 10dd9d8..257a166 100644
--- a/luni/src/test/java/tests/api/java/net/AllTests.java
+++ b/luni/src/test/java/tests/api/java/net/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.java.net;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.java.net;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AuthenticatorRequestorTypeTest.class);
@@ -46,7 +41,8 @@
         suite.addTestSuite(DatagramSocketTest.class);
         suite.addTestSuite(ExcludedProxyTest.class);
         suite.addTestSuite(FileNameMapTest.class);
-        suite.addTestSuite(HttpRetryExceptionTest.class);
+	suite.addTestSuite(HttpRetryExceptionTest.class);
+        suite.addTestSuite(IDNTest.class);
         suite.addTestSuite(JarURLConnectionTest.class);
         suite.addTestSuite(MalformedURLExceptionTest.class);
         suite.addTestSuite(MulticastSocketTest.class);
diff --git a/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java b/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
index 256c5ba..89f9f3c 100644
--- a/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
+++ b/luni/src/test/java/tests/api/java/net/CookieHandlerTest.java
@@ -157,7 +157,6 @@
             args = {java.net.URI.class, java.util.Map.class}
         )
     })
-    @KnownFailure("Cache is not used")
     public void test_get_put() {
         MockCookieHandler mch = new MockCookieHandler();
         CookieHandler defaultHandler = CookieHandler.getDefault();
diff --git a/luni/src/test/java/tests/api/java/net/IDNTest.java b/luni/src/test/java/tests/api/java/net/IDNTest.java
new file mode 100644
index 0000000..7ea209c
--- /dev/null
+++ b/luni/src/test/java/tests/api/java/net/IDNTest.java
@@ -0,0 +1,160 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.net;
+
+import java.net.IDN;
+
+import junit.framework.TestCase;
+
+public class IDNTest extends TestCase {
+
+	/**
+	 * @tests {@link java.net.IDN#toASCII(String)}
+	 * 
+	 * @since 1.6
+	 */
+	public void test_ToASCII_LString() {
+		try {
+			IDN.toASCII(null);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+
+		try {
+			IDN.toASCII("www.m\uE400kitorppa.edu");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+
+		try {
+			IDN.toASCII("www.\u672C\uFE73\uFFFF.jp");
+			fail("should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+
+		assertEquals("www.xn--gwtq9nb2a.jp", IDN
+				.toASCII("www.\u65E5\u672C\u5E73.jp"));
+		assertEquals(
+				"www.xn--vckk7bxa0eza9ezc9d.com",
+				IDN
+						.toASCII("www.\u30CF\u30F3\u30C9\u30DC\u30FC\u30EB\u30B5\u30E0\u30BA.com"));
+		assertEquals("www.xn--frgbolaget-q5a.nu", IDN
+				.toASCII("www.f\u00E4rgbolaget.nu"));
+		assertEquals("www.xn--bcher-kva.de", IDN.toASCII("www.b\u00FCcher.de"));
+		assertEquals("www.xn--brndendekrlighed-vobh.com", IDN
+				.toASCII("www.br\u00E6ndendek\u00E6rlighed.com"));
+		assertEquals("www.xn--rksmrgs-5wao1o.se", IDN
+				.toASCII("www.r\u00E4ksm\u00F6rg\u00E5s.se"));
+		assertEquals("www.xn--9d0bm53a3xbzui.com", IDN
+				.toASCII("www.\uC608\uBE44\uAD50\uC0AC.com"));
+		assertEquals("xn--lck1c3crb1723bpq4a.com", IDN
+				.toASCII("\u7406\u5BB9\u30CA\u30AB\u30E0\u30E9.com"));
+		assertEquals("xn--l8je6s7a45b.org", IDN
+				.toASCII("\u3042\u30FC\u308B\u3044\u3093.org"));
+		assertEquals("www.xn--frjestadsbk-l8a.net", IDN
+				.toASCII("www.f\u00E4rjestadsbk.net"));
+		assertEquals("www.xn--mkitorppa-v2a.edu", IDN
+				.toASCII("www.m\u00E4kitorppa.edu"));
+	}
+
+	/**
+	 * @tests {@link java.net.IDN#toASCII(String, int)}
+	 * 
+	 * @since 1.6
+	 */
+	public void test_ToASCII_LString_I() {
+		try {
+			IDN.toASCII("www.br\u00E6ndendek\u00E6rlighed.com",
+					IDN.USE_STD3_ASCII_RULES);
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+
+		try {
+			IDN.toASCII("www.r\u00E4ksm\u00F6rg\u00E5s.se",
+					IDN.USE_STD3_ASCII_RULES);
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+
+		try {
+			IDN.toASCII("www.f\u00E4rjestadsbk.net", IDN.ALLOW_UNASSIGNED
+					| IDN.USE_STD3_ASCII_RULES);
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+
+		assertEquals("www.xn--gwtq9nb2a.jp", IDN.toASCII(
+				"www.\u65E5\u672C\u5E73.jp", 0));
+		assertEquals(
+				"www.xn--vckk7bxa0eza9ezc9d.com",
+				IDN
+						.toASCII(
+								"www.\u30CF\u30F3\u30C9\u30DC\u30FC\u30EB\u30B5\u30E0\u30BA.com",
+								0));
+		assertEquals("www.xn--frgbolaget-q5a.nu", IDN.toASCII(
+				"www.f\u00E4rgbolaget.nu", IDN.ALLOW_UNASSIGNED));
+		assertEquals("www.xn--bcher-kva.de", IDN.toASCII("www.b\u00FCcher.de",
+				IDN.ALLOW_UNASSIGNED));
+		assertEquals("www.google.com", IDN.toASCII("www.google\u002Ecom",
+				IDN.USE_STD3_ASCII_RULES));
+	}
+
+	/**
+	 * @tests {@link java.net.IDN#toUnicode(String)}
+	 * 
+	 * @since 1.6
+	 */
+	public void test_ToUnicode_LString() {
+		try {
+			IDN.toUnicode(null);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+
+		assertEquals("", IDN.toUnicode(""));
+		assertEquals("www.bcher.de", IDN.toUnicode("www.bcher.de"));
+		assertEquals("www.b\u00FCcher.de", IDN.toUnicode("www.b\u00FCcher.de"));
+		assertEquals("www.\u65E5\u672C\u5E73.jp", IDN
+				.toUnicode("www.\u65E5\u672C\u5E73.jp"));
+		assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode("www\uFF0Exn--gwtq9nb2a\uFF61jp"));
+		assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode("www.xn--gwtq9nb2a.jp"));
+	}
+
+	/**
+	 * @tests {@link java.net.IDN#toUnicode(String, int)}
+	 * 
+	 * @since 1.6
+	 */
+	public void test_ToUnicode_LString_I() {
+		assertEquals("", IDN.toUnicode("", IDN.ALLOW_UNASSIGNED));
+		assertEquals("www.f\u00E4rgbolaget.nu", IDN.toUnicode(
+				"www.f\u00E4rgbolaget.nu", IDN.USE_STD3_ASCII_RULES));
+		assertEquals("www.r\u00E4ksm\u00F6rg\u00E5s.nu", IDN.toUnicode(
+				"www.r\u00E4ksm\u00F6rg\u00E5s\u3002nu",
+				IDN.USE_STD3_ASCII_RULES));
+		// RI bug. It cannot parse "www.xn--gwtq9nb2a.jp" when
+		// USE_STD3_ASCII_RULES is set.
+		assertEquals("www.\u65E5\u672C\u5E73.jp", IDN.toUnicode(
+				"www\uFF0Exn--gwtq9nb2a\uFF61jp", IDN.USE_STD3_ASCII_RULES));
+		
+	}
+}
diff --git a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
index 018d58a..2959509 100644
--- a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
+++ b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
@@ -32,6 +32,7 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 
+import dalvik.annotation.KnownFailure;
 import tests.support.Support_NetworkInterface;
 import tests.support.Support_PortManager;
 
@@ -351,6 +352,7 @@
 	 * @throws InterruptedException 
 	 * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,java.net.NetworkInterface)
 	 */
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
 	public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws IOException, InterruptedException {
 		// security manager that allows us to check that we only return the
 		// addresses that we should
diff --git a/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java b/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java
index 0272af1..26960c4 100644
--- a/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java
+++ b/luni/src/test/java/tests/api/java/net/NetworkInterfaceTest.java
@@ -17,597 +17,545 @@
 
 package tests.api.java.net;
 
-import dalvik.annotation.TestTargetClass; 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.net.InetAddress;
+import java.net.InterfaceAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
-import java.security.Permission;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.List;
 
-@TestTargetClass(NetworkInterface.class) 
 public class NetworkInterfaceTest extends junit.framework.TestCase {
 
-    // private member variables used for tests
-    boolean atLeastOneInterface = false;
+	// private member variables used for tests
+    Enumeration<NetworkInterface> theInterfaces = null;
 
-    boolean atLeastTwoInterfaces = false;
+	boolean atLeastOneInterface = false;
 
-    private NetworkInterface networkInterface1 = null;
+	boolean atLeastTwoInterfaces = false;
 
-    private NetworkInterface sameAsNetworkInterface1 = null;
+	private NetworkInterface networkInterface1 = null;
 
-    private NetworkInterface networkInterface2 = null;
+	private NetworkInterface sameAsNetworkInterface1 = null;
 
-    /**
-     * @tests java.net.NetworkInterface#getName()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getName",
-        args = {}
-    )
-    public void test_getName() {
-        if (atLeastOneInterface) {
-            assertNotNull("validate that non null name is returned",
-                    networkInterface1.getName());
-            assertFalse("validate that non-zero length name is generated",
-                    networkInterface1.getName().equals(""));
-        }
-        if (atLeastTwoInterfaces) {
-            assertFalse(
-                    "Validate strings are different for different interfaces",
-                    networkInterface1.getName().equals(
-                            networkInterface2.getName()));
-        }
-    }
+	private NetworkInterface networkInterface2 = null;
 
-    /**
-     * @tests java.net.NetworkInterface#getInetAddresses()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInetAddresses",
-        args = {}
-    )
-    public void test_getInetAddresses() {
+	/**
+	 * @tests java.net.NetworkInterface#getName()
+	 */
+	public void test_getName() {
+		if (atLeastOneInterface) {
+			assertNotNull("validate that non null name is returned",
+					networkInterface1.getName());
+			assertFalse("validate that non-zero length name is generated",
+					networkInterface1.getName().equals(""));
+		}
+		if (atLeastTwoInterfaces) {
+			assertFalse(
+					"Validate strings are different for different interfaces",
+					networkInterface1.getName().equals(
+							networkInterface2.getName()));
+		}
+	}
 
-        // security manager that allows us to check that we only return the
-        // addresses that we should
-        class mySecurityManager extends SecurityManager {
+	/**
+	 * @tests java.net.NetworkInterface#getInetAddresses()
+	 */
+	public void test_getInetAddresses() throws Exception {
 
-            ArrayList disallowedNames = null;
+		// security manager that allows us to check that we only return the
+		// addresses that we should
+		class mySecurityManager extends SecurityManager {
 
-            public mySecurityManager(ArrayList addresses) {
-                disallowedNames = new ArrayList();
-                for (int i = 0; i < addresses.size(); i++) {
-                    disallowedNames.add(((InetAddress) addresses.get(i))
-                            .getHostName());
-                    disallowedNames.add(((InetAddress) addresses.get(i))
-                            .getHostAddress());
-                }
-            }
+			ArrayList disallowedNames = null;
 
-            public void checkConnect(String host, int port) {
+			public mySecurityManager(ArrayList addresses) {
+				disallowedNames = new ArrayList();
+				for (int i = 0; i < addresses.size(); i++) {
+					disallowedNames.add(((InetAddress) addresses.get(i))
+							.getHostName());
+					disallowedNames.add(((InetAddress) addresses.get(i))
+							.getHostAddress());
+				}
+			}
 
-                if (host == null) {
-                    throw new NullPointerException("host was null)");
-                }
+			public void checkConnect(String host, int port) {
 
-                for (int i = 0; i < disallowedNames.size(); i++) {
-                    if (((String) disallowedNames.get(i)).equals(host)) {
-                        throw new SecurityException("not allowed");
-                    }
-                }
-            }
+				if (host == null) {
+					throw new NullPointerException("host was null)");
+				}
 
-            public void checkPermission(Permission perm) {
-                // allow everything
-            }
-        }
+				for (int i = 0; i < disallowedNames.size(); i++) {
+					if (((String) disallowedNames.get(i)).equals(host)) {
+						throw new SecurityException("not allowed");
+					}
+				}
+			}
 
-        if (atLeastOneInterface) {
+		}
+
+		if (atLeastOneInterface) {
             Enumeration theAddresses = networkInterface1.getInetAddresses();
-            if (theAddresses != null) {
-                while (theAddresses.hasMoreElements()) {
-                    InetAddress theAddress = (InetAddress) theAddresses
-                            .nextElement();
-                    assertTrue("validate that address is not null",
-                            null != theAddress);
-                }
+            while (theAddresses.hasMoreElements()) {
+                InetAddress theAddress = (InetAddress) theAddresses
+                        .nextElement();
+                assertNotNull("validate that address is not null", theAddress);
             }
         }
 
-        if (atLeastTwoInterfaces) {
-            Enumeration theAddresses = networkInterface2.getInetAddresses();
-            if (theAddresses != null) {
-                while (theAddresses.hasMoreElements()) {
-                    InetAddress theAddress = (InetAddress) theAddresses
+		if (atLeastTwoInterfaces) {
+			Enumeration theAddresses = networkInterface2.getInetAddresses();
+			while (theAddresses.hasMoreElements()) {
+                InetAddress theAddress = (InetAddress) theAddresses
+                        .nextElement();
+                assertNotNull("validate that address is not null", theAddress);
+            }
+		}
+
+		// create the list of ok and not ok addresses to return
+		if (atLeastOneInterface) {
+			ArrayList okAddresses = new ArrayList();
+			Enumeration addresses = networkInterface1.getInetAddresses();
+			int index = 0;
+			ArrayList notOkAddresses = new ArrayList();
+			while (addresses.hasMoreElements()) {
+                InetAddress theAddress = (InetAddress) addresses.nextElement();
+                if (index != 0) {
+                    okAddresses.add(theAddress);
+                } else {
+                    notOkAddresses.add(theAddress);
+                }
+                index++;
+            }
+
+			// do the same for network interface 2 if it exists
+			if (atLeastTwoInterfaces) {
+				addresses = networkInterface2.getInetAddresses();
+				index = 0;
+				while (addresses.hasMoreElements()) {
+					InetAddress theAddress = (InetAddress) addresses
+							.nextElement();
+					if (index != 0) {
+						okAddresses.add(theAddress);
+					} else {
+						notOkAddresses.add(theAddress);
+					}
+					index++;
+				}
+			}
+
+			// set the security manager that will make the first address not
+			// visible
+			System.setSecurityManager(new mySecurityManager(notOkAddresses));
+
+			// validate not ok addresses are not returned
+			for (int i = 0; i < notOkAddresses.size(); i++) {
+				Enumeration reducedAddresses = networkInterface1
+						.getInetAddresses();
+				while (reducedAddresses.hasMoreElements()) {
+                    InetAddress nextAddress = (InetAddress) reducedAddresses
                             .nextElement();
-                    assertTrue("validate that address is not null",
-                            null != theAddress);
+                    assertTrue(
+                            "validate that address without permission is not returned",
+                            !nextAddress.equals(notOkAddresses.get(i)));
                 }
-            }
-        }
-
-        // create the list of ok and not ok addresses to return
-        if (atLeastOneInterface) {
-            ArrayList okAddresses = new ArrayList();
-            Enumeration addresses = networkInterface1.getInetAddresses();
-            int index = 0;
-            ArrayList notOkAddresses = new ArrayList();
-            if (addresses != null) {
-                while (addresses.hasMoreElements()) {
-                    InetAddress theAddress = (InetAddress) addresses
-                            .nextElement();
-                    if (index != 0) {
-                        okAddresses.add(theAddress);
-                    } else {
-                        notOkAddresses.add(theAddress);
-                    }
-                    index++;
-                }
-            }
-
-            // do the same for network interface 2 it it exists
-            if (atLeastTwoInterfaces) {
-                addresses = networkInterface2.getInetAddresses();
-                index = 0;
-                if (addresses != null) {
-                    while (addresses.hasMoreElements()) {
-                        InetAddress theAddress = (InetAddress) addresses
-                                .nextElement();
-                        if (index != 0) {
-                            okAddresses.add(theAddress);
-                        } else {
-                            notOkAddresses.add(theAddress);
-                        }
-                        index++;
-                    }
-                }
-            }
-
-            // set the security manager that will make the first address not
-            // visible
-            System.setSecurityManager(new mySecurityManager(notOkAddresses));
-
-            // validate not ok addresses are not returned
-            for (int i = 0; i < notOkAddresses.size(); i++) {
-                Enumeration reducedAddresses = networkInterface1
-                        .getInetAddresses();
-                if (reducedAddresses != null) {
-                    while (reducedAddresses.hasMoreElements()) {
-                        InetAddress nextAddress = (InetAddress) reducedAddresses
-                                .nextElement();
-                        assertTrue(
-                                "validate that address without permission is not returned",
-                                !nextAddress.equals(notOkAddresses.get(i)));
-                    }
-                }
-                if (atLeastTwoInterfaces) {
+				if (atLeastTwoInterfaces) {
                     reducedAddresses = networkInterface2.getInetAddresses();
-                    if (reducedAddresses != null) {
-                        while (reducedAddresses.hasMoreElements()) {
-                            InetAddress nextAddress = (InetAddress) reducedAddresses
-                                    .nextElement();
-                            assertTrue(
-                                    "validate that address without permission is not returned",
-                                    !nextAddress.equals(notOkAddresses.get(i)));
-                        }
+					while (reducedAddresses.hasMoreElements()) {
+						InetAddress nextAddress = (InetAddress) reducedAddresses
+								.nextElement();
+						assertTrue(
+								"validate that address without permission is not returned",
+								!nextAddress.equals(notOkAddresses.get(i)));
+					}
+				}
+			}
+
+			// validate that ok addresses are returned
+			for (int i = 0; i < okAddresses.size(); i++) {
+				boolean addressReturned = false;
+				Enumeration reducedAddresses = networkInterface1
+						.getInetAddresses();
+				while (reducedAddresses.hasMoreElements()) {
+                    InetAddress nextAddress = (InetAddress) reducedAddresses
+                            .nextElement();
+                    if (nextAddress.equals(okAddresses.get(i))) {
+                        addressReturned = true;
                     }
                 }
+				if (atLeastTwoInterfaces) {
+					reducedAddresses = networkInterface2.getInetAddresses();
+					while (reducedAddresses.hasMoreElements()) {
+						InetAddress nextAddress = (InetAddress) reducedAddresses
+								.nextElement();
+						if (nextAddress.equals(okAddresses.get(i))) {
+							addressReturned = true;
+						}
+					}
+				}
+				assertTrue("validate that address with permission is returned",
+						addressReturned);
+			}
+
+			// validate that we can get the interface by specifying the address.
+			// This is to be compatible
+			for (int i = 0; i < notOkAddresses.size(); i++) {
+                assertNotNull(
+                        "validate we cannot get the NetworkInterface with an address for which we have no privs",
+                        NetworkInterface
+                                .getByInetAddress((InetAddress) notOkAddresses
+                                        .get(i)));
             }
 
-            // validate that ok addresses are returned
-            for (int i = 0; i < okAddresses.size(); i++) {
-                boolean addressReturned = false;
-                Enumeration reducedAddresses = networkInterface1
-                        .getInetAddresses();
-                if (reducedAddresses != null) {
-                    while (reducedAddresses.hasMoreElements()) {
-                        InetAddress nextAddress = (InetAddress) reducedAddresses
-                                .nextElement();
-                        if (nextAddress.equals(okAddresses.get(i))) {
-                            addressReturned = true;
-                        }
-                    }
-                }
-                if (atLeastTwoInterfaces) {
-                    reducedAddresses = networkInterface2.getInetAddresses();
-                    if (reducedAddresses != null) {
-                        while (reducedAddresses.hasMoreElements()) {
-                            InetAddress nextAddress = (InetAddress) reducedAddresses
-                                    .nextElement();
-                            if (nextAddress.equals(okAddresses.get(i))) {
-                                addressReturned = true;
-                            }
-                        }
-                    }
-                }
-                assertTrue("validate that address with permission is returned",
-                        addressReturned);
+			// validate that we can get the network interface for the good
+			// addresses
+			for (int i = 0; i < okAddresses.size(); i++) {
+                assertNotNull(
+                        "validate we cannot get the NetworkInterface with an address fro which we have no privs",
+                        NetworkInterface
+                                .getByInetAddress((InetAddress) okAddresses
+                                        .get(i)));
             }
 
-            // validate that we can get the interface by specifying the address.
-            // This is to be compatible
-            for (int i = 0; i < notOkAddresses.size(); i++) {
-                try {
-                    assertNotNull(
-                            "validate we cannot get the NetworkInterface with an address for which we have no privs",
-                            NetworkInterface
-                                    .getByInetAddress((InetAddress) notOkAddresses
-                                            .get(i)));
-                } catch (Exception e) {
-                    fail("get NetworkInterface for address with no perm - exception");
-                }
-            }
+			System.setSecurityManager(null);
+		}
+	}
 
-            // validate that we can get the network interface for the good
-            // addresses
-            try {
-                for (int i = 0; i < okAddresses.size(); i++) {
-                    assertNotNull(
-                            "validate we cannot get the NetworkInterface with an address fro which we have no privs",
-                            NetworkInterface
-                                    .getByInetAddress((InetAddress) okAddresses
-                                            .get(i)));
-                }
-            } catch (Exception e) {
-                fail("get NetworkInterface for address with perm - exception");
-            }
+	/**
+	 * @tests java.net.NetworkInterface#getDisplayName()
+	 */
+	public void test_getDisplayName() {
+		if (atLeastOneInterface) {
+			assertNotNull("validate that non null display name is returned",
+					networkInterface1.getDisplayName());
+			assertFalse(
+					"validate that non-zero length display name is generated",
+					networkInterface1.getDisplayName().equals(""));
+		}
+		if (atLeastTwoInterfaces) {
+			assertFalse(
+					"Validate strings are different for different interfaces",
+					networkInterface1.getDisplayName().equals(
+							networkInterface2.getDisplayName()));
+		}
+	}
 
-            System.setSecurityManager(null);
-        }
-    }
-
-    /**
-     * @tests java.net.NetworkInterface#getDisplayName()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getDisplayName",
-        args = {}
-    )
-    public void test_getDisplayName() {
-        if (atLeastOneInterface) {
-            assertNotNull("validate that non null display name is returned",
-                    networkInterface1.getDisplayName());
-            assertFalse(
-                    "validate that non-zero lengtj display name is generated",
-                    networkInterface1.getDisplayName().equals(""));
-        }
-        if (atLeastTwoInterfaces) {
-            assertFalse(
-                    "Validate strings are different for different interfaces",
-                    networkInterface1.getDisplayName().equals(
-                            networkInterface2.getDisplayName()));
-        }
-    }
-
-    /**
-     * @tests java.net.NetworkInterface#getByName(java.lang.String)
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "SocketException checking missed.",
-        method = "getByName",
-        args = {java.lang.String.class}
-    )
-    public void test_getByNameLjava_lang_String() {
-        try {
-            assertNull("validate null handled ok",
+	/**
+	 * @tests java.net.NetworkInterface#getByName(java.lang.String)
+	 */
+	public void test_getByNameLjava_lang_String() throws Exception {
+		try {
+			assertNull("validate null handled ok",
                                    NetworkInterface.getByName(null));
-            fail("getByName did not throw NullPointerException for null argument");
-        } catch (NullPointerException e) {
-        } catch (Exception e) {
-            fail("getByName, null inetAddress - raised exception : "
-                    + e.getMessage());
-        }
+			fail("getByName did not throw NullPointerException for null argument");
+		} catch (NullPointerException e) {
+		} 
 
-        try {
-            assertNull("validate handled ok if we ask for name not associated with any interface",
-                                   NetworkInterface.getByName("8not a name4"));
-        } catch (Exception e) {
-            fail("getByName, unknown inetAddress - raised exception : "
-                    + e.getMessage());
-        }
+		assertNull("validate handled ok if we ask for name not associated with any interface",
+                                  NetworkInterface.getByName("8not a name4"));
 
-        // for each address in an interface validate that we get the right
-        // interface for that name
-        if (atLeastOneInterface) {
-            String theName = networkInterface1.getName();
-            if (theName != null) {
-                try {
-                    assertTrue(
-                            "validate that Interface can be obtained with its name",
-                            NetworkInterface.getByName(theName).equals(
-                                    networkInterface1));
-                } catch (Exception e) {
-                    fail("validate to get network interface using name - socket exception");
-                }
+		// for each address in an interface validate that we get the right
+		// interface for that name
+		if (atLeastOneInterface) {
+			String theName = networkInterface1.getName();
+			if (theName != null) {
+                assertEquals(
+                        "validate that Interface can be obtained with its name",
+                        networkInterface1, NetworkInterface.getByName(theName));
             }
-            try {
-                NetworkInterface.getByName(null);
-                fail("NullPointerException was not thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            } catch (SocketException e) {
-                fail("SocketException was thrown.");
+		}
+
+		// validate that we get the right interface with the second interface as
+		// well (ie we just don't always get the first interface
+		if (atLeastTwoInterfaces) {
+			String theName = networkInterface2.getName();
+			if (theName != null) {
+                assertEquals(
+                        "validate that Interface can be obtained with its name",
+                        networkInterface2, NetworkInterface.getByName(theName));
             }
-        }
+		}
+	}
 
-        // validate that we get the right interface with the second interface as
-        // well (ie we just don't always get the first interface
-        if (atLeastTwoInterfaces) {
-            String theName = networkInterface2.getName();
-            if (theName != null) {
-                try {
-                    assertTrue(
-                            "validate that Interface can be obtained with its name",
-                            NetworkInterface.getByName(theName).equals(
-                                    networkInterface2));
-                } catch (Exception e) {
-                    fail("validate to get network interface using name - socket exception");
-                }
-            }
-        }
-    }
+	/**
+	 * @tests java.net.NetworkInterface#getByInetAddress(java.net.InetAddress)
+	 */
+	public void test_getByInetAddressLjava_net_InetAddress() throws Exception {
 
-    /**
-     * @tests java.net.NetworkInterface#getByInetAddress(java.net.InetAddress)
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "SocketException checking missed.",
-        method = "getByInetAddress",
-        args = {java.net.InetAddress.class}
-    )
-    public void test_getByInetAddressLjava_net_InetAddress() {
+		byte addressBytes[] = new byte[4];
+		addressBytes[0] = 0;
+		addressBytes[1] = 0;
+		addressBytes[2] = 0;
+		addressBytes[3] = 0;
 
-        byte addressBytes[] = new byte[4];
-        addressBytes[0] = 0;
-        addressBytes[1] = 0;
-        addressBytes[2] = 0;
-        addressBytes[3] = 0;
-
-        try {
-            assertNull("validate null handled ok",
+		try {
+			assertNull("validate null handled ok",
                                    NetworkInterface.getByInetAddress(null));
-            fail("should not get here if getByInetAddress throws "
-                    + "NullPointerException if null passed in");
-        } catch (NullPointerException e) {
-        } catch (Exception e) {
-            fail("getByInetAddress, null inetAddress should have raised NPE"
-                    + " but instead threw a : " + e.getMessage());
-        }
+			fail("should not get here if getByInetAddress throws "
+					+ "NullPointerException if null passed in");
+		} catch (NullPointerException e) {
+		}
 
-        try {
-            assertNull("validate handled ok if we ask for address not associated with any interface",
-                                   NetworkInterface.getByInetAddress(InetAddress
-                            .getByAddress(addressBytes)));
-        } catch (Exception e) {
-            fail("getByInetAddress, unknown inetAddress threw exception : " + e);
-        }
+                assertNull("validate handled ok if we ask for address not associated with any interface",
+                           NetworkInterface.getByInetAddress(InetAddress
+                                                .getByAddress(addressBytes)));
 
-        // for each address in an interface validate that we get the right
-        // interface for that address
-        if (atLeastOneInterface) {
-            Enumeration addresses = networkInterface1.getInetAddresses();
-            if (addresses != null) {
-                while (addresses.hasMoreElements()) {
-                    InetAddress theAddress = (InetAddress) addresses
-                            .nextElement();
-                    try {
-                        assertTrue(
-                                "validate that Interface can be obtained with any one of its addresses",
-                                NetworkInterface.getByInetAddress(theAddress)
-                                        .equals(networkInterface1));
-                    } catch (Exception e) {
-                        fail("validate to get address using inetAddress " +
-                                "threw exception : " + e);
-                    }
-                }
+		// for each address in an interface validate that we get the right
+		// interface for that address
+		if (atLeastOneInterface) {
+			Enumeration addresses = networkInterface1.getInetAddresses();
+			while (addresses.hasMoreElements()) {
+                InetAddress theAddress = (InetAddress) addresses.nextElement();
+                assertEquals(
+                        "validate that Interface can be obtained with any one of its addresses",
+                        networkInterface1, NetworkInterface
+                                .getByInetAddress(theAddress));
             }
+		}
+
+		// validate that we get the right interface with the second interface as
+		// well (ie we just don't always get the first interface
+		if (atLeastTwoInterfaces) {
+			Enumeration addresses = networkInterface2.getInetAddresses();
+			while (addresses.hasMoreElements()) {
+                InetAddress theAddress = (InetAddress) addresses.nextElement();
+                assertEquals(
+                        "validate that Interface can be obtained with any one of its addresses",
+                        networkInterface2, NetworkInterface
+                                .getByInetAddress(theAddress));
+            }
+		}
+	}
+
+	/**
+	 * @tests java.net.NetworkInterface#getNetworkInterfaces()
+	 */
+	public void test_getNetworkInterfaces() throws Exception {
+
+		// really this is tested by all of the other calls but just make sure we
+		// can call it and get a list of interfaces if they exist
+		Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+	}
+
+	/**
+	 * @tests java.net.NetworkInterface#equals(java.lang.Object)
+	 */
+	public void test_equalsLjava_lang_Object() {
+		// Test for method boolean
+		// java.net.SocketPermission.equals(java.lang.Object)
+		if (atLeastOneInterface) {
+            assertEquals("If objects are the same true is returned",
+                    sameAsNetworkInterface1, networkInterface1);
+            assertNotNull("Validate Null handled ok", networkInterface1);
+        }
+		if (atLeastTwoInterfaces) {
+			assertFalse("If objects are different false is returned",
+					networkInterface1.equals(networkInterface2));
+		}
+	}
+
+	/**
+	 * @tests java.net.NetworkInterface#hashCode()
+	 */
+	public void test_hashCode() {
+
+		if (atLeastOneInterface) {
+			assertTrue(
+					"validate that hash codes are the same for two calls on the same object",
+					networkInterface1.hashCode() == networkInterface1
+							.hashCode());
+			assertTrue(
+					"validate that hash codes are the same for two objects for which equals is true",
+					networkInterface1.hashCode() == sameAsNetworkInterface1
+							.hashCode());
+		}
+	}
+
+	/**
+	 * @tests java.net.NetworkInterface#toString()
+	 */
+	public void test_toString() {
+		if (atLeastOneInterface) {
+			assertNotNull("validate that non null string is generated",
+					networkInterface1.toString());
+			assertFalse("validate that non-zero length string is generated",
+					networkInterface1.toString().equals(""));
+		}
+		if (atLeastTwoInterfaces) {
+			assertFalse(
+					"Validate strings are different for different interfaces",
+					networkInterface1.toString().equals(
+							networkInterface2.toString()));
+		}
+	}
+
+    private class MockSecurityManager extends SecurityManager {
+        @Override
+        public void checkConnect(String host, int port) {
+            throw new SecurityException();
+        }
+    }
+
+    /**
+     * 
+     * @tests java.net.NetworkInterface#getInterfaceAddresses()
+     * 
+     * @since 1.6
+     */
+    public void test_getInterfaceAddresses() throws SocketException {
+        if (theInterfaces != null) {
+            SecurityManager oldSM = System.getSecurityManager();
+            System.setSecurityManager(new MockSecurityManager());
             
-            try {
-                NetworkInterface.getByInetAddress(null);
-                fail("NullPointerException should be thrown.");
-            } catch(NullPointerException npe) {
-                //expected
-            } catch (SocketException e) {
-                fail("SocketException was thrown.");
+            while (theInterfaces.hasMoreElements()) {
+                NetworkInterface netif = theInterfaces.nextElement();
+                assertEquals(netif.getName()
+                        + " getInterfaceAddresses should contain no element", 0,
+                        netif.getInterfaceAddresses().size());
             }
-        }
-
-        // validate that we get the right interface with the second interface as
-        // well (ie we just don't always get the first interface
-        if (atLeastTwoInterfaces) {
-            Enumeration addresses = networkInterface2.getInetAddresses();
-            if (addresses != null) {
-                while (addresses.hasMoreElements()) {
-                    InetAddress theAddress = (InetAddress) addresses
-                            .nextElement();
-                    try {
-                        assertTrue(
-                                "validate that Interface can be obtained with any one of its addresses",
-                                NetworkInterface.getByInetAddress(theAddress)
-                                        .equals(networkInterface2));
-                    } catch (Exception e) {
-                        fail("validate to get address using inetAddress "
-                                + "threw exception : " + e);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * @tests java.net.NetworkInterface#getNetworkInterfaces()
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "SocketException checking missed.",
-        method = "getNetworkInterfaces",
-        args = {}
-    )
-    public void test_getNetworkInterfaces() {
-
-        // really this is tested by all of the other calls but just make sure we
-        // can call it and get a list of interfaces if they exist
-        try {
-            Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
-        } catch (Exception e) {
-            fail("get Network Interfaces - raised exception : "
-                    + e.getMessage());
-        }
-    }
-
-    /**
-     * @tests java.net.NetworkInterface#equals(java.lang.Object)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
-    public void test_equalsLjava_lang_Object() {
-        // Test for method boolean
-        // java.net.SocketPermission.equals(java.lang.Object)
-        if (atLeastOneInterface) {
-            assertTrue("If objects are the same true is returned",
-                    networkInterface1.equals(sameAsNetworkInterface1));
-            assertFalse("Validate Null handled ok", networkInterface1
-                    .equals(null));
-        }
-        if (atLeastTwoInterfaces) {
-            assertFalse("If objects are different false is returned",
-                    networkInterface1.equals(networkInterface2));
-        }
-    }
-
-    /**
-     * @tests java.net.NetworkInterface#hashCode()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
-    public void test_hashCode() {
-
-        if (atLeastOneInterface) {
-            assertTrue(
-                    "validate that hash codes are the same for two calls on the same object",
-                    networkInterface1.hashCode() == networkInterface1
-                            .hashCode());
-            assertTrue(
-                    "validate that hash codes are the same for two objects for which equals is true",
-                    networkInterface1.hashCode() == sameAsNetworkInterface1
-                            .hashCode());
-        }
-    }
-
-    /**
-     * @tests java.net.NetworkInterface#toString()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
-    public void test_toString() {
-        if (atLeastOneInterface) {
-            assertNotNull("validate that non null string is generated",
-                    networkInterface1.toString());
-            assertFalse("validate that non-zero length string is generated",
-                    networkInterface1.toString().equals(""));
-        }
-        if (atLeastTwoInterfaces) {
-            assertFalse(
-                    "Validate strings are different for different interfaces",
-                    networkInterface1.toString().equals(
-                            networkInterface2.toString()));
-        }
-    }
-
-    protected void setUp() {
-
-        Enumeration theInterfaces = null;
-        try {
+            System.setSecurityManager(oldSM);
+            
             theInterfaces = NetworkInterface.getNetworkInterfaces();
-        } catch (Exception e) {
-            fail("Exception occurred getting network interfaces : " + e);
+            while (theInterfaces.hasMoreElements()) {
+                NetworkInterface netif = theInterfaces.nextElement();
+                List<InterfaceAddress> interfaceAddrs = netif.getInterfaceAddresses();
+                assertTrue(interfaceAddrs instanceof ArrayList);
+                for (InterfaceAddress addr : interfaceAddrs) {
+                    assertNotNull(addr);                    
+                }
+                
+                List<InterfaceAddress> interfaceAddrs2 = netif.getInterfaceAddresses();
+                // RI fails on this since it cannot tolerate null broadcast address. 
+                assertEquals(interfaceAddrs, interfaceAddrs2);              
+            }
         }
-        
-        // Set up NetworkInterface instance members. Note that because the call
-        // to NetworkInterface.getNetworkInterfaces() returns *all* of the 
-        // interfaces on the test machine it is possible that one or more of 
-        // them will not currently be bound to an InetAddress. e.g. a laptop
-        // running connected by a wire to the local network may also have a 
-        // wireless interface that is not active and so has no InetAddress 
-        // bound to it. For these tests only work with NetworkInterface objects 
-        // that are bound to an InetAddress.   
-        if ((theInterfaces != null) && (theInterfaces.hasMoreElements())) {
-            while ((theInterfaces.hasMoreElements())
-                    && (atLeastOneInterface == false)) {
-                NetworkInterface theInterface = (NetworkInterface) theInterfaces
-                        .nextElement();
-                if (theInterface.getInetAddresses() != null) {
-                    // Ensure that the current NetworkInterface has at least
-                    // one InetAddress bound to it.  
-                    Enumeration addrs = theInterface.getInetAddresses();
-                    if ((addrs != null) && (addrs.hasMoreElements())) {
-                        atLeastOneInterface = true;
-                        networkInterface1 = theInterface;
-                    }// end if 
-                }
-            }
-
-            while ((theInterfaces.hasMoreElements())
-                    && (atLeastTwoInterfaces == false)) {
-                NetworkInterface theInterface = (NetworkInterface) theInterfaces
-                        .nextElement();
-                if (theInterface.getInetAddresses() != null) {
-                    // Ensure that the current NetworkInterface has at least
-                    // one InetAddress bound to it.  
-                    Enumeration addrs = theInterface.getInetAddresses();
-                    if ((addrs != null) && (addrs.hasMoreElements())) {
-                        atLeastTwoInterfaces = true;
-                        networkInterface2 = theInterface;
-                    }// end if 
-                }
-            }
-
-            // Only set sameAsNetworkInterface1 if we succeeded in finding 
-            // at least one good NetworkInterface
-            if (atLeastOneInterface) {
-                Enumeration addresses = networkInterface1.getInetAddresses();
-                if (addresses != null) {
-                    try {
-                        if (addresses.hasMoreElements()) {
-                            sameAsNetworkInterface1 = NetworkInterface
-                            .getByInetAddress((InetAddress) addresses
-                                    .nextElement());
-                        }
-                    } catch (SocketException e) {
-                        fail("SocketException occurred : " + e);
+    }   
+    
+    /**
+     * @tests java.net.NetworkInterface#isLoopback()
+     * 
+     * @since 1.6
+     */
+    public void test_isLoopback() throws SocketException {  
+        if (theInterfaces != null) {
+            while (theInterfaces.hasMoreElements()) {
+                NetworkInterface netif = theInterfaces.nextElement();
+                boolean loopback = false;
+                Enumeration<InetAddress> addrs = netif.getInetAddresses();
+                while(addrs != null && addrs.hasMoreElements()){
+                    if(addrs.nextElement().isLoopbackAddress()){
+                        loopback = true;
+                        break;
                     }
                 }
-            }// end if atLeastOneInterface
+                assertEquals(loopback, netif.isLoopback());
+            }
         }
     }
-
-    protected void tearDown() {
-        System.setSecurityManager(null);
+    
+    /**
+     * @tests java.net.NetworkInterface#getHardwareAddress()
+     * 
+     * @since 1.6
+     */
+    public void test_getHardwareAddress() throws SocketException {
+        if (theInterfaces != null) {
+            while (theInterfaces.hasMoreElements()) {
+                NetworkInterface netif = theInterfaces.nextElement();
+                byte[] hwAddr = netif.getHardwareAddress();
+                if (netif.isLoopback()) {
+                    assertTrue(hwAddr == null || hwAddr.length == 0);
+                } else {
+                    assertTrue(hwAddr.length >= 0);
+                }
+            }
+        }
     }
+    
+    /**
+     * 
+     * @tests java.net.NetworkInterface#getHardwareAddress()
+     * 
+     * @since 1.6
+     */
+    public void test_getMTU() throws SocketException {      
+        if (theInterfaces != null) {
+            while (theInterfaces.hasMoreElements()) {
+                NetworkInterface netif = theInterfaces.nextElement();
+                assertTrue(netif.getName() + "has non-positive MTU", netif.getMTU() >= 0);
+            }           
+        }
+    }
+    
+	protected void setUp() throws SocketException {
+
+		Enumeration theInterfaces = null;
+		try {
+			theInterfaces = NetworkInterface.getNetworkInterfaces();
+		} catch (Exception e) {
+			fail("Exception occurred getting network interfaces : " + e);
+		}
+		
+		// Set up NetworkInterface instance members. Note that because the call
+		// to NetworkInterface.getNetworkInterfaces() returns *all* of the 
+		// interfaces on the test machine it is possible that one or more of 
+		// them will not currently be bound to an InetAddress. e.g. a laptop
+		// running connected by a wire to the local network may also have a 
+		// wireless interface that is not active and so has no InetAddress 
+		// bound to it. For these tests only work with NetworkInterface objects 
+		// that are bound to an InetAddress.   
+		if ((theInterfaces != null) && (theInterfaces.hasMoreElements())) {
+			while ((theInterfaces.hasMoreElements())
+					&& (atLeastOneInterface == false)) {
+				NetworkInterface theInterface = (NetworkInterface) theInterfaces
+						.nextElement();
+				if (theInterface.getInetAddresses().hasMoreElements()) {
+					// Ensure that the current NetworkInterface has at least
+					// one InetAddress bound to it.  
+					Enumeration addrs = theInterface.getInetAddresses();
+					if ((addrs != null) && (addrs.hasMoreElements())) {
+						atLeastOneInterface = true;
+						networkInterface1 = theInterface;
+					}// end if 
+				}
+			}
+
+			while ((theInterfaces.hasMoreElements())
+					&& (atLeastTwoInterfaces == false)) {
+				NetworkInterface theInterface = (NetworkInterface) theInterfaces
+						.nextElement();
+				if (theInterface.getInetAddresses().hasMoreElements()) {
+					// Ensure that the current NetworkInterface has at least
+					// one InetAddress bound to it.  
+					Enumeration addrs = theInterface.getInetAddresses();
+					if ((addrs != null) && (addrs.hasMoreElements())) {
+						atLeastTwoInterfaces = true;
+						networkInterface2 = theInterface;
+					}// end if 
+				}
+			}
+
+			// Only set sameAsNetworkInterface1 if we succeeded in finding 
+			// at least one good NetworkInterface
+			if (atLeastOneInterface) {
+				Enumeration addresses = networkInterface1.getInetAddresses();
+				if (addresses.hasMoreElements()) {
+					try {
+						if (addresses.hasMoreElements()) {
+							sameAsNetworkInterface1 = NetworkInterface
+							.getByInetAddress((InetAddress) addresses
+									.nextElement());
+						}
+					} catch (SocketException e) {
+						fail("SocketException occurred : " + e);
+					}
+				}
+			}// end if atLeastOneInterface
+		}
+        theInterfaces = NetworkInterface.getNetworkInterfaces();
+	}
+
+	protected void tearDown() {
+		System.setSecurityManager(null);
+	}
 }
diff --git a/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java b/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
index 8aeb820..15a0a82 100644
--- a/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
+++ b/luni/src/test/java/tests/api/java/net/ResponseCacheTest.java
@@ -185,9 +185,6 @@
         method = "put",
         args = {URI.class, URLConnection.class}
     )
-    @KnownFailure("the call to put is made with a wrong uri."
-            + " The RI calls with http://localhost:<port>/test1,"
-            + " but android only calls with http://localhost:<port>")
     public void test_put() throws Exception {
         // Create test ResponseCache
         TestResponseCache cache = new TestResponseCache(
@@ -338,4 +335,4 @@
             return null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/luni/src/test/java/tests/api/java/util/AllTests.java b/luni/src/test/java/tests/api/java/util/AllTests.java
index c2651d9..2d9c422 100644
--- a/luni/src/test/java/tests/api/java/util/AllTests.java
+++ b/luni/src/test/java/tests/api/java/util/AllTests.java
@@ -24,13 +24,8 @@
  * TODO Type description
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Test for java.util");
+        TestSuite suite = new TestSuite("Test for java.util");
 
         // $JUnit-BEGIN$
         suite.addTestSuite(AbstractListTest.class);
diff --git a/luni/src/test/java/tests/api/java/util/CalendarTest.java b/luni/src/test/java/tests/api/java/util/CalendarTest.java
index 4ffe2c6..646c680 100644
--- a/luni/src/test/java/tests/api/java/util/CalendarTest.java
+++ b/luni/src/test/java/tests/api/java/util/CalendarTest.java
@@ -17,369 +17,372 @@
 
 package tests.api.java.util;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-import tests.support.Support_Locale;
-
+import java.text.DateFormatSymbols;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.TimeZone;
 
-@TestTargetClass(Calendar.class) 
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
 public class CalendarTest extends junit.framework.TestCase {
-    
-    Locale defaultLocale;
+	
+	Locale defaultLocale;
 
-    /**
-     * @tests java.util.Calendar#set(int, int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "set",
-        args = {int.class, int.class}
-    )
-    public void test_setII() {
-        // Test for correct result defined by the last set field
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
+	/**
+	 * @tests java.util.Calendar#set(int, int)
+	 */
+	public void test_setII() {
+		// Test for correct result defined by the last set field
+		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        assertTrue("Incorrect result 0: " + cal.getTime().getTime(), cal
-                .getTime().getTime() == 1009861200000L);
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		assertTrue("Incorrect result 0: " + cal.getTime().getTime(), cal
+				.getTime().getTime() == 1009861200000L);
 
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		assertTrue("Incorrect result 0a: " + cal.getTime(), cal.getTime()
+				.getTime() == 1014958800000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 24);
+		assertTrue("Incorrect result 0b: " + cal.getTime(), cal.getTime()
+				.getTime() == 1011848400000L);
+
+		cal.set(Calendar.MONTH, Calendar.OCTOBER);
+		cal.set(Calendar.DATE, 31);
+		cal.set(Calendar.MONTH, Calendar.NOVEMBER);
+		cal.set(Calendar.DATE, 26);
+		assertTrue("Incorrect month: " + cal.get(Calendar.MONTH), cal
+				.get(Calendar.MONTH) == Calendar.NOVEMBER);
+
+		int dow = cal.get(Calendar.DAY_OF_WEEK);
+		cal.set(Calendar.DATE, 27);
+		assertTrue("Incorrect DAY_OF_WEEK: " + cal.get(Calendar.DAY_OF_WEEK)
+				+ " expected: " + dow, cal.get(Calendar.DAY_OF_WEEK) != dow);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		assertTrue("Incorrect result 0c1: " + cal.getTime().getTime(), cal
+				.getTime().getTime() == 1010379600000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+		assertTrue("Incorrect result 0c2: " + cal.getTime().getTime(), cal
+				.getTime().getTime() == 1009861200000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
+		assertTrue("Incorrect result 0c3: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010034000000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_MONTH, 2);
+		assertTrue("Incorrect result 0d: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010293200000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
+		assertTrue("Incorrect result 0e: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010898000000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		assertTrue("Incorrect result 0f: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015736400000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 24);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		assertTrue("Incorrect result 0g: " + cal.getTime(), cal.getTime()
+				.getTime() == 1011848400000L);
+
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.get(Calendar.WEEK_OF_YEAR); // Force fields to compute
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		assertTrue("Incorrect result 0h: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015909200000L);
+
+		// WEEK_OF_YEAR has priority over MONTH/DATE
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_YEAR, 170);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		cal.set(Calendar.MONTH, Calendar.JANUARY);
+		cal.set(Calendar.DATE, 5);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		assertTrue("Incorrect result 1: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
+
+		// WEEK_OF_YEAR has priority over MONTH/DATE
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		cal.set(Calendar.MONTH, Calendar.JANUARY);
+		cal.set(Calendar.DATE, 5);
+		cal.set(Calendar.DAY_OF_YEAR, 170);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		assertTrue("Incorrect result 1a: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
+
+		// DAY_OF_WEEK has no effect when other fields not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+		assertTrue("Incorrect result 1b: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
+        // Regression for HARMONY-4384
+        // Set DAY_OF_WEEK without DATE
         cal.clear();
         cal.set(Calendar.YEAR, 2002);
         cal.set(Calendar.MONTH, Calendar.MARCH);
-        assertTrue("Incorrect result 0a: " + cal.getTime(), cal.getTime()
-                .getTime() == 1014958800000L);
-
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 24);
-        assertTrue("Incorrect result 0b: " + cal.getTime(), cal.getTime()
-                .getTime() == 1011848400000L);
-
-        cal.set(Calendar.MONTH, Calendar.OCTOBER);
-        cal.set(Calendar.DATE, 31);
-        cal.set(Calendar.MONTH, Calendar.NOVEMBER);
-        cal.set(Calendar.DATE, 26);
-        assertTrue("Incorrect month: " + cal.get(Calendar.MONTH), cal
-                .get(Calendar.MONTH) == Calendar.NOVEMBER);
-
-        int dow = cal.get(Calendar.DAY_OF_WEEK);
-        cal.set(Calendar.DATE, 27);
-        assertTrue("Incorrect DAY_OF_WEEK: " + cal.get(Calendar.DAY_OF_WEEK)
-                + " expected: " + dow, cal.get(Calendar.DAY_OF_WEEK) != dow);
-
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        assertTrue("Incorrect result 0c1: " + cal.getTime().getTime(), cal
-                .getTime().getTime() == 1010379600000L);
-
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
         cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
-        assertTrue("Incorrect result 0c2: " + cal.getTime().getTime(), cal
-                .getTime().getTime() == 1009861200000L);
+        assertEquals("Incorrect result 1b: " + cal.getTime(), 1015304400000L, cal.getTime()
+                .getTime());
+        
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
-        assertTrue("Incorrect result 0c3: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010034000000L);
+		// WEEK_OF_MONTH has priority
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+		cal.set(Calendar.WEEK_OF_MONTH, 3);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DATE, 5);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		assertTrue("Incorrect result 2: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_MONTH, 2);
-        assertTrue("Incorrect result 0d: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010293200000L);
+		// DAY_OF_WEEK_IN_MONTH has priority over WEEK_OF_YEAR
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DATE, 5);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		assertTrue("Incorrect result 3: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
-        assertTrue("Incorrect result 0e: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010898000000L);
+		// WEEK_OF_MONTH has priority, MONTH not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+		cal.set(Calendar.WEEK_OF_MONTH, 3);
+		cal.set(Calendar.DATE, 25);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		assertTrue("Incorrect result 4: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010984400000L);
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        assertTrue("Incorrect result 0f: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015736400000L);
+		// WEEK_OF_YEAR has priority when MONTH set last and DAY_OF_WEEK set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		cal.set(Calendar.DATE, 25);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		cal.set(Calendar.MONTH, Calendar.JANUARY);
+		assertTrue("Incorrect result 5: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 24);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        assertTrue("Incorrect result 0g: " + cal.getTime(), cal.getTime()
-                .getTime() == 1011848400000L);
+		// Use MONTH/DATE when WEEK_OF_YEAR set but not DAY_OF_WEEK
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		assertTrue("Incorrect result 5a: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.get(Calendar.WEEK_OF_YEAR); // Force fields to compute
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        assertTrue("Incorrect result 0h: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015909200000L);
+		// Use MONTH/DATE when DAY_OF_WEEK is not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.WEEK_OF_MONTH, 1);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		assertTrue("Incorrect result 5b: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // WEEK_OF_YEAR has priority over MONTH/DATE
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_YEAR, 170);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        cal.set(Calendar.MONTH, Calendar.JANUARY);
-        cal.set(Calendar.DATE, 5);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        assertTrue("Incorrect result 1: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// WEEK_OF_MONTH has priority
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DATE, 5);
+		cal.set(Calendar.WEEK_OF_MONTH, 3);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		assertTrue("Incorrect result 5c: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // WEEK_OF_YEAR has priority over MONTH/DATE
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        cal.set(Calendar.MONTH, Calendar.JANUARY);
-        cal.set(Calendar.DATE, 5);
-        cal.set(Calendar.DAY_OF_YEAR, 170);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        assertTrue("Incorrect result 1a: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// DATE has priority when set last
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DATE, 11);
+		assertTrue("Incorrect result 6: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DAY_OF_WEEK has no effect when other fields not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
-        assertTrue("Incorrect result 1b: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// DATE has priority when set last, MONTH not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 12);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		cal.set(Calendar.DATE, 14);
+		assertTrue("Incorrect result 7: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010984400000L);
 
-        // WEEK_OF_MONTH has priority
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
-        cal.set(Calendar.WEEK_OF_MONTH, 3);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.DATE, 5);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        assertTrue("Incorrect result 2: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// DAY_OF_YEAR has priority when MONTH set last and DATE not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_YEAR, 70);
+		cal.set(Calendar.MONTH, Calendar.JANUARY);
+		assertTrue("Incorrect result 8: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DAY_OF_WEEK_IN_MONTH has priority over WEEK_OF_YEAR
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 2);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.DATE, 5);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        assertTrue("Incorrect result 3: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// DAY/MONTH has priority when DATE set after DAY_OF_YEAR
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_YEAR, 170);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		assertTrue("Incorrect result 8a: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // WEEK_OF_MONTH has priority, MONTH not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
-        cal.set(Calendar.WEEK_OF_MONTH, 3);
-        cal.set(Calendar.DATE, 25);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        assertTrue("Incorrect result 4: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010984400000L);
+		// DAY_OF_YEAR has priority when set after DATE
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 15);
+		cal.set(Calendar.DAY_OF_YEAR, 70);
+		cal.set(Calendar.MONTH, Calendar.JANUARY);
+		assertTrue("Incorrect result 8b: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // WEEK_OF_YEAR has priority when MONTH set last and DAY_OF_WEEK set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        cal.set(Calendar.DATE, 25);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        cal.set(Calendar.MONTH, Calendar.JANUARY);
-        assertTrue("Incorrect result 5: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// DATE has priority when set last
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_YEAR, 70);
+		cal.set(Calendar.DATE, 14);
+		assertTrue("Incorrect result 9: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010984400000L);
 
-        // Use MONTH/DATE when WEEK_OF_YEAR set but not DAY_OF_WEEK
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        assertTrue("Incorrect result 5a: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// DATE has priority when set last
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_YEAR, 15);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
+		cal.set(Calendar.DATE, 14);
+		assertTrue("Incorrect result 9a: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010984400000L);
 
-        // Use MONTH/DATE when DAY_OF_WEEK is not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.WEEK_OF_MONTH, 1);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        assertTrue("Incorrect result 5b: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+		cal.set(Calendar.DATE, 14);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		assertTrue("Incorrect result 9b: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // WEEK_OF_MONTH has priority
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DATE, 5);
-        cal.set(Calendar.WEEK_OF_MONTH, 3);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        assertTrue("Incorrect result 5c: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 14);
+		cal.set(Calendar.WEEK_OF_YEAR, 11);
+		assertTrue("Incorrect result 9c: " + cal.getTime(), cal.getTime()
+				.getTime() == 1010984400000L);
 
-        // DATE has priority when set last
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.DATE, 11);
-        assertTrue("Incorrect result 6: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.WEEK_OF_MONTH, 1);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DATE, 11);
+		assertTrue("Incorrect result 9d: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DATE has priority when set last, MONTH not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 12);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        cal.set(Calendar.DATE, 14);
-        assertTrue("Incorrect result 7: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010984400000L);
+		// DAY_OF_YEAR has priority when DAY_OF_MONTH set last and other fields
+		// not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_YEAR, 70);
+		cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
+		assertTrue("Incorrect result 10: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DAY_OF_YEAR has priority when MONTH set last and DATE not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_YEAR, 70);
-        cal.set(Calendar.MONTH, Calendar.JANUARY);
-        assertTrue("Incorrect result 8: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// MONTH/DATE has priority when DAY_OF_WEEK_IN_MONTH set last but
+		// DAY_OF_WEEK not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
+		assertTrue("Incorrect result 11: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DAY/MONTH has priority when DATE set after DAY_OF_YEAR
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_YEAR, 170);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        assertTrue("Incorrect result 8a: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// MONTH/DATE has priority when WEEK_OF_YEAR set last but DAY_OF_WEEK
+		// not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.WEEK_OF_YEAR, 15);
+		assertTrue("Incorrect result 12: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DAY_OF_YEAR has priority when set after DATE
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 15);
-        cal.set(Calendar.DAY_OF_YEAR, 70);
-        cal.set(Calendar.MONTH, Calendar.JANUARY);
-        assertTrue("Incorrect result 8b: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
+		// MONTH/DATE has priority when WEEK_OF_MONTH set last but DAY_OF_WEEK
+		// not set
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DATE, 11);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.WEEK_OF_MONTH, 1);
+		assertTrue("Incorrect result 13: " + cal.getTime(), cal.getTime()
+				.getTime() == 1015822800000L);
 
-        // DATE has priority when set last
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_YEAR, 70);
-        cal.set(Calendar.DATE, 14);
-        assertTrue("Incorrect result 9: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010984400000L);
+		// Ensure last date field set is reset after computing
+		cal.clear();
+		cal.set(Calendar.YEAR, 2002);
+		cal.set(Calendar.DAY_OF_YEAR, 111);
+		cal.get(Calendar.YEAR);
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.AM_PM, Calendar.AM);
+		assertTrue("Incorrect result 14: " + cal.getTime(), cal.getTime()
+				.getTime() == 1016686800000L);
 
-        // DATE has priority when set last
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_YEAR, 15);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
-        cal.set(Calendar.DATE, 14);
-        assertTrue("Incorrect result 9a: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010984400000L);
-
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
-        cal.set(Calendar.DATE, 14);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        assertTrue("Incorrect result 9b: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
-
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 14);
-        cal.set(Calendar.WEEK_OF_YEAR, 11);
-        assertTrue("Incorrect result 9c: " + cal.getTime(), cal.getTime()
-                .getTime() == 1010984400000L);
-
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.WEEK_OF_MONTH, 1);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.DATE, 11);
-        assertTrue("Incorrect result 9d: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
-
-        // DAY_OF_YEAR has priority when DAY_OF_MONTH set last and other fields
-        // not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_YEAR, 70);
-        cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
-        assertTrue("Incorrect result 10: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
-
-        // MONTH/DATE has priority when DAY_OF_WEEK_IN_MONTH set last but
-        // DAY_OF_WEEK not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
-        assertTrue("Incorrect result 11: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
-
-        // MONTH/DATE has priority when WEEK_OF_YEAR set last but DAY_OF_WEEK
-        // not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.WEEK_OF_YEAR, 15);
-        assertTrue("Incorrect result 12: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
-
-        // MONTH/DATE has priority when WEEK_OF_MONTH set last but DAY_OF_WEEK
-        // not set
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DATE, 11);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.WEEK_OF_MONTH, 1);
-        assertTrue("Incorrect result 13: " + cal.getTime(), cal.getTime()
-                .getTime() == 1015822800000L);
-
-        // Ensure last date field set is reset after computing
-        cal.clear();
-        cal.set(Calendar.YEAR, 2002);
-        cal.set(Calendar.DAY_OF_YEAR, 111);
-        cal.get(Calendar.YEAR);
-        cal.set(Calendar.MONTH, Calendar.MARCH);
-        cal.set(Calendar.AM_PM, Calendar.AM);
-        assertTrue("Incorrect result 14: " + cal.getTime(), cal.getTime()
-                .getTime() == 1016686800000L);
-
-        int hour = cal.get(Calendar.HOUR);
-        cal.set(Calendar.HOUR, hour);
-        cal.set(Calendar.AM_PM, Calendar.PM);
-        assertEquals("AM_PM not changed", Calendar.PM, cal.get(Calendar.AM_PM));
-        // setting AM_PM without HOUR should not have any affect
-        cal.set(Calendar.AM_PM, Calendar.AM);
-        assertEquals("AM_PM was changed 1",
-                Calendar.AM, cal.get(Calendar.AM_PM));
-        int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
-        hour = cal.get(Calendar.HOUR);
-        cal.set(Calendar.AM_PM, Calendar.PM);
-        assertEquals("AM_PM was changed 2",
-                Calendar.PM, cal.get(Calendar.AM_PM));
-        assertEquals(hour, cal.get(Calendar.HOUR));
-        assertEquals(hourOfDay + 12, cal.get(Calendar.HOUR_OF_DAY));
+		int hour = cal.get(Calendar.HOUR);
+		cal.set(Calendar.HOUR, hour);
+		cal.set(Calendar.AM_PM, Calendar.PM);
+		assertEquals("AM_PM not changed", Calendar.PM, cal.get(Calendar.AM_PM));
+		// setting AM_PM without HOUR should not have any affect
+		cal.set(Calendar.AM_PM, Calendar.AM);
+		assertEquals("AM_PM was changed 1",
+				Calendar.AM, cal.get(Calendar.AM_PM));
+		int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
+		hour = cal.get(Calendar.HOUR);
+		cal.set(Calendar.AM_PM, Calendar.PM);
+		assertEquals("AM_PM was changed 2",
+				Calendar.PM, cal.get(Calendar.AM_PM));
+		assertEquals(hour, cal.get(Calendar.HOUR));
+		assertEquals(hourOfDay + 12, cal.get(Calendar.HOUR_OF_DAY));
         
         // regression test for Harmony-2122
         cal = Calendar.getInstance();
@@ -388,74 +391,40 @@
         cal.set(Calendar.AM_PM, newValue);
         newValue = cal.get(Calendar.AM_PM);
         assertTrue(newValue != oldValue);
-        
-        cal.setLenient(false);
-        
-        try {
-            cal.set(-1, 3);
-            fail("ArrayIndexOutOfBoundsException expected");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            //expected
-        }
-        
-        try {
-            cal.set(Calendar.FIELD_COUNT + 1, 3);
-            fail("ArrayIndexOutOfBoundsException expected");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            //expected
-        }
-    }
+	}
 
-    /**
-     * @tests java.util.Calendar#setTime(java.util.Date)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setTime",
-        args = {java.util.Date.class}
-    )
-    public void test_setTimeLjava_util_Date() {
-        Calendar cal = Calendar.getInstance();
-        // Use millisecond time for testing in Core
-        cal.setTime(new Date(884581200000L)); // (98, Calendar.JANUARY, 12)
-        assertEquals("incorrect millis", 884581200000L, cal.getTime().getTime());
-        cal.setTimeZone(TimeZone.getTimeZone("EST"));
-        cal.setTime(new Date(943506000000L)); // (99, Calendar.NOVEMBER, 25)
-        assertTrue("incorrect fields", cal.get(Calendar.YEAR) == 1999
-                && cal.get(Calendar.MONTH) == Calendar.NOVEMBER
-                && cal.get(Calendar.DATE) == 25);
-    }
+	/**
+	 * @tests java.util.Calendar#setTime(java.util.Date)
+	 */
+	public void test_setTimeLjava_util_Date() {
+		Calendar cal = Calendar.getInstance();
+		// Use millisecond time for testing in Core
+		cal.setTime(new Date(884581200000L)); // (98, Calendar.JANUARY, 12)
+		assertEquals("incorrect millis", 884581200000L, cal.getTime().getTime());
+		cal.setTimeZone(TimeZone.getTimeZone("EST"));
+		cal.setTime(new Date(943506000000L)); // (99, Calendar.NOVEMBER, 25)
+		assertTrue("incorrect fields", cal.get(Calendar.YEAR) == 1999
+				&& cal.get(Calendar.MONTH) == Calendar.NOVEMBER
+				&& cal.get(Calendar.DATE) == 25);
+	}
 
-    /**
-     * @tests java.util.Calendar#compareTo(Calendar)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies NullPointerException.",
-        method = "compareTo",
-        args = {java.util.Calendar.class}
-    )
-    public void test_compareToLjava_util_Calendar_null() {
-        Calendar cal = Calendar.getInstance();
-        try {
-            cal.compareTo(null);
-            fail("should throw NullPointerException");
-        } catch (NullPointerException e) {
-            // expected
-        }
-    }
+	/**
+	 * @tests java.util.Calendar#compareTo(Calendar)
+	 */
+	public void test_compareToLjava_util_Calendar_null() {
+		Calendar cal = Calendar.getInstance();
+		try {
+			cal.compareTo(null);
+			fail("should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
 
-    /**
-     * @tests java.util.Calendar#compareTo(Calendar)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.util.Calendar.class}
-    )
-    public void test_compareToLjava_util_Calendar() {
+	/**
+	 * @tests java.util.Calendar#compareTo(Calendar)
+	 */
+	public void test_compareToLjava_util_Calendar() {
         Calendar cal = Calendar.getInstance();
         cal.clear();
         cal.set(1997, 12, 13, 23, 57);
@@ -474,33 +443,11 @@
         anotherCal.clear();
         anotherCal.set(1997, 12, 13, 23, 58);
         assertEquals(-1, cal.compareTo(anotherCal));
-        
-        try {
-            cal.compareTo(null);
-            fail("NullPointerException expected");
-        } catch (NullPointerException e) {
-            //expected
-        }
-
-        MockCalendar mc = new MockCalendar();
-
-        try {
-            cal.compareTo(mc);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException e) {
-            //expected
-        }
     }
 
     /**
      * @tests java.util.Calendar#clone()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clone",
-        args = {}
-    )
     public void test_clone() {
         // Regression for HARMONY-475
         Calendar cal = Calendar.getInstance();
@@ -514,17 +461,11 @@
     /**
      * @tests java.util.Calendar#getTimeInMillis()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTimeInMillis",
-        args = {}
-    )
     public void test_getTimeInMillis() {
         Calendar cal = Calendar.getInstance();
 
         int year = Integer.MIN_VALUE + 71;
-        cal.setTimeZone(TimeZone.getTimeZone("GMT"));;
+		cal.setTimeZone(TimeZone.getTimeZone("GMT"));
         cal.set(Calendar.YEAR, year + 1900);
         cal.set(Calendar.MONTH, Calendar.JANUARY);
         cal.set(Calendar.DATE, 1);
@@ -536,793 +477,623 @@
         assertEquals(6017546357372606464L, cal.getTimeInMillis());
     }
 
+	private static final Locale[] locales = new Locale[] { Locale.getDefault(),
+			Locale.US, Locale.UK, Locale.TAIWAN, Locale.PRC, Locale.KOREA,
+			Locale.JAPAN, Locale.ITALIAN, Locale.GERMAN, Locale.ENGLISH,
+			Locale.CHINA, Locale.CANADA, Locale.FRANCE };
+
     /**
-     * @tests {@link java.util.Calendar#getActualMaximum(int)}
+     * @tests java.util.Calendar#before(Object)
+     * @tests java.util.Calendar#after(Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getActualMaximum",
-        args = {int.class}
-    )
-    public void test_getActualMaximum_I() {
-        Calendar c = new MockCalendar();
-        assertEquals("should be equal to 0", 0, c.getActualMaximum(0));
+    public void test_before_after() {
+        Calendar early = Calendar.getInstance();
+        Calendar late = Calendar.getInstance();
+        // test by second
+        early.set(2008, 3, 20, 17, 28, 12);
+        late.set(2008, 3, 20, 17, 28, 22);
+        // test before()
+        assertTrue(early.before(late));
+        assertFalse(early.before(early));
+        assertFalse(late.before(early));
+        // test after();
+        assertTrue(late.after(early));
+        assertFalse(late.after(late));
+        assertFalse(early.after(late));
+
+        // test by minute
+        early.set(2008, 3, 20, 17, 18, 12);
+        late.set(2008, 3, 20, 17, 28, 12);
+        // test before()
+        assertTrue(early.before(late));
+        assertFalse(early.before(early));
+        assertFalse(late.before(early));
+        // test after();
+        assertTrue(late.after(early));
+        assertFalse(late.after(late));
+        assertFalse(early.after(late));
+
+        // test by hour
+        early.set(2008, 3, 20, 17, 28, 12);
+        late.set(2008, 3, 20, 27, 28, 12);
+        // test before()
+        assertTrue(early.before(late));
+        assertFalse(early.before(early));
+        assertFalse(late.before(early));
+        // test after();
+        assertTrue(late.after(early));
+        assertFalse(late.after(late));
+        assertFalse(early.after(late));
+
+        // test by day
+        early.set(2008, 3, 10, 17, 28, 12);
+        late.set(2008, 3, 20, 17, 28, 12);
+        // test before()
+        assertTrue(early.before(late));
+        assertFalse(early.before(early));
+        assertFalse(late.before(early));
+        // test after();
+        assertTrue(late.after(early));
+        assertFalse(late.after(late));
+        assertFalse(early.after(late));
+
+        // test by month
+        early.set(2008, 2, 20, 17, 28, 12);
+        late.set(2008, 3, 20, 17, 28, 12);
+        // test before()
+        assertTrue(early.before(late));
+        assertFalse(early.before(early));
+        assertFalse(late.before(early));
+        // test after();
+        assertTrue(late.after(early));
+        assertFalse(late.after(late));
+        assertFalse(early.after(late));
+
+        // test by year
+        early.set(2007, 3, 20, 17, 28, 12);
+        late.set(2008, 3, 20, 17, 28, 12);
+        // test before()
+        assertTrue(early.before(late));
+        assertFalse(early.before(early));
+        assertFalse(late.before(early));
+        // test after();
+        assertTrue(late.after(early));
+        assertFalse(late.after(late));
+        assertFalse(early.after(late));
     }
-    
+
     /**
-     * @tests {@link java.util.Calendar#getActualMinimum(int)}
+     * @tests java.util.Calendar#clear()
+     * @tests java.util.Calendar#clear(int)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getActualMinimum",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "Calendar",
-            args = {}
-        )
-    })
-    public void test_getActualMinimum_I() {
-        Calendar c = new MockCalendar();
-        assertEquals("should be equal to 0", 0, c.getActualMinimum(0));
-    }
-
-    private class MockCalendar extends Calendar {
-
-        public MockCalendar() {
-            super();
-        }
-
-        public MockCalendar(TimeZone default1, Locale germany) {
-            super(default1, germany);
-        }
-
-        @Override
-        public void add(int field, int value) {
-        }
-
-        @Override
-        protected void computeFields() {
-        }
-
-        @Override
-        protected void computeTime() {
-            throw new IllegalArgumentException();
-        }
-
-        @Override
-        public int getGreatestMinimum(int field) {
-            return 0;
-        }
-
-        @Override
-        public int getLeastMaximum(int field) {
-            return 0;
-        }
-
-        @Override
-        public int getMaximum(int field) {
-            return 0;
-        }
-
-        @Override
-        public int getMinimum(int field) {
-            return 0;
-        }
-
-        @Override
-        public void roll(int field, boolean increment) {
-        }
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Calendar",
-        args = {java.util.TimeZone.class, java.util.Locale.class}
-    )
-    public void test_ConstructorLjava_utilTimeZoneLjava_util_Locale() {
-        assertNotNull(new MockCalendar(TimeZone.getDefault(), Locale.GERMANY));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Test calls dummy implementation of abstract method.",
-        method = "add",
-        args = {int.class, int.class}
-    )
-    public void test_addII() {
-        MockCalendar mc = new MockCalendar();
-        
-        mc.add(Calendar.DAY_OF_YEAR, 7);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "after",
-        args = {java.lang.Object.class}
-    )
-    public void test_afterLjava_lang_Object() {
-        MockCalendar mcBefore = new MockCalendar();
-        MockCalendar mc       = new MockCalendar();
-        MockCalendar mcAfter  = new MockCalendar();
-        MockCalendar mcSame   = new MockCalendar();
-
-        mcBefore.setTimeInMillis(1000);
-        mc.setTimeInMillis(10000);
-        mcAfter.setTimeInMillis(100000);
-        mcSame.setTimeInMillis(10000);
-        
-        assertTrue(mc.after(mcBefore));
-        assertFalse(mc.after(mcAfter));
-        assertFalse(mc.after(mcSame));
-        assertFalse(mc.after(mc));
-        assertFalse(mc.after(new String()));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "before",
-        args = {java.lang.Object.class}
-    )
-    public void test_beforeLjava_lang_Object() {
-        MockCalendar mcBefore = new MockCalendar();
-        MockCalendar mc       = new MockCalendar();
-        MockCalendar mcAfter  = new MockCalendar();
-        MockCalendar mcSame   = new MockCalendar();
-    
-        mcBefore.setTimeInMillis(1000);
-        mc.setTimeInMillis(10000);
-        mcAfter.setTimeInMillis(100000);
-        mcSame.setTimeInMillis(10000);
-        
-        assertFalse(mc.before(mcBefore));
-        assertTrue(mc.before(mcAfter));
-        assertFalse(mc.before(mcSame));
-        assertFalse(mc.before(mc));
-        assertFalse(mc.before(new String()));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clear",
-        args = {}
-    )
     public void test_clear() {
-        MockCalendar mc1 = new MockCalendar();
-        MockCalendar mc2 = new MockCalendar();
-        
-        assertTrue(mc1.toString().equals(mc2.toString()));
-        mc1.set(2008, Calendar.SEPTEMBER, 23, 18, 0, 0);
-        assertFalse(mc1.toString().equals(mc2.toString()));
-        mc1.clear();
-        assertTrue(mc1.toString().equals(mc2.toString()));
+        Calendar calendar = Calendar.getInstance();
+
+        int count = 6;
+        int[] fields = new int[count];
+        int[] defaults = new int[count];
+
+        fields[0] = Calendar.YEAR;
+        fields[1] = Calendar.MONTH;
+        fields[2] = Calendar.DATE;
+        fields[3] = Calendar.HOUR_OF_DAY;
+        fields[4] = Calendar.MINUTE;
+        fields[5] = Calendar.SECOND;
+
+        defaults[0] = 1970;
+        defaults[1] = 0;
+        defaults[2] = 1;
+        defaults[3] = 0;
+        defaults[4] = 0;
+        defaults[5] = 0;
+
+        calendar.set(2008, 3, 20, 17, 28, 12);
+
+        // test clear(int)
+        for (int i = 0; i < fields.length; i++) {
+            int index = fields[i];
+            calendar.clear(index);
+            if (5 == index) {
+                // RI also doesn't change the value of DATE
+                assertEquals("Field " + index + " Should equal to 20.", 20,
+                        calendar.get(index));
+            } else if (11 == index) {
+                // RI also doesn't change the value of HOUR
+                assertEquals("Field " + index + " Should equal to 17.", 17,
+                        calendar.get(index));
+            } else {
+                // Other have been set to default values
+                assertEquals("Field " + index + " Should equal to "
+                        + defaults[i] + ".", defaults[i], calendar.get(index));
+            }
+        }
+
+        // test clear()
+        calendar.set(2008, 3, 20, 17, 28, 12);
+
+        calendar.clear();
+
+        for (int i = 0; i < fields.length; i++) {
+            int index = fields[i];
+            assertEquals("Field " + index + " Should equal to "
+                    + defaults[i] + ".", defaults[i], calendar.get(index));
+        }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clear",
-        args = {int.class}
-    )
-    public void test_clearI() {
-        MockCalendar mc1 = new MockCalendar();
-        MockCalendar mc2 = new MockCalendar();
-        
-        assertTrue(mc1.toString().equals(mc2.toString()));
-        mc1.set(2008, Calendar.SEPTEMBER, 23, 18, 0, 0);
-        assertFalse(mc1.toString().equals(mc2.toString()));
-        mc1.clear(Calendar.YEAR);
-        mc1.clear(Calendar.MONTH);
-        mc1.clear(Calendar.DAY_OF_MONTH);
-        mc1.clear(Calendar.HOUR_OF_DAY);
-        mc1.clear(Calendar.MINUTE);
-        mc1.clear(Calendar.SECOND);
-        mc1.clear(Calendar.MILLISECOND);
-        assertTrue(mc1.toString().equals(mc2.toString()));
+    /**
+     * @tests java.util.Calendar#isSet(int)
+     */
+    public void test_isSet() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.clear();
+        for (int i = 0; i < Calendar.FIELD_COUNT; i++) {
+            assertFalse(calendar.isSet(i));
+        }
     }
 
-    class Mock_Calendar extends Calendar {
-        boolean flagComplete = false;
-        @Override
-        public void add(int field, int amount) {
-            
+    /**
+     * @tests java.util.Calendar#getAvailableLocales()
+     */
+    public void test_getAvailableLocales() {
+        Locale[] locales = Calendar.getAvailableLocales();
+        boolean exist = false;
+        for (int i = 0; i < locales.length; i++) {
+            Locale l = locales[i];
+            if (Locale.US.equals(l)) {
+                exist = true;
+                break;
+            }
         }
+        assertTrue(exist);
+    }
 
-        @Override
-        protected void computeFields() {
-            this.set(MONTH, this.internalGet(MONTH)%12);
-        }
+    /**
+     * @tests java.util.Calendar#getInstance(Locale)
+     * @tests java.util.Calendar#getInstance(TimeZone, Locale)
+     */
+    public void test_getInstance() {
+        // test getInstance(Locale)
+        Calendar us_calendar = Calendar.getInstance(Locale.US);
+        Calendar ch_calendar = Calendar.getInstance(Locale.CHINESE);
+        assertEquals(Calendar.SUNDAY, us_calendar
+                .getFirstDayOfWeek());
+        assertEquals(Calendar.MONDAY, ch_calendar
+                .getFirstDayOfWeek());
 
-        @Override
-        protected void computeTime() {
-        }
+        // test getInstance(Locale, TimeZone)
+        Calendar gmt_calendar = Calendar.getInstance(TimeZone
+                .getTimeZone("GMT"), Locale.US);
+        assertEquals(TimeZone.getTimeZone("GMT"),
+                gmt_calendar.getTimeZone());
+        Calendar est_calendar = Calendar.getInstance(TimeZone
+                .getTimeZone("EST"), Locale.US);
+        assertEquals(TimeZone.getTimeZone("EST")
+                .getID(), est_calendar.getTimeZone().getID());
+    }
 
-        @Override
-        public int getGreatestMinimum(int field) {
-            return 0;
-        }
+    /**
+     * @tests java.util.Calendar#internalGet(int)
+     */
+    public void test_internalGet() {
+        MockGregorianCalendar c = new MockGregorianCalendar();
+        c.clear(Calendar.YEAR);
+        assertEquals(0, c.internal_get(Calendar.YEAR));
+    }
 
-        @Override
-        public int getLeastMaximum(int field) {
-            return 0;
-        }
+    /**
+     * @tests java.util.Calendar#hashCode()
+     */
+    public void test_hashcode() {
+        Calendar calendar = Calendar.getInstance(Locale.JAPAN);
+        assertTrue(calendar.hashCode() == calendar.hashCode());
+    }
 
-        @Override
-        public int getMaximum(int field) {
-            return 0;
-        }
+    /**
+     * @tests java.util.Calendar#roll(int, int)
+     */
+    public void test_roll() {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(2008, 3, 20, 17, 28, 12);
 
-        @Override
-        public int getMinimum(int field) {
-            return 0;
-        }
+        // roll up
+        calendar.roll(Calendar.DATE, 5);
+        assertEquals(25, calendar.get(Calendar.DATE));
 
-        @Override
-        public void roll(int field, boolean up) {
-        }
-        
-        @Override
-        public void complete() {
-            computeTime();
-            computeFields();
-            flagComplete = true;
-        }
-        
-        public boolean isCompleted () {
-            return flagComplete;
-        }
+        // roll down
+        calendar.roll(Calendar.DATE, -5);
+        assertEquals(20, calendar.get(Calendar.DATE));
 
-        public int internalGetField(int field) {
+        // roll 0
+        calendar.roll(Calendar.DATE, 0);
+        assertEquals(20, calendar.get(Calendar.DATE));
+
+        // roll overweight
+        calendar.set(2008, 1, 31, 17, 28, 12);
+        calendar.roll(Calendar.MONTH, 1);
+        assertEquals(2, calendar.get(Calendar.DATE));
+
+    }
+
+    /**
+     * @tests java.util.Calendar#toString()
+     */
+    public void test_toString() {
+        Calendar calendar = Calendar.getInstance();
+        //Should be the current time with no interrogation in the string.
+        assertTrue(calendar.toString() instanceof String);
+        assertEquals(-1, calendar.toString().indexOf("?"));
+        calendar.clear();
+        assertTrue(calendar.toString() instanceof String);
+        assertTrue(0 <= calendar.toString().indexOf("?"));
+    }
+
+    /**
+     * @tests serialization/deserialization.
+     */
+    public void testSerializationSelf() throws Exception {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(2008, 3, 20, 17, 28, 12);
+
+        SerializationTest.verifySelf(calendar);
+    }
+
+
+    private class MockGregorianCalendar extends GregorianCalendar {
+        public int internal_get(int field) {
             return super.internalGet(field);
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "complete",
-        args = {}
-    )
-    public void test_complete() {
-        Mock_Calendar cal = new Mock_Calendar();
-        
-        assertFalse(cal.isCompleted());
-        cal.setTimeInMillis(1000);
-        cal.get(Calendar.MONTH);
-        assertTrue(cal.isCompleted());
+    private class MockCalendar extends Calendar {
+
+		public MockCalendar() {
+			super();
+		}
+
+		@Override
+		public void add(int field, int value) {
+		}
+
+		@Override
+		protected void computeFields() {
+		}
+
+		@Override
+		protected void computeTime() {
+		}
+
+		@Override
+		public int getGreatestMinimum(int field) {
+			return 0;
+		}
+
+		@Override
+		public int getLeastMaximum(int field) {
+			return 0;
+		}
+
+		@Override
+		public int getMaximum(int field) {
+			return 0;
+		}
+
+		@Override
+		public int getMinimum(int field) {
+			return 0;
+		}
+
+		@Override
+		public void roll(int field, boolean increment) {
+		}
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "computeFields",
-        args = {}
-    )
-    public void test_computeFields() {
-        Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal1.setTimeInMillis(1222185600225L);
-        cal2.set(2008, Calendar.SEPTEMBER, 23, 18, 0, 0);
-        assertFalse(cal1.toString().equals(cal2.toString()));
-        cal1.get(Calendar.YEAR);
-        cal2.getTimeInMillis();
-        cal1.set(Calendar.MILLISECOND, 0);
-        cal2.set(Calendar.MILLISECOND, 0);
-        // tests fails in this line.
-        assertTrue(cal1.toString().equals(cal2.toString()));
-    }
+	/**
+	 * @tests {@link java.util.Calendar#getDisplayName(int, int, Locale)}
+	 * @since 1.6
+	 */
+	public void test_getDisplayNameIILjava_util_Locale() {
+		Calendar cal = Calendar.getInstance();
+		for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+			for (Locale locale : locales) {
+				DateFormatSymbols symbols = new DateFormatSymbols(locale);
+				String value = null;
+				switch (field) {
+				case Calendar.AM_PM:
+					cal.set(Calendar.AM_PM, Calendar.AM);
+					value = symbols.getAmPmStrings()[0];
+					assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+							locale), value);
+					assertEquals(cal.getDisplayName(field, Calendar.LONG,
+							locale), value);
+					cal.set(Calendar.AM_PM, Calendar.PM);
+					value = symbols.getAmPmStrings()[1];
+					assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+							locale), value);
+					assertEquals(cal.getDisplayName(field, Calendar.LONG,
+							locale), value);
+					break;
+				case Calendar.ERA:
+					cal.set(Calendar.ERA, GregorianCalendar.BC);
+					value = symbols.getEras()[0];
+					assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+							locale), value);
+					assertEquals(cal.getDisplayName(field, Calendar.LONG,
+							locale), value);
+					cal.set(Calendar.ERA, GregorianCalendar.AD);
+					value = symbols.getEras()[1];
+					assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+							locale), value);
+					assertEquals(cal.getDisplayName(field, Calendar.LONG,
+							locale), value);
+					break;
+				case Calendar.MONTH:
+					cal.set(Calendar.DAY_OF_MONTH, 1);
+					for (int month = 0; month <= 11; month++) {
+						cal.set(Calendar.MONTH, month);
+						value = symbols.getShortMonths()[month];
+						assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+								locale), value);
+						value = symbols.getMonths()[month];
+						assertEquals(cal.getDisplayName(field, Calendar.LONG,
+								locale), value);
+					}
+					break;
+				case Calendar.DAY_OF_WEEK:
+					for (int day = 1; day <= 7; day++) {
+						cal.set(Calendar.DAY_OF_WEEK, day);
+						value = symbols.getShortWeekdays()[day];
+						assertEquals(cal.getDisplayName(field, Calendar.SHORT,
+								locale), value);
+						value = symbols.getWeekdays()[day];
+						assertEquals(cal.getDisplayName(field, Calendar.LONG,
+								locale), value);
+					}
+					break;
+				default:
+					assertNull(cal
+							.getDisplayName(field, Calendar.SHORT, locale));
+					assertNull(cal.getDisplayName(field, Calendar.LONG, locale));
+				}
+			}
+		}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
-    public void test_equals() {
-        Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal1.setTimeInMillis(1222185600225L);
-        cal2.set(2008, Calendar.SEPTEMBER, 23, 18, 0, 0);
-        assertFalse(cal1.equals(cal2));
-        cal1.get(Calendar.YEAR);
-        cal2.getTimeInMillis();
-        cal1.set(Calendar.MILLISECOND, 0);
-        cal2.set(Calendar.MILLISECOND, 0);
-        // tests fails on following line.
-        assertTrue(cal1.equals(cal2));
-    }
+		cal.setLenient(true);
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "get",
-        args = {int.class}
-    )
-    public void test_getI() {
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal.setTimeInMillis(1222185600225L);
-        assertEquals(cal.get(Calendar.ERA), 1);
-        assertEquals(cal.get(Calendar.YEAR), 2008);
-        assertEquals(cal.get(Calendar.MONTH), Calendar.SEPTEMBER);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
-        // Following line returns wrong value. Behavior uncompatible with RI.
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 18);
-        assertEquals(cal.get(Calendar.MINUTE), 0);
-        
-        try {
-            cal.get(-1);
-            fail("ArrayIndexOutOfBoundsException expected");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            //expected
-        }
+		try {
+			cal.getDisplayName(-1, Calendar.SHORT, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(Calendar.MONTH, -1, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(Calendar.MONTH, 3, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, null);
+			fail("Should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(-1, Calendar.SHORT, null);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(Calendar.MONTH, -1, null);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		// in lenient mode, following cases pass
+		cal.set(Calendar.SECOND, 999);
+		cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
+		// test for ALL_STYLES, it is equal to use SHORT
+		for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+			for (Locale locale : locales) {
+				String result = cal.getDisplayName(field, Calendar.ALL_STYLES,
+						locale);
+				if (field == Calendar.AM_PM || field == Calendar.ERA
+						|| field == Calendar.MONTH
+						|| field == Calendar.DAY_OF_WEEK) {
+					assertEquals(result, cal.getDisplayName(field,
+							Calendar.SHORT, locale));
+				} else {
+					assertNull(result);
+				}
+			}
+		}
 
-        try {
-            cal.get(Calendar.FIELD_COUNT + 1);
-            fail("ArrayIndexOutOfBoundsException expected");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            //expected
-        }
-    }
+		// invalid value for an un-related field when the calendar is not
+		// lenient
+		cal.setLenient(false);
+		assertNotNull(cal.getDisplayName(Calendar.MONTH, Calendar.SHORT,
+				Locale.US));
+		cal.set(Calendar.SECOND, 999);
+		try {
+			cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayName(Calendar.MONTH, Calendar.ALL_STYLES, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getAvailableLocales",
-        args = {}
-    )
-    public void test_getAvailableLocales() {
-        assertNotNull(Calendar.getAvailableLocales());
-    }
+	/**
+	 * @tests {@link java.util.Calendar#getDisplayNames(int, int, Locale)}
+	 * @since 1.6
+	 */
+	public void test_getDisplayNamesIILjava_util_Locale() {
+		assertEquals(0, Calendar.ALL_STYLES);
+		assertEquals(1, Calendar.SHORT);
+		assertEquals(2, Calendar.LONG);
 
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getFirstDayOfWeek",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getInstance",
-            args = {}
-        )
-    })
-    public void test_getFirstDayOfWeek() {
-        Locale[] requiredLocales = {Locale.US, Locale.FRANCE};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        Calendar cal = Calendar.getInstance();
+		Calendar cal = Calendar.getInstance(Locale.US);
 
-        assertEquals(Calendar.SUNDAY, cal.getFirstDayOfWeek());
-        Locale.setDefault(Locale.FRANCE);
-        cal = Calendar.getInstance();
-        assertEquals(Calendar.MONDAY, cal.getFirstDayOfWeek());
-        Locale.setDefault(Locale.US);
-    }
+		for (int field = 0; field < Calendar.FIELD_COUNT; field++) {
+			for (Locale locale : locales) {
+				Map<String, Integer> shortResult = cal.getDisplayNames(field,
+						Calendar.SHORT, locale);
+				Map<String, Integer> longResult = cal.getDisplayNames(field,
+						Calendar.LONG, locale);
+				Map<String, Integer> allResult = cal.getDisplayNames(field,
+						Calendar.ALL_STYLES, locale);
+				DateFormatSymbols symbols = new DateFormatSymbols(locale);
+				String[] values = null;
+				switch (field) {
+				case Calendar.AM_PM:
+				case Calendar.ERA:
+					values = (field == Calendar.AM_PM) ? symbols
+							.getAmPmStrings() : symbols.getEras();
+					assertDisplayNameMap(values, shortResult, 0);
+					assertDisplayNameMap(values, longResult, 0);
+					assertDisplayNameMap(values, allResult, 0);
+					break;
+				case Calendar.MONTH:
+					values = symbols.getShortMonths();
+					assertDisplayNameMap(values, shortResult, 0);
+					values = symbols.getMonths();
+					assertDisplayNameMap(values, longResult, 0);
+					assertTrue(allResult.size() >= shortResult.size());
+					assertTrue(allResult.size() >= longResult.size());
+					assertTrue(allResult.size() <= shortResult.size()
+							+ longResult.size());
+					break;
+				case Calendar.DAY_OF_WEEK:
+					values = symbols.getShortWeekdays();
+					assertDisplayNameMap(values, shortResult, 1);
+					values = symbols.getWeekdays();
+					assertDisplayNameMap(values, longResult, 1);
+					assertTrue(allResult.size() >= shortResult.size());
+					assertTrue(allResult.size() >= longResult.size());
+					assertTrue(allResult.size() <= shortResult.size()
+							+ longResult.size());
+					break;
+				default:
+					assertNull(shortResult);
+					assertNull(longResult);
+					assertNull(allResult);
+				}
+			}
+		}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInstance",
-        args = {java.util.Locale.class}
-    )
-    public void test_getInstanceLjava_util_Locale() {
-        Locale[] requiredLocales = {Locale.US, Locale.FRANCE};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        Calendar cal1 = Calendar.getInstance(Locale.FRANCE);
-        Locale.setDefault(Locale.FRANCE);
-        Calendar cal2 = Calendar.getInstance();
-        assertSame(cal1.getFirstDayOfWeek(), cal2.getFirstDayOfWeek());
-        Locale.setDefault(Locale.US);
-        cal2 = Calendar.getInstance();
-        assertNotSame(cal1.getFirstDayOfWeek(), cal2.getFirstDayOfWeek());
-    }
+		cal.setLenient(true);
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInstance",
-        args = {java.util.TimeZone.class}
-    )
-    public void test_get_InstanceLjava_util_TimeZone() {
-        Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT-6"));
-        Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT+1"));
-        assertNotSame(cal1.getTimeZone().getRawOffset(), cal2.getTimeZone().getRawOffset());
-    }
+		try {
+			cal.getDisplayNames(-1, Calendar.SHORT, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayNames(Calendar.FIELD_COUNT, Calendar.LONG, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayNames(Calendar.MONTH, -1, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayNames(Calendar.MONTH, 3, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, null);
+			fail("Should throw NullPointerException");
+		} catch (NullPointerException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayNames(-1, Calendar.SHORT, null);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			cal.getDisplayNames(Calendar.MONTH, -1, null);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+		cal.set(Calendar.SECOND, 999);
+		cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US);
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInstance",
-        args = {java.util.TimeZone.class, java.util.Locale.class}
-    )
-    public void test_getInstanceLjava_util_TimeZoneLjava_util_Locale() {
-        Locale[] requiredLocales = {Locale.US, Locale.FRANCE};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        Calendar cal1 = Calendar.getInstance(TimeZone.getTimeZone("GMT-6"), Locale.FRANCE);
-        Locale.setDefault(Locale.FRANCE);
-        Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT+1"));
-        assertSame(cal1.getFirstDayOfWeek(), cal2.getFirstDayOfWeek());
-        assertNotSame(cal1.getTimeZone().getRawOffset(), cal2.getTimeZone().getRawOffset());
-        Locale.setDefault(Locale.US);
-        cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT+1"));
-        assertNotSame(cal1.getFirstDayOfWeek(), cal2.getFirstDayOfWeek());
-        assertNotSame(cal1.getTimeZone().getRawOffset(), cal2.getTimeZone().getRawOffset());
-    }
+		// RI fails here
+		// invalid value for an un-related field when the calendar is not
+		// lenient
+		cal.setLenient(false);
+		cal.set(Calendar.SECOND, 999);
+		try {
+			cal.getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.US);
+			fail("Should throw IllegalArgumentException");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getMinimalDaysInFirstWeek",
-        args = {}
-    )
-    public void test_getMinimalDaysInFirstWeek() {
-        Locale[] requiredLocales = {Locale.US, Locale.FRANCE};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        Locale.setDefault(Locale.US);
-        Calendar cal = Calendar.getInstance();
-        assertEquals(1, cal.getMinimalDaysInFirstWeek());
-        Locale.setDefault(Locale.FRANCE);
-        cal = Calendar.getInstance();
-        assertEquals(4, cal.getMinimalDaysInFirstWeek());
-        Locale.setDefault(Locale.US);
-    }
+	private void assertDisplayNameMap(String[] values,
+			Map<String, Integer> result, int shift) {
+		List<String> trimValue = new ArrayList<String>();
+		for (String value : values) {
+			if (value.trim().length() > 0) {
+				trimValue.add(value);
+			}
+		}
+		assertEquals(trimValue.size(), result.size());
+		for (int i = 0; i < trimValue.size(); i++) {
+			assertEquals(i + shift, result.get(trimValue.get(i)).intValue());
+		}
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTime",
-        args = {}
-    )
-    public void test_getTime() {
-        Calendar cal = Calendar.getInstance();
-        Date d = new Date(1222185600225L);
-        
-        cal.setTimeInMillis(1222185600225L);
-        assertEquals(d.getTime(), cal.getTimeInMillis());
-        assertEquals(d, cal.getTime());
-    }
+	/**
+	 * @tests {@link java.util.Calendar#getActualMaximum(int)}
+	 */
+	public void test_getActualMaximum_I() {
+		Calendar c = new MockCalendar();
+		assertEquals("should be equal to 0", 0, c.getActualMaximum(0));
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getTimeZone",
-        args = {}
-    )
-    public void test_getTimeZone() {
-        Calendar cal = Calendar.getInstance();
-        cal.setTimeZone(TimeZone.getTimeZone("GMT-6"));
-        
-        assertEquals(TimeZone.getTimeZone("GMT-6"), cal.getTimeZone());
-        cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-8"));
-        assertEquals(TimeZone.getTimeZone("GMT-8"), cal.getTimeZone());
-    }
+	/**
+	 * @tests {@link java.util.Calendar#getActualMinimum(int)}
+	 */
+	public void test_getActualMinimum_I() {
+		Calendar c = new MockCalendar();
+		assertEquals("should be equal to 0", 0, c.getActualMinimum(0));
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
-    public void test_hashCode() {
-        Locale[] requiredLocales = {Locale.US, Locale.FRANCE};
-        if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
-            // locale dependent test, bug 1943269
-            return;
-        }
-        Calendar cal1 = Calendar.getInstance();
-        Locale.setDefault(Locale.FRANCE);
-        Calendar cal2 = Calendar.getInstance();
-        Locale.setDefault(Locale.US);
-        assertTrue(cal1.hashCode() != cal2.hashCode());
-    }
+	protected void setUp() {
+		defaultLocale = Locale.getDefault();
+		Locale.setDefault(Locale.US);
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "internalGet",
-        args = {int.class}
-    )
-    public void test_internalGet() {
-        Mock_Calendar mc = new Mock_Calendar();
-        assertEquals(0, mc.internalGetField(Calendar.MONTH));
-        mc.set(Calendar.MONTH, 35);
-        assertEquals(35, mc.internalGetField(Calendar.MONTH));
-        assertEquals(11, mc.get(Calendar.MONTH));
-    }
-
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "isLenient",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setLenient",
-            args = {boolean.class}
-        )
-    })
-    public void test_isLenient() {
-        Calendar cal = Calendar.getInstance();
-        assertTrue(cal.isLenient());
-        cal.set(Calendar.MONTH, 35);
-        cal.get(Calendar.MONTH);
-        cal.setLenient(false);
-        cal.set(Calendar.MONTH, 35);
-        try {
-            cal.get(Calendar.MONTH);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException e) {
-            //expected
-        }
-        assertFalse(cal.isLenient());
-        cal.setLenient(true);
-        cal.set(Calendar.MONTH, 35);
-        cal.get(Calendar.MONTH);
-        assertTrue(cal.isLenient());
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "isSet",
-        args = {int.class}
-    )
-    public void test_isSet() {
-        Calendar cal = Calendar.getInstance();
-        cal.clear();
-        assertFalse(cal.isSet(Calendar.MONTH));
-        cal.set(Calendar.MONTH, 35);
-        assertTrue(cal.isSet(Calendar.MONTH));
-        assertFalse(cal.isSet(Calendar.YEAR));
-        cal.get(Calendar.MONTH);
-        assertTrue(cal.isSet(Calendar.YEAR));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "roll",
-        args = {int.class, int.class}
-    )
-    public void test_rollII() {
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal.setTimeInMillis(1222185600225L);
-        cal.roll(Calendar.DAY_OF_MONTH, 200);
-        assertEquals(cal.get(Calendar.ERA), 1);
-        assertEquals(cal.get(Calendar.YEAR), 2008);
-        assertEquals(cal.get(Calendar.MONTH), Calendar.SEPTEMBER);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 13);
-        // Following line returns wrong value. Behavior uncompatible with RI.
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 18);
-        assertEquals(cal.get(Calendar.MINUTE), 0);
-        cal.roll(Calendar.DAY_OF_MONTH, -200);
-        assertEquals(cal.get(Calendar.ERA), 1);
-        assertEquals(cal.get(Calendar.YEAR), 2008);
-        assertEquals(cal.get(Calendar.MONTH), Calendar.SEPTEMBER);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 18);
-        assertEquals(cal.get(Calendar.MINUTE), 0);
-    }
-
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "set",
-            args = {int.class, int.class, int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setTimeInMillis",
-            args = {long.class}
-        )
-    })
-    public void test_setIII() {
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal.setTimeInMillis(1222185600225L);
-        assertEquals(1222185600225L, cal.getTimeInMillis());
-        assertEquals(cal.get(Calendar.YEAR), 2008);
-        assertEquals(cal.get(Calendar.MONTH), Calendar.SEPTEMBER);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
-        assertEquals(cal.get(Calendar.SECOND), 0);
-        
-        cal.set(1970, Calendar.JANUARY, 1);
-        assertEquals(cal.get(Calendar.ERA), 1);
-        // Following line returns wrong value. Behavior uncompatible with RI.
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 18);
-        assertEquals(cal.get(Calendar.MINUTE), 0);
-        assertEquals(cal.get(Calendar.SECOND), 0);
-
-        assertEquals(cal.get(Calendar.YEAR), 1970);
-        assertEquals(cal.get(Calendar.MONTH), 0);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 1);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "set",
-        args = {int.class, int.class, int.class, int.class, int.class}
-    )
-    public void test_setIIIII() {
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal.setTimeInMillis(1222185600225L);
-        assertEquals(cal.get(Calendar.YEAR), 2008);
-        assertEquals(cal.get(Calendar.MONTH), Calendar.SEPTEMBER);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
-        // Following line returns wrong value. Behavior uncompatible with RI.
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 18);
-        assertEquals(cal.get(Calendar.MINUTE), 0);
-        assertEquals(cal.get(Calendar.SECOND), 0);
-        
-        cal.set(1970, Calendar.JANUARY, 1, 0, 10);
-        assertEquals(cal.get(Calendar.ERA), 1);
-        assertEquals(cal.get(Calendar.SECOND), 0);
-    
-        assertEquals(cal.get(Calendar.YEAR), 1970);
-        assertEquals(cal.get(Calendar.MONTH), 0);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 1);
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 0);
-        assertEquals(cal.get(Calendar.MINUTE), 10);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "set",
-        args = {int.class, int.class, int.class, int.class, int.class, int.class}
-    )
-    public void test_setIIIIII() {
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+2"), defaultLocale);
-        
-        cal.setTimeInMillis(1222185600225L);
-        assertEquals(cal.get(Calendar.YEAR), 2008);
-        assertEquals(cal.get(Calendar.MONTH), Calendar.SEPTEMBER);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 23);
-        // Following line returns wrong value. Behavior uncompatible with RI.
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 18);
-        assertEquals(cal.get(Calendar.MINUTE), 0);
-        assertEquals(cal.get(Calendar.SECOND), 0);
-        
-        cal.set(1970, Calendar.JANUARY, 1, 0, 10, 33);
-        assertEquals(cal.get(Calendar.ERA), 1);
-    
-        assertEquals(cal.get(Calendar.YEAR), 1970);
-        assertEquals(cal.get(Calendar.MONTH), 0);
-        assertEquals(cal.get(Calendar.DAY_OF_MONTH), 1);
-        assertEquals(cal.get(Calendar.HOUR_OF_DAY), 0);
-        assertEquals(cal.get(Calendar.MINUTE), 10);
-        assertEquals(cal.get(Calendar.SECOND), 33);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setFirstDayOfWeek",
-        args = {int.class}
-    )
-    public void test_setFirstDayOfWeekI() {
-        Calendar cal = Calendar.getInstance();
-        
-        for (int i = 0; i < 10; i++) {
-            cal.setFirstDayOfWeek(i);
-            assertEquals(i, cal.getFirstDayOfWeek());
-        }
-        cal.setLenient(false);
-        cal.setFirstDayOfWeek(10);
-        cal.setFirstDayOfWeek(-10);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setMinimalDaysInFirstWeek",
-        args = {int.class}
-    )
-    public void test_setMinimalDaysInFirstWeekI() {
-        Calendar cal = Calendar.getInstance();
-        
-        for (int i = 0; i < 10; i++) {
-            cal.setMinimalDaysInFirstWeek(i);
-            assertEquals(i, cal.getMinimalDaysInFirstWeek());
-        }
-        cal.setLenient(false);
-        cal.setMinimalDaysInFirstWeek(10);
-        cal.setMinimalDaysInFirstWeek(-10);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setTimeZone",
-        args = {java.util.TimeZone.class}
-    )
-    public void test_setTimeZoneLjava_util_TimeZone() {
-        Calendar cal = Calendar.getInstance();
-        cal.setTimeZone(TimeZone.getTimeZone("GMT-6"));
-        assertEquals(TimeZone.getTimeZone("GMT-6"), cal.getTimeZone());
-        cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-8"));
-        cal.setTimeZone(TimeZone.getTimeZone("GMT-6"));
-        assertEquals(TimeZone.getTimeZone("GMT-6"), cal.getTimeZone());
-        
-        cal.setTimeZone(null);
-    }
-
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
-    public void test_toString() {
-        Calendar cal1 = Calendar.getInstance();
-        Calendar cal2 = Calendar.getInstance();
-        cal1.setTimeZone(TimeZone.getTimeZone("GMT-6"));
-        cal2.setTimeZone(TimeZone.getTimeZone("GMT-8"));
-        cal1.set(Calendar.MILLISECOND, 0);
-        cal2.set(Calendar.MILLISECOND, 0);
-        assertFalse(cal1.toString().equals(cal2.toString()));
-        cal1.setTimeZone(TimeZone.getTimeZone("GMT-8"));
-        assertTrue(cal1.toString().equals(cal2.toString()));
-    }
-    
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        method = "get",
-        args = {int.class}
-    )
-    public void test_EdgeCases() {
-        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
-        
-        c.setTimeInMillis(Long.MAX_VALUE);
-        
-        assertEquals(292278994, c.get(Calendar.YEAR));
-        assertEquals(Calendar.AUGUST, c.get(Calendar.MONTH));
-        assertEquals(17, c.get(Calendar.DAY_OF_MONTH));
-        assertEquals(Calendar.SUNDAY, c.get(Calendar.DAY_OF_WEEK));
-        assertEquals(7, c.get(Calendar.HOUR_OF_DAY));
-        assertEquals(12, c.get(Calendar.MINUTE));
-        assertEquals(55, c.get(Calendar.SECOND));
-    }
-
-    protected void setUp() {
-        defaultLocale = Locale.getDefault();
-        Locale.setDefault(Locale.US);
-    }
-
-    protected void tearDown() {
-        Locale.setDefault(defaultLocale);
-    }
+	protected void tearDown() {
+		Locale.setDefault(defaultLocale);
+	}
 }
diff --git a/luni/src/test/java/tests/api/java/util/CollectionsTest.java b/luni/src/test/java/tests/api/java/util/CollectionsTest.java
index 7fc60d8..897b355 100644
--- a/luni/src/test/java/tests/api/java/util/CollectionsTest.java
+++ b/luni/src/test/java/tests/api/java/util/CollectionsTest.java
@@ -43,8 +43,6 @@
 import java.util.TreeSet;
 import java.util.Arrays;
 
-import org.apache.harmony.luni.internal.nls.Messages;
-
 import tests.support.Support_CollectionTest;
 import tests.support.Support_ListTest;
 import tests.support.Support_SetTest;
diff --git a/luni/src/test/java/tests/api/java/util/FormatterTest.java b/luni/src/test/java/tests/api/java/util/FormatterTest.java
index 7709b88..ea53e8c 100644
--- a/luni/src/test/java/tests/api/java/util/FormatterTest.java
+++ b/luni/src/test/java/tests/api/java/util/FormatterTest.java
@@ -2073,6 +2073,7 @@
         args = {java.lang.String.class, java.lang.Object[].class}
     )
     @AndroidOnly("ICU data is different from RI data")
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void test_formatLjava_lang_String$Ljava_lang_Object_DateTimeConversion() {
         Locale[] requiredLocales = {Locale.FRANCE, Locale.CHINA, Locale.GERMAN, Locale.US};
         if (!Support_Locale.areLocalesAvailable(requiredLocales)) {
@@ -3165,8 +3166,6 @@
         method = "format",
         args = {java.lang.String.class, java.lang.Object[].class}
     )
-    @KnownFailure("Formatting of Double.MIN_VALUE works improperly")
-    @AndroidOnly("last case fails on RI. See comment below")
     public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionE() {
         Formatter f = null;
         final Object[][] tripleE = {
@@ -3400,8 +3399,6 @@
         method = "format",
         args = {java.lang.String.class, java.lang.Object[].class}
     )
-    @KnownFailure("Formatting of Double.MIN_VALUE works improperly")
-    @AndroidOnly("last case fails on RI. See comment below")
     public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionG() {
         Formatter f = null;
         final Object[][] tripleG = {
@@ -3652,7 +3649,6 @@
         method = "format",
         args = {java.lang.String.class, java.lang.Object[].class}
     )
-    @KnownFailure("Formatting of Float.MAX_VALUE works improperly")
     public void test_formatLjava_lang_String$Ljava_lang_Object_FloatConversionF() {
         Formatter f = null;
 
@@ -4157,8 +4153,6 @@
         method = "format",
         args = {java.lang.String.class, java.lang.Object[].class}
     )
-    @KnownFailure("Formatting of BigDecimal lost precission sometimes")
-    @AndroidOnly("last case fails on RI. See comment below")
     public void test_formatLjava_lang_String$Ljava_lang_Object_BigDecimalConversionG() {
         Formatter f = null;
         final Object[][] tripleG = {
diff --git a/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java b/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
index aba02a5..b64fcd1 100644
--- a/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
+++ b/luni/src/test/java/tests/api/java/util/GregorianCalendarTest.java
@@ -770,8 +770,6 @@
         method = "getMinimalDaysInFirstWeek",
         args = {}
     )
-    @KnownFailure("Some difference in timezones and/or locales data"
-            + "Who is right, the CLDR or the RI?")
     public void test_getMinimalDaysInFirstWeek() {
         // Regression for Harmony-1037
         GregorianCalendar g = new GregorianCalendar(TimeZone
diff --git a/luni/src/test/java/tests/api/java/util/PropertiesTest.java b/luni/src/test/java/tests/api/java/util/PropertiesTest.java
index ddf9994..d1d4c67 100644
--- a/luni/src/test/java/tests/api/java/util/PropertiesTest.java
+++ b/luni/src/test/java/tests/api/java/util/PropertiesTest.java
@@ -17,24 +17,29 @@
 
 package tests.api.java.util;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.InvalidPropertiesFormatException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Properties;
+import java.util.Scanner;
+import java.util.Set;
 
 import tests.support.resource.Support_Resources;
 
-@TestTargetClass(Properties.class) 
 public class PropertiesTest extends junit.framework.TestCase {
 
     Properties tProps;
@@ -44,76 +49,76 @@
     /**
      * @tests java.util.Properties#Properties()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Properties",
-        args = {}
-    )
     public void test_Constructor() {
+        // Test for method java.util.Properties()
         Properties p = new Properties();
         // do something to avoid getting a variable unused warning
         p.clear();
+        assertTrue("Created incorrect Properties", true);
+    }
+
+    public void test_loadLjava_io_InputStream_NPE() throws Exception {
+        Properties p = new Properties();
+        try {
+            p.load((InputStream) null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
+    
+    public void test_loadsave() throws Exception{
+        Properties p = new Properties();
+        try {
+            p.load((InputStream) null);
+            fail("should throw NPE");
+        } catch (NullPointerException npe) {
+        	// expected
+        }        
     }
 
     /**
      * @tests java.util.Properties#Properties(java.util.Properties)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Properties",
-        args = {java.util.Properties.class}
-    )
     public void test_ConstructorLjava_util_Properties() {
-        if (System.getProperty("java.vendor") != null) {
-            Properties p = new Properties(System.getProperties());
-            assertNotNull("failed to construct correct properties", p
-                    .getProperty("java.vendor"));
+        Properties systemProperties = System.getProperties();
+        Properties properties = new Properties(systemProperties);
+        Enumeration<?> propertyNames = systemProperties.propertyNames();
+        String propertyName = null;
+        while (propertyNames.hasMoreElements()) {
+            propertyName = (String) propertyNames.nextElement();
+            assertEquals("failed to construct correct properties",
+                    systemProperties.get(propertyName), properties
+                            .getProperty(propertyName));
         }
     }
 
     /**
      * @tests java.util.Properties#getProperty(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Verifies positive case.",
-        method = "getProperty",
-        args = {java.lang.String.class}
-    )
     public void test_getPropertyLjava_lang_String() {
+        // Test for method java.lang.String
+        // java.util.Properties.getProperty(java.lang.String)
         assertEquals("Did not retrieve property", "this is a test property",
-                tProps.getProperty("test.prop"));
+                ((String) tProps.getProperty("test.prop")));
     }
 
     /**
      * @tests java.util.Properties#getProperty(java.lang.String,
      *        java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getProperty",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void test_getPropertyLjava_lang_StringLjava_lang_String() {
+        // Test for method java.lang.String
+        // java.util.Properties.getProperty(java.lang.String, java.lang.String)
         assertEquals("Did not retrieve property", "this is a test property",
-                tProps.getProperty("test.prop", "Blarg"));
-        assertEquals("Did not return default value", "Gabba", tProps
-                .getProperty("notInThere.prop", "Gabba"));
-        assertNull(tProps.getProperty("", null));
+                ((String) tProps.getProperty("test.prop", "Blarg")));
+        assertEquals("Did not return default value", "Gabba", ((String) tProps
+                .getProperty("notInThere.prop", "Gabba")));
     }
 
     /**
      * @tests java.util.Properties#getProperty(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test.",
-        method = "getProperty",
-        args = {java.lang.String.class}
-    )
     public void test_getPropertyLjava_lang_String2() {
         // regression test for HARMONY-3518
         MyProperties props = new MyProperties();
@@ -124,16 +129,10 @@
      * @tests java.util.Properties#getProperty(java.lang.String,
      *        java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Regression test.",
-        method = "getProperty",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void test_getPropertyLjava_lang_StringLjava_lang_String2() {
         // regression test for HARMONY-3518
         MyProperties props = new MyProperties();
-        assertEquals(props.getProperty("key", "defaultValue"), "defaultValue");
+        assertEquals("defaultValue", props.getProperty("key", "defaultValue"));
     }
 
     // regression testing for HARMONY-3518
@@ -146,67 +145,179 @@
     /**
      * @tests java.util.Properties#list(java.io.PrintStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "list",
-        args = {java.io.PrintStream.class}
-    )
     public void test_listLjava_io_PrintStream() {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         PrintStream ps = new PrintStream(baos);
         Properties myProps = new Properties();
-        String propList;
         myProps.setProperty("Abba", "Cadabra");
         myProps.setProperty("Open", "Sesame");
+        myProps.setProperty("LongProperty",
+                "a long long long long long long long property");
         myProps.list(ps);
         ps.flush();
-        propList = baos.toString();
-        assertTrue("Property list innacurate", (propList
-                .indexOf("Abba=Cadabra") >= 0)
-                && (propList.indexOf("Open=Sesame") >= 0));
+        String propList = baos.toString();
+        assertTrue("Property list innacurate",
+                propList.indexOf("Abba=Cadabra") >= 0);
+        assertTrue("Property list innacurate",
+                propList.indexOf("Open=Sesame") >= 0);
+        assertTrue("property list do not conatins \"...\"", propList
+                .indexOf("...") != -1);
+
+        ps = null;
+        try {
+            myProps.list(ps);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
     }
 
     /**
      * @tests java.util.Properties#list(java.io.PrintWriter)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "list",
-        args = {java.io.PrintWriter.class}
-    )
     public void test_listLjava_io_PrintWriter() {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         PrintWriter pw = new PrintWriter(baos);
         Properties myProps = new Properties();
-        String propList;
         myProps.setProperty("Abba", "Cadabra");
         myProps.setProperty("Open", "Sesame");
+        myProps.setProperty("LongProperty",
+                "a long long long long long long long property");
         myProps.list(pw);
         pw.flush();
-        propList = baos.toString();
-        assertTrue("Property list innacurate", (propList
-                .indexOf("Abba=Cadabra") >= 0)
-                && (propList.indexOf("Open=Sesame") >= 0));
+        String propList = baos.toString();
+        assertTrue("Property list innacurate",
+                propList.indexOf("Abba=Cadabra") >= 0);
+        assertTrue("Property list innacurate",
+                propList.indexOf("Open=Sesame") >= 0);
+        pw = null;
+        try {
+            myProps.list(pw);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests java.util.Properties#load(java.io.InputStream)
+     */
+    public void test_loadLjava_io_InputStream() {
+        // Test for method void java.util.Properties.load(java.io.InputStream)
+        Properties prop = null;
+        try {
+            InputStream is;
+            prop = new Properties();
+            prop.load(is = new ByteArrayInputStream(writeProperties()));
+            is.close();
+        } catch (Exception e) {
+            fail("Exception during load test : " + e.getMessage());
+        }
+        assertEquals("Failed to load correct properties", "harmony.tests", prop
+                .getProperty("test.pkg"));
+        assertNull("Load failed to parse incorrectly", prop
+                .getProperty("commented.entry"));
+
+        prop = new Properties();
+		try {
+			prop.load(new ByteArrayInputStream("=".getBytes()));
+		} catch (IOException e) {
+			// expected
+		}
+        assertTrue("Failed to add empty key", prop.get("").equals(""));
+
+        prop = new Properties();
+        try {
+			prop.load(new ByteArrayInputStream(" = ".getBytes()));
+		} catch (IOException e) {
+			// expected
+		}
+        assertTrue("Failed to add empty key2", prop.get("").equals(""));
+
+		prop = new Properties();
+		try {
+			prop.load(new ByteArrayInputStream(" a= b".getBytes()));
+		} catch (IOException e) {
+			// expected
+		}
+		assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
+
+		prop = new Properties();
+		try {
+			prop.load(new ByteArrayInputStream(" a b".getBytes()));
+		} catch (IOException e) {
+			// expected
+		}
+		assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
+
+		prop = new Properties();
+		try {
+			prop.load(new ByteArrayInputStream("#\u008d\u00d2\na=\u008d\u00d3"
+					.getBytes("ISO8859_1")));
+		} catch (IOException e) {
+			// expected
+		}
+		assertEquals("Failed to parse chars >= 0x80", "\u008d\u00d3", prop
+				.get("a"));
+
+		prop = new Properties();
+		try {
+			prop.load(new ByteArrayInputStream(
+					"#properties file\r\nfred=1\r\n#last comment"
+							.getBytes("ISO8859_1")));
+		} catch (IOException e) {
+			// expected
+		} catch (IndexOutOfBoundsException e) {
+			fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
+		}
+        assertEquals("Failed to load when last line contains a comment", "1",
+                prop.get("fred"));
+    }
+
+    /**
+	 * @tests java.util.Properties#load(java.io.InputStream)
+	 */
+    public void test_loadLjava_io_InputStream_subtest0() {
+        try {
+            InputStream is = Support_Resources
+                    .getStream("hyts_PropertiesTest.properties");
+            Properties props = new Properties();
+            props.load(is);
+            is.close();
+            assertEquals("1", "\n \t \f", props.getProperty(" \r"));
+            assertEquals("2", "a", props.getProperty("a"));
+            assertEquals("3", "bb as,dn   ", props.getProperty("b"));
+            assertEquals("4", ":: cu", props.getProperty("c\r \t\nu"));
+            assertEquals("5", "bu", props.getProperty("bu"));
+            assertEquals("6", "d\r\ne=e", props.getProperty("d"));
+            assertEquals("7", "fff", props.getProperty("f"));
+            assertEquals("8", "g", props.getProperty("g"));
+            assertEquals("9", "", props.getProperty("h h"));
+            assertEquals("10", "i=i", props.getProperty(" "));
+            assertEquals("11", "   j", props.getProperty("j"));
+            assertEquals("12", "   c", props.getProperty("space"));
+            assertEquals("13", "\\", props.getProperty("dblbackslash"));
+        } catch (IOException e) {
+            fail("Unexpected: " + e);
+        }
     }
 
     /**
      * @throws IOException
-     * @tests java.util.Properties#load(java.io.InputStream)
+     * @tests java.util.Properties#load(java.io.Reader)
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "load",
-        args = {java.io.InputStream.class}
-    )
-    public void test_loadLjava_io_InputStream() throws IOException {
-        Properties prop = new Properties();
-        InputStream is = new ByteArrayInputStream(writeProperties());
-        prop.load(is);
-        is.close();
-        
+    public void test_loadLjava_io_Reader() throws IOException {
+        Properties prop = null;
+        try {
+            InputStream is;
+            prop = new Properties();
+            is = new ByteArrayInputStream(writeProperties());
+            prop.load(new InputStreamReader(is));
+            is.close();
+        } catch (Exception e) {
+            fail("Exception during load test : " + e.getMessage());
+        }
         assertEquals("Failed to load correct properties", "harmony.tests", prop
                 .getProperty("test.pkg"));
         assertNull("Load failed to parse incorrectly", prop
@@ -214,11 +325,11 @@
 
         prop = new Properties();
         prop.load(new ByteArrayInputStream("=".getBytes()));
-        assertTrue("Failed to add empty key", prop.get("").equals(""));
+        assertEquals("Failed to add empty key", "", prop.get(""));
 
         prop = new Properties();
         prop.load(new ByteArrayInputStream(" = ".getBytes()));
-        assertTrue("Failed to add empty key2", prop.get("").equals(""));
+        assertEquals("Failed to add empty key2", "", prop.get(""));
 
         prop = new Properties();
         prop.load(new ByteArrayInputStream(" a= b".getBytes()));
@@ -229,42 +340,102 @@
         assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
 
         prop = new Properties();
-        prop.load(new ByteArrayInputStream("#\u008d\u00d2\na=\u008d\u00d3"
-                .getBytes("ISO8859_1")));
-        assertEquals("Failed to parse chars >= 0x80", "\u008d\u00d3", prop
-                .get("a"));
+        prop.load(new ByteArrayInputStream("#comment\na=value"
+                .getBytes("UTF-8")));
+        assertEquals("value", prop.getProperty("a"));
 
         prop = new Properties();
-        prop.load(new ByteArrayInputStream(
-                "#properties file\r\nfred=1\r\n#last comment"
-                        .getBytes("ISO8859_1")));
+        prop.load(new InputStreamReader(new ByteArrayInputStream(
+                "#\u008d\u00d2\na=\u008d\u00d3".getBytes("UTF-8"))));
+        try {
+            prop
+                    .load(new InputStreamReader(new ByteArrayInputStream(
+                            "#\u008d\u00d2\na=\\\\u008d\\\\\\uu00d3"
+                                    .getBytes("UTF-8"))));
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        prop = new Properties();
+        try {
+            prop.load(new InputStreamReader(new ByteArrayInputStream(
+                    "#properties file\r\nfred=1\r\n#last comment"
+                            .getBytes("ISO8859_1"))));
+        } catch (IndexOutOfBoundsException e) {
+            fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
+        }
         assertEquals("Failed to load when last line contains a comment", "1",
                 prop.get("fred"));
 
-        ByteArrayInputStream bais = new ByteArrayInputStream(new byte[]{'\\', 'u', 'x', 'x', 'x', 'x'});
+        // Regression tests for HARMONY-5414
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("a=\\u1234z".getBytes()));
+
+        prop = new Properties();
         try {
-            prop.load(bais);
-            fail("IllegalArgumentException expected");
+            prop.load(new ByteArrayInputStream("a=\\u123".getBytes()));
+            fail("should throw IllegalArgumentException");
         } catch (IllegalArgumentException e) {
-            //expected
+            // Expected
         }
+
+        prop = new Properties();
+        try {
+            prop.load(new ByteArrayInputStream("a=\\u123z".getBytes()));
+            fail("should throw IllegalArgumentException");
+        } catch (IllegalArgumentException expected) {
+            // Expected
+        }
+
+        prop = new Properties();
+        Properties expected = new Properties();
+        expected.put("a", "\u0000");
+        prop.load(new ByteArrayInputStream("a=\\".getBytes()));
+        assertEquals("Failed to read trailing slash value", expected, prop);
+
+        prop = new Properties();
+        expected = new Properties();
+        expected.put("a", "\u1234\u0000");
+        prop.load(new ByteArrayInputStream("a=\\u1234\\".getBytes()));
+        assertEquals("Failed to read trailing slash value #2", expected, prop);
+
+        prop = new Properties();
+        expected = new Properties();
+        expected.put("a", "q");
+        prop.load(new ByteArrayInputStream("a=\\q".getBytes()));
+        assertEquals("Failed to read slash value #3", expected, prop);
+    }
+    
+    /**
+     * @tests java.util.Properties#load(java.io.InputStream)
+     */
+    public void test_loadLjava_io_InputStream_Special() throws IOException {
+        // Test for method void java.util.Properties.load(java.io.InputStream)
+        Properties prop = null;
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("=".getBytes()));
+        assertTrue("Failed to add empty key", prop.get("").equals(""));
+        
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("=\r\n".getBytes()));
+        assertTrue("Failed to add empty key", prop.get("").equals(""));
+        
+        prop = new Properties();
+        prop.load(new ByteArrayInputStream("=\n\r".getBytes()));
+        assertTrue("Failed to add empty key", prop.get("").equals(""));
     }
 
     /**
      * @throws IOException
-     * @tests java.util.Properties#load(java.io.InputStream)
+     * @tests java.util.Properties#load(java.io.Reader)
+     * @since 1.6
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Doesn't verify IOException, IllegalArgumentException.",
-        method = "load",
-        args = {java.io.InputStream.class}
-    )
-    public void test_loadLjava_io_InputStream_subtest0() throws IOException {
+    public void test_loadLjava_io_Reader_subtest0() throws IOException {
         InputStream is = Support_Resources
                 .getStream("hyts_PropertiesTest.properties");
         Properties props = new Properties();
-        props.load(is);
+        props.load(new InputStreamReader(is));
         is.close();
         assertEquals("1", "\n \t \f", props.getProperty(" \r"));
         assertEquals("2", "a", props.getProperty("a"));
@@ -282,36 +453,240 @@
     }
 
     /**
-     * @throws IOException
+     * @tests java.util.Properties#propertyNames()
+     */
+    public void test_propertyNames() {
+        Properties myPro = new Properties(tProps);
+        Enumeration names = myPro.propertyNames();
+        int i = 0;
+        while (names.hasMoreElements()) {
+            ++i;
+            String p = (String) names.nextElement();
+            assertTrue("Incorrect names returned", p.equals("test.prop")
+                    || p.equals("bogus.prop"));
+        }
+    }
+
+    public void test_propertyNames_sequence() {
+        Properties parent = new Properties();
+        parent.setProperty("parent.a.key", "parent.a.value");
+        parent.setProperty("parent.b.key", "parent.b.value");
+
+        Enumeration<?> names = parent.propertyNames();
+        assertEquals("parent.a.key", names.nextElement());
+        assertEquals("parent.b.key", names.nextElement());
+        assertFalse(names.hasMoreElements());
+
+        Properties current = new Properties(parent);
+        current.setProperty("current.a.key", "current.a.value");
+        current.setProperty("current.b.key", "current.b.value");
+
+        names = current.propertyNames();
+        assertEquals("parent.a.key", names.nextElement());
+        assertEquals("current.b.key", names.nextElement());
+        assertEquals("parent.b.key", names.nextElement());
+        assertEquals("current.a.key", names.nextElement());
+        assertFalse(names.hasMoreElements());
+
+        Properties child = new Properties(current);
+        child.setProperty("child.a.key", "child.a.value");
+        child.setProperty("child.b.key", "child.b.value");
+
+        names = child.propertyNames();
+        assertEquals("parent.a.key", names.nextElement());
+        assertEquals("child.b.key", names.nextElement());
+        assertEquals("current.b.key", names.nextElement());
+        assertEquals("parent.b.key", names.nextElement());
+        assertEquals("child.a.key", names.nextElement());
+        assertEquals("current.a.key", names.nextElement());
+        assertFalse(names.hasMoreElements());
+    }
+
+    /**
+     * @tests {@link java.util.Properties#stringPropertyNames()}
+     * @since 1.6
+     */
+    public void test_stringPropertyNames() {
+        Set<String> set = tProps.stringPropertyNames();
+        assertEquals(2, set.size());
+        assertTrue(set.contains("test.prop"));
+        assertTrue(set.contains("bogus.prop"));
+        assertNotSame(set, tProps.stringPropertyNames());
+
+        set = new Properties().stringPropertyNames();
+        assertEquals(0, set.size());
+
+        set = new Properties(System.getProperties()).stringPropertyNames();
+        assertTrue(set.size() > 0);
+
+        tProps = new Properties(tProps);
+        tProps.put("test.prop", "anotherValue");
+        tProps.put("3rdKey", "3rdValue");
+        set = tProps.stringPropertyNames();
+        assertEquals(3, set.size());
+        assertTrue(set.contains("test.prop"));
+        assertTrue(set.contains("bogus.prop"));
+        assertTrue(set.contains("3rdKey"));
+
+        tProps.put(String.class, "valueOfNonStringKey");
+        set = tProps.stringPropertyNames();
+        assertEquals(3, set.size());
+        assertTrue(set.contains("test.prop"));
+        assertTrue(set.contains("bogus.prop"));
+        assertTrue(set.contains("3rdKey"));
+
+        tProps.put("4thKey", "4thValue");
+        assertEquals(4, tProps.size());
+        assertEquals(3, set.size());
+
+        try {
+            set.add("another");
+            fail("Should throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+    }
+
+    /**
+     * @tests {@link java.util.Properties#stringPropertyNames()}
+     * @since 1.6
+     */
+    public void test_stringPropertyNames_scenario1() {
+        String[] keys = new String[] { "key1", "key2", "key3" };
+        String[] values = new String[] { "value1", "value2", "value3" };
+        List<String> keyList = Arrays.asList(keys);
+
+        Properties properties = new Properties();
+        for (int index = 0; index < keys.length; index++) {
+            properties.setProperty(keys[index], values[index]);
+        }
+
+        properties = new Properties(properties);
+        Set<String> nameSet = properties.stringPropertyNames();
+        assertEquals(keys.length, nameSet.size());
+        Iterator<String> iterator = nameSet.iterator();
+        while (iterator.hasNext()) {
+            assertTrue(keyList.contains(iterator.next()));
+        }
+
+        Enumeration<?> nameEnum = properties.propertyNames();
+        int count = 0;
+        while (nameEnum.hasMoreElements()) {
+            count++;
+            assertTrue(keyList.contains(nameEnum.nextElement()));
+        }
+        assertEquals(keys.length, count);
+
+        properties = new Properties(properties);
+        nameSet = properties.stringPropertyNames();
+        assertEquals(keys.length, nameSet.size());
+        iterator = nameSet.iterator();
+        while (iterator.hasNext()) {
+            assertTrue(keyList.contains(iterator.next()));
+        }
+
+        nameEnum = properties.propertyNames();
+        count = 0;
+        while (nameEnum.hasMoreElements()) {
+            count++;
+            assertTrue(keyList.contains(nameEnum.nextElement()));
+        }
+        assertEquals(keys.length, count);
+    }
+
+    /**
+     * @tests {@link java.util.Properties#stringPropertyNames()}
+     * @since 1.6
+     */
+    public void test_stringPropertyNames_scenario2() {
+        String[] defaultKeys = new String[] { "defaultKey1", "defaultKey2",
+                "defaultKey3", "defaultKey4", "defaultKey5", "defaultKey6" };
+        String[] defaultValues = new String[] { "defaultValue1",
+                "defaultValue2", "defaultValue3", "defaultValue4",
+                "defaultValue5", "defaultValue6" };
+        List<String> keyList = new ArrayList<String>();
+        Properties defaults = new Properties();
+        for (int index = 0; index < 3; index++) {
+            defaults.setProperty(defaultKeys[index], defaultValues[index]);
+            keyList.add(defaultKeys[index]);
+        }
+
+        String[] keys = new String[] { "key1", "key2", "key3" };
+        String[] values = new String[] { "value1", "value2", "value3" };
+        Properties properties = new Properties(defaults);
+        for (int index = 0; index < keys.length; index++) {
+            properties.setProperty(keys[index], values[index]);
+            keyList.add(keys[index]);
+        }
+
+        Set<String> nameSet = properties.stringPropertyNames();
+        assertEquals(keyList.size(), nameSet.size());
+        Iterator<String> iterator = nameSet.iterator();
+        while (iterator.hasNext()) {
+            assertTrue(keyList.contains(iterator.next()));
+        }
+
+        Enumeration<?> nameEnum = properties.propertyNames();
+        int count = 0;
+        while (nameEnum.hasMoreElements()) {
+            count++;
+            assertTrue(keyList.contains(nameEnum.nextElement()));
+        }
+        assertEquals(keyList.size(), count);
+
+        for (int index = 3; index < defaultKeys.length; index++) {
+            defaults.setProperty(defaultKeys[index], defaultValues[index]);
+            keyList.add(defaultKeys[index]);
+        }
+
+        nameSet = properties.stringPropertyNames();
+        assertEquals(keyList.size(), nameSet.size());
+        iterator = nameSet.iterator();
+        while (iterator.hasNext()) {
+            assertTrue(keyList.contains(iterator.next()));
+        }
+
+        nameEnum = properties.propertyNames();
+        count = 0;
+        while (nameEnum.hasMoreElements()) {
+            count++;
+            assertTrue(keyList.contains(nameEnum.nextElement()));
+        }
+        assertEquals(keyList.size(), count);
+    }
+
+    /**
      * @tests java.util.Properties#save(java.io.OutputStream, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "save",
-        args = {java.io.OutputStream.class, java.lang.String.class}
-    )
-    public void test_saveLjava_io_OutputStreamLjava_lang_String()
-            throws IOException {
+    public void test_saveLjava_io_OutputStreamLjava_lang_String() {
+        // Test for method void java.util.Properties.save(java.io.OutputStream,
+        // java.lang.String)
         Properties myProps = new Properties();
+        Properties myProps2 = new Properties();
+
         myProps.setProperty("Property A", "aye");
         myProps.setProperty("Property B", "bee");
         myProps.setProperty("Property C", "see");
 
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        myProps.save(out, "A Header");
-        out.close();
-
-        Properties myProps2 = new Properties();
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        myProps2.load(in);
-        in.close();
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            myProps.save(out, "A Header");
+            out.close();
+            ByteArrayInputStream in = new ByteArrayInputStream(out
+                    .toByteArray());
+            myProps2.load(in);
+            in.close();
+        } catch (IOException ioe) {
+            fail("IOException occurred reading/writing file : "
+                    + ioe.getMessage());
+        }
 
         Enumeration e = myProps.propertyNames();
+        String nextKey;
         while (e.hasMoreElements()) {
-            String nextKey = (String) e.nextElement();
-            assertTrue("Stored property list not equal to original", myProps2
-                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+            nextKey = (String) e.nextElement();
+            assertEquals("Stored property list not equal to original", myProps
+                    .getProperty(nextKey), myProps2.getProperty(nextKey));
         }
     }
 
@@ -319,13 +694,9 @@
      * @tests java.util.Properties#setProperty(java.lang.String,
      *        java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setProperty",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void test_setPropertyLjava_lang_StringLjava_lang_String() {
+        // Test for method java.lang.Object
+        // java.util.Properties.setProperty(java.lang.String, java.lang.String)
         Properties myProps = new Properties();
         myProps.setProperty("Yoink", "Yabba");
         assertEquals("Failed to set property", "Yabba", myProps
@@ -336,94 +707,132 @@
     }
 
     /**
-     * @throws IOException
      * @tests java.util.Properties#store(java.io.OutputStream, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "store",
-        args = {java.io.OutputStream.class, java.lang.String.class}
-    )
-    public void test_storeLjava_io_OutputStreamLjava_lang_String()
-            throws IOException {
+    public void test_storeLjava_io_OutputStreamLjava_lang_String() {
+        // Test for method void java.util.Properties.store(java.io.OutputStream,
+        // java.lang.String)
         Properties myProps = new Properties();
+        Properties myProps2 = new Properties();
+        Enumeration e;
+        String nextKey;
+
         myProps.put("Property A", " aye\\\f\t\n\r\b");
         myProps.put("Property B", "b ee#!=:");
         myProps.put("Property C", "see");
 
-        Properties myProps2 = new Properties();
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        myProps.store(out, "A Header");
-        myProps.store(out, null);
-        out.close();
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            myProps.store(out, "A Header");
+            out.close();
+            ByteArrayInputStream in = new ByteArrayInputStream(out
+                    .toByteArray());
+            myProps2.load(in);
+            in.close();
+        } catch (IOException ioe) {
+            fail("IOException occurred reading/writing file : "
+                    + ioe.getMessage());
+        }
 
+        e = myProps.propertyNames();
+        while (e.hasMoreElements()) {
+            nextKey = (String) e.nextElement();
+            assertTrue("Stored property list not equal to original", myProps2
+                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+        }
+
+    }
+
+    /**
+     * @throws IOException
+     * @tests java.util.Properties#store(java.io.Writer, java.lang.String)
+     * @since 1.6
+     */
+    public void test_storeLjava_io_WriterLjava_lang_String() throws IOException {
+        Properties myProps = new Properties();
+        Properties myProps2 = new Properties();
+
+        myProps.put("Property A", " aye\\\f\t\n\r\b");
+        myProps.put("Property B", "b ee#!=:");
+        myProps.put("Property C", "see");
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        myProps.store(new OutputStreamWriter(out), "A Header");
+        Scanner scanner = new Scanner(out.toString());
+        assertTrue(scanner.nextLine().startsWith("#A Header"));
+        assertTrue(scanner.nextLine().startsWith("#"));
+        out.close();
         ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
         myProps2.load(in);
         in.close();
 
         Enumeration e = myProps.propertyNames();
+        String nextKey;
         while (e.hasMoreElements()) {
-            String nextKey = (String) e.nextElement();
+            nextKey = (String) e.nextElement();
             assertTrue("Stored property list not equal to original", myProps2
                     .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
         }
-        
+
         try {
-            myProps.store(null, "String");
-            fail("NullPointerException expected");
-        } catch (NullPointerException ee){
-            //expected
+            myProps.store((Writer) null, "some comments");
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e1) {
+            // expected
+        }
+
+        myProps.put(String.class, "wrong type");
+        try {
+            myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+                    "some comments");
+            fail("Should throw ClassCastException");
+        } catch (ClassCastException e1) {
+            // expected
+        }
+        myProps.remove(String.class);
+        myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+                "some comments");
+        // it is OK
+        myProps.put("wrong type", String.class);
+        try {
+            myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
+                    "some comments");
+            fail("Should throw ClassCastException");
+        } catch (ClassCastException e1) {
+            // expected
         }
     }
 
     /**
-     * @throws IOException
      * @tests java.util.Properties#loadFromXML(java.io.InputStream)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "loadFromXML",
-        args = {java.io.InputStream.class}
-    )
-    @KnownFailure("Expected Exception is not thrown.")
-    public void test_loadFromXMLLjava_io_InputStream() throws IOException {
-        Properties myProps = new Properties();
-        myProps.put("Property A", " aye\\\f\t\n\r\b");
-        myProps.put("Property B", "b ee#!=:");
-        myProps.put("Property C", "see");
-        Properties myProps2 = new Properties();
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        myProps.storeToXML(out, "A Header");
-        out.close();
-        
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+    public void test_loadFromXMLLjava_io_InputStream() throws Exception {
+        // Test for method void
+        // java.util.Properties.loadFromXML(java.io.InputStream)
+        Properties prop = null;
         try {
-            myProps2.loadFromXML(in);
-            fail("InvalidPropertiesFormatException expected");
-        } catch (InvalidPropertiesFormatException e) {
-            //expected
+            InputStream is;
+            prop = new Properties();
+            prop.loadFromXML(is = new ByteArrayInputStream(
+                    writePropertiesXMLUTF_8()));
+            is.close();
+        } catch (Exception e) {
+            fail("Exception during load test : " + e.getMessage());
         }
-        in.close();
-        
-        
-        Properties prop = new Properties();
-        InputStream is = new ByteArrayInputStream(writePropertiesXML("UTF-8"));
-        prop.loadFromXML(is);
-        is.close();
-
         assertEquals("Failed to load correct properties", "value3", prop
                 .getProperty("key3"));
         assertEquals("Failed to load correct properties", "value1", prop
                 .getProperty("key1"));
 
-        prop = new Properties();
-        is = new ByteArrayInputStream(writePropertiesXML("ISO-8859-1"));
-        prop.loadFromXML(is);
-        is.close();
-
+        try {
+            InputStream is;
+            prop = new Properties();
+            prop.loadFromXML(is = new ByteArrayInputStream(
+                    writePropertiesXMLISO_8859_1()));
+            is.close();
+        } catch (Exception e) {
+            fail("Exception during load test : " + e.getMessage());
+        }
         assertEquals("Failed to load correct properties", "value2", prop
                 .getProperty("key2"));
         assertEquals("Failed to load correct properties", "value1", prop
@@ -431,26 +840,26 @@
         
         try {
             prop.loadFromXML(null);
-            fail("NullPointerException expected");
+            fail("should throw NullPointerException");
         } catch (NullPointerException e) {
-            //expected
+            // expected
         }
     }
 
     /**
-     * @throws IOException
      * @tests java.util.Properties#storeToXML(java.io.OutputStream,
      *        java.lang.String, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "storeToXML",
-        args = {java.io.OutputStream.class, java.lang.String.class, java.lang.String.class}
-    )
     public void test_storeToXMLLjava_io_OutputStreamLjava_lang_StringLjava_lang_String()
-            throws IOException {
+            throws Exception {
+        // Test for method void
+        // java.util.Properties.storeToXML(java.io.OutputStream,
+        // java.lang.String, java.lang.String)
         Properties myProps = new Properties();
+        Properties myProps2 = new Properties();
+        Enumeration e;
+        String nextKey;
+
         myProps.setProperty("key1", "value1");
         myProps.setProperty("key2", "value2");
         myProps.setProperty("key3", "value3");
@@ -466,126 +875,153 @@
         myProps.setProperty("<a>&amp;key13&lt;</a>",
                 "&amp;&value13<b>&amp;</b>");
 
-        // store in UTF-8 encoding
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        myProps.storeToXML(out, "comment");
-        out.close();
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
 
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        Properties myProps2 = new Properties();
-        myProps2.loadFromXML(in);
-        in.close();
-
-        Enumeration e = myProps.propertyNames();
-        while (e.hasMoreElements()) {
-            String nextKey = (String) e.nextElement();
-            assertTrue("Stored property list not equal to original", myProps2
-                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
+            // store in UTF-8 encoding
+            myProps.storeToXML(out, "comment");
+            out.close();
+            ByteArrayInputStream in = new ByteArrayInputStream(out
+                    .toByteArray());
+            myProps2.loadFromXML(in);
+            in.close();
+        } catch (InvalidPropertiesFormatException ipfe) {
+            fail("InvalidPropertiesFormatException occurred reading file: "
+                    + ipfe.getMessage());
+        } catch (IOException ioe) {
+            fail("IOException occurred reading/writing file : "
+                    + ioe.getMessage());
         }
 
-        // store in ISO-8859-1 encoding
-        out = new ByteArrayOutputStream();
-        myProps.storeToXML(out, "comment", "ISO-8859-1");
-        out.close();
-
-        in = new ByteArrayInputStream(out.toByteArray());
-        myProps2 = new Properties();
-        myProps2.loadFromXML(in);
-        in.close();
-
         e = myProps.propertyNames();
         while (e.hasMoreElements()) {
-            String nextKey = (String) e.nextElement();
+            nextKey = (String) e.nextElement();
             assertTrue("Stored property list not equal to original", myProps2
                     .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
         }
 
-        out = new ByteArrayOutputStream();
-        myProps.storeToXML(out, "comment", "ISO-8859-1");
-        myProps.storeToXML(out, null, "ISO-8859-1");
-        out.close();
-        
         try {
-            myProps.storeToXML(out, "comment", null);
-            fail("NulPointerException expected");
-        } catch (NullPointerException ee) {
-            //expected
-        }
-        
-        try {
-            myProps.storeToXML(null, "comment", "ISO-8859-1");
-            fail("NulPointerException expected");
-        } catch (NullPointerException ee) {
-            //expected
-        }
-    }
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "storeToXML",
-        args = {java.io.OutputStream.class, java.lang.String.class}
-    )
-    public void test_storeToXMLLjava_io_OutputStreamLjava_lang_String()
-    throws IOException {
-        Properties myProps = new Properties();
-        myProps.put("Property A", "value 1");
-        myProps.put("Property B", "value 2");
-        myProps.put("Property C", "value 3");
-        
-        Properties myProps2 = new Properties();
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        myProps.storeToXML(out, "A Header");
-        out.close();
-        
-        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
-        myProps2.loadFromXML(in);
-        in.close();
-        
-        Enumeration e = myProps.propertyNames();
+            // store in ISO-8859-1 encoding
+            myProps.storeToXML(out, "comment", "ISO-8859-1");
+            out.close();
+            ByteArrayInputStream in = new ByteArrayInputStream(out
+                    .toByteArray());
+            myProps2 = new Properties();
+            myProps2.loadFromXML(in);
+            in.close();
+        } catch (InvalidPropertiesFormatException ipfe) {
+            fail("InvalidPropertiesFormatException occurred reading file: "
+                    + ipfe.getMessage());
+        } catch (IOException ioe) {
+            fail("IOException occurred reading/writing file : "
+                    + ioe.getMessage());
+        }
+
+        e = myProps.propertyNames();
         while (e.hasMoreElements()) {
-            String nextKey = (String) e.nextElement();
+            nextKey = (String) e.nextElement();
             assertTrue("Stored property list not equal to original", myProps2
                     .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
         }
         
         try {
-            myProps.storeToXML(null, "String");
-            fail("NullPointerException expected");
-        } catch (NullPointerException ee){
-            //expected
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            myProps.storeToXML(out, null, null);
+            fail("should throw nullPointerException");
+        } catch (NullPointerException ne) {
+            // expected
         }
     }
+ 
+    /**
+     * if loading from single line like "hello" without "\n\r" neither "=", it
+     * should be same as loading from "hello="
+     */
+    public void testLoadSingleLine() throws Exception{
+        Properties props = new Properties();
+        InputStream sr = new ByteArrayInputStream("hello".getBytes());
+        props.load(sr);
+        assertEquals(1, props.size());
+    }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "propertyNames",
-        args = {}
-    )
-    public void test_propertyNames() {
-        Properties myProps = new Properties();
-        myProps.put("Property A", "value 1");
-        myProps.put("Property B", "value 2");
-        myProps.put("Property C", "value 3");
-        
-        Enumeration e = myProps.propertyNames();
-        
-        int count = 0;
-        while (e.hasMoreElements()) {
-            count++;
-            assertTrue(myProps.containsKey(e.nextElement()));
-        }
-        
-        assertTrue(myProps.size() == count);
+    public void test_SequentialpropertyNames() {
+        Properties parent = new Properties();
+        parent.setProperty("parent.a.key", "parent.a.value");
+        parent.setProperty("parent.b.key", "parent.b.value");
+
+        Enumeration<?> names = parent.propertyNames();
+        assertEquals("parent.a.key", names.nextElement());
+        assertEquals("parent.b.key", names.nextElement());
+        assertFalse(names.hasMoreElements());
+
+        Properties current = new Properties(parent);
+        current.setProperty("current.a.key", "current.a.value");
+        current.setProperty("current.b.key", "current.b.value");
+
+        names = current.propertyNames();
+        assertEquals("parent.a.key", names.nextElement());
+        assertEquals("current.b.key", names.nextElement());
+        assertEquals("parent.b.key", names.nextElement());
+        assertEquals("current.a.key", names.nextElement());
+        assertFalse(names.hasMoreElements());
+
+        Properties child = new Properties(current);
+        child.setProperty("child.a.key", "child.a.value");
+        child.setProperty("child.b.key", "child.b.value");
+
+        names = child.propertyNames();
+        assertEquals("parent.a.key", names.nextElement());
+        assertEquals("child.b.key", names.nextElement());
+        assertEquals("current.b.key", names.nextElement());
+        assertEquals("parent.b.key", names.nextElement());
+        assertEquals("child.a.key", names.nextElement());
+        assertEquals("current.a.key", names.nextElement());
+        assertFalse(names.hasMoreElements());
+    }
+
+    public void test_SequentialstringPropertyNames() {
+        Properties parent = new Properties();
+        parent.setProperty("parent.a.key", "parent.a.value");
+        parent.setProperty("parent.b.key", "parent.b.value");
+
+        Iterator<String> nameIterator = parent.stringPropertyNames().iterator();
+        assertEquals("parent.a.key", nameIterator.next());
+        assertEquals("parent.b.key", nameIterator.next());
+        assertFalse(nameIterator.hasNext());
+
+        Properties current = new Properties(parent);
+        current.setProperty("current.a.key", "current.a.value");
+        current.setProperty("current.b.key", "current.b.value");
+
+        nameIterator = current.stringPropertyNames().iterator();
+        assertEquals("parent.a.key", nameIterator.next());
+        assertEquals("current.b.key", nameIterator.next());
+        assertEquals("parent.b.key", nameIterator.next());
+        assertEquals("current.a.key", nameIterator.next());
+        assertFalse(nameIterator.hasNext());
+
+        Properties child = new Properties(current);
+        child.setProperty("child.a.key", "child.a.value");
+        child.setProperty("child.b.key", "child.b.value");
+
+        nameIterator = child.stringPropertyNames().iterator();
+        assertEquals("parent.a.key", nameIterator.next());
+        assertEquals("child.b.key", nameIterator.next());
+        assertEquals("current.b.key", nameIterator.next());
+        assertEquals("parent.b.key", nameIterator.next());
+        assertEquals("child.a.key", nameIterator.next());
+        assertEquals("current.a.key", nameIterator.next());
+        assertFalse(nameIterator.hasNext());
     }
 
     /**
      * Sets up the fixture, for example, open a network connection. This method
      * is called before a test is executed.
      */
-    protected void setUp() throws Exception {
-        super.setUp();
+    protected void setUp() {
+
         tProps = new Properties();
         tProps.put("test.prop", "this is a test property");
         tProps.put("bogus.prop", "bogus");
@@ -595,14 +1031,17 @@
      * Tears down the fixture, for example, close a network connection. This
      * method is called after a test is executed.
      */
-    protected void tearDown() throws Exception {
-        tProps = null;
-        super.tearDown();
+    protected void tearDown() {
     }
 
+    /**
+     * Tears down the fixture, for example, close a network connection. This
+     * method is called after a test is executed.
+     */
     protected byte[] writeProperties() throws IOException {
+        PrintStream ps = null;
         ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        PrintStream ps = new PrintStream(bout);
+        ps = new PrintStream(bout);
         ps.println("#commented.entry=Bogus");
         ps.println("test.pkg=harmony.tests");
         ps.println("test.proj=Automated Tests");
@@ -610,10 +1049,29 @@
         return bout.toByteArray();
     }
 
-    protected byte[] writePropertiesXML(String encoding) throws IOException {
+    protected byte[] writePropertiesXMLUTF_8() throws IOException {
+        PrintStream ps = null;
         ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        PrintStream ps = new PrintStream(bout, true, encoding);
-        ps.println("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>");
+        ps = new PrintStream(bout, true, "UTF-8");
+        ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        ps
+                .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
+        ps.println("<properties>");
+        ps.println("<comment>comment</comment>");
+        ps.println("<entry key=\"key4\">value4</entry>");
+        ps.println("<entry key=\"key3\">value3</entry>");
+        ps.println("<entry key=\"key2\">value2</entry>");
+        ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
+        ps.println("</properties>");
+        ps.close();
+        return bout.toByteArray();
+    }
+
+    protected byte[] writePropertiesXMLISO_8859_1() throws IOException {
+        PrintStream ps = null;
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ps = new PrintStream(bout, true, "ISO-8859-1");
+        ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
         ps
                 .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
         ps.println("<properties>");
diff --git a/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java b/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
index 480c998..52a2409 100644
--- a/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
+++ b/luni/src/test/java/tests/api/java/util/ResourceBundleTest.java
@@ -188,7 +188,7 @@
         }
         
         try {
-            ResourceBundle.getBundle(name, Locale.getDefault(), null);
+            ResourceBundle.getBundle(name, Locale.getDefault(), (ClassLoader) null);
             fail("NullPointerException expected");
         } catch (NullPointerException ee) {
             //expected
diff --git a/luni/src/test/java/tests/api/java/util/ScannerTest.java b/luni/src/test/java/tests/api/java/util/ScannerTest.java
index bd13383..cd6ac09 100644
--- a/luni/src/test/java/tests/api/java/util/ScannerTest.java
+++ b/luni/src/test/java/tests/api/java/util/ScannerTest.java
@@ -1872,7 +1872,6 @@
         method = "nextBigInteger",
         args = {int.class}
     )
-    @KnownFailure("nextBigInteger method doesn't work properly if input string has Arabic-Indic digits")
     public void test_nextBigIntegerI() throws IOException {
         s = new Scanner("123 456");
         assertEquals(new BigInteger("123"), s.nextBigInteger(10));
@@ -2021,7 +2020,6 @@
         method = "nextBigInteger",
         args = {}
     )
-    @KnownFailure("nextBigInteger method doesn't work properly if input string has Arabic-Indic digits")
     public void test_nextBigInteger() throws IOException {
         s = new Scanner("123 456");
         assertEquals(new BigInteger("123"), s.nextBigInteger());
@@ -3380,7 +3378,6 @@
         method = "hasNextBigInteger",
         args = {int.class}
     )
-    @KnownFailure("hasNextBigInteger method doesn't work properly if input string has Arabic-Indic digits")    
     public void test_hasNextBigIntegerI() throws IOException {
         s = new Scanner("123 456");
         assertTrue(s.hasNextBigInteger(10));
@@ -3586,7 +3583,6 @@
         method = "hasNextBigInteger",
         args = {}
     )
-    @KnownFailure("nextBigInteger method doesn't work properly if input string has Arabic-Indic digits")
     public void test_hasNextBigInteger() throws IOException {
         s = new Scanner("123 456");
         assertTrue(s.hasNextBigInteger());
@@ -5452,7 +5448,6 @@
         method = "findWithinHorizon",
         args = {java.util.regex.Pattern.class, int.class}
     )
-    @KnownFailure("findWithinHorizon method doesn't work properly")
     public void test_findWithinHorizon_LPatternI(){
 
         // This method searches through the input up to the specified search
diff --git a/luni/src/test/java/tests/api/java/util/TimeZoneTest.java b/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
index aacf6ce..2919a75 100644
--- a/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/tests/api/java/util/TimeZoneTest.java
@@ -63,7 +63,6 @@
         method = "getDSTSavings",
         args = {}
     )
-    @KnownFailure("Might be a difference in data.")
     public void test_getDSTSavings() {
         // Test for method int java.util.TimeZone.getDSTSavings()
 
@@ -138,7 +137,6 @@
         method = "getTimeZone",
         args = {java.lang.String.class}
     )
-    @KnownFailure("Android fails the last test.")
     public void test_getTimeZoneLjava_lang_String() {
         assertEquals("Must return GMT when given an invalid TimeZone id SMT-8.",
                              "GMT", TimeZone.getTimeZone("SMT-8").getID());
@@ -375,7 +373,6 @@
         method = "hasSameRules",
         args = {java.util.TimeZone.class}
     )
-    @KnownFailure("Arizona doesn't observe DST")
     public void test_hasSameRulesLjava_util_TimeZone() {
         TimeZone tz1 = TimeZone.getTimeZone("America/Denver");
         TimeZone tz2 = TimeZone.getTimeZone("America/Phoenix");
diff --git a/luni/src/test/java/tests/luni/AllTestsIo.java b/luni/src/test/java/tests/luni/AllTestsIo.java
index d135244..010916c 100644
--- a/luni/src/test/java/tests/luni/AllTestsIo.java
+++ b/luni/src/test/java/tests/luni/AllTestsIo.java
@@ -31,7 +31,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.io");
+        TestSuite suite = new TestSuite("Tests for java.io");
 
         suite.addTest(tests.api.java.io.AllTests.suite());
 
diff --git a/luni/src/test/java/tests/luni/AllTestsLang.java b/luni/src/test/java/tests/luni/AllTestsLang.java
index 418571e..1a3b240 100644
--- a/luni/src/test/java/tests/luni/AllTestsLang.java
+++ b/luni/src/test/java/tests/luni/AllTestsLang.java
@@ -31,7 +31,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.lang");
+        TestSuite suite = new TestSuite("Tests for java.lang");
 
         suite.addTest(org.apache.harmony.luni.tests.java.lang.AllTests.suite());
 
diff --git a/luni/src/test/java/tests/luni/AllTestsNet.java b/luni/src/test/java/tests/luni/AllTestsNet.java
index c61cb5f..835cfc7 100644
--- a/luni/src/test/java/tests/luni/AllTestsNet.java
+++ b/luni/src/test/java/tests/luni/AllTestsNet.java
@@ -31,7 +31,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.net");
+        TestSuite suite = new TestSuite("Tests for java.net");
 
         suite.addTest(org.apache.harmony.luni.tests.java.net.AllTests.suite());
         
diff --git a/luni/src/test/java/tests/luni/AllTestsUtil.java b/luni/src/test/java/tests/luni/AllTestsUtil.java
index a157a95..102093e 100644
--- a/luni/src/test/java/tests/luni/AllTestsUtil.java
+++ b/luni/src/test/java/tests/luni/AllTestsUtil.java
@@ -31,7 +31,7 @@
     }
 
     public static final Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.util");
+        TestSuite suite = new TestSuite("Tests for java.util");
 
         suite.addTest(tests.api.java.util.AllTests.suite());
         suite.addTest(org.apache.harmony.luni.tests.java.util.AllTests.suite());
diff --git a/luni/src/test/resources/META-INF/services/java.util.ServiceLoaderTestInterface b/luni/src/test/resources/META-INF/services/java.util.ServiceLoaderTestInterface
new file mode 100644
index 0000000..b87e043
--- /dev/null
+++ b/luni/src/test/resources/META-INF/services/java.util.ServiceLoaderTestInterface
@@ -0,0 +1,7 @@
+# this is a comment
+# followed by a blank line
+
+java.util.ServiceLoaderTest$Impl1
+java.util.ServiceLoaderTest$Impl2 # this comment is valid
+java.util.ServiceLoaderTest$Impl2#as is this
+java.util.ServiceLoaderTest$Impl2 # and duplicates are allowed too
diff --git a/math/src/main/java/java/math/BigDecimal.java b/math/src/main/java/java/math/BigDecimal.java
index 4e4875b..364470a 100644
--- a/math/src/main/java/java/math/BigDecimal.java
+++ b/math/src/main/java/java/math/BigDecimal.java
@@ -22,8 +22,6 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 
-import org.apache.harmony.math.internal.nls.Messages;
-
 /**
  * This class represents immutable integer numbers of arbitrary length. Large
  * numbers are typically used in security applications and therefore BigIntegers
@@ -378,8 +376,7 @@
             newScale = (long)scale - Integer.parseInt(scaleString);
             scale = (int)newScale;
             if (newScale != scale) {
-                // math.02=Scale out of range.
-                throw new NumberFormatException(Messages.getString("math.02")); //$NON-NLS-1$
+                throw new NumberFormatException("Scale out of range");
             }
         }
         // Parsing the unscaled value
@@ -523,8 +520,7 @@
      */
     public BigDecimal(double val) {
         if (Double.isInfinite(val) || Double.isNaN(val)) {
-            // math.03=Infinity or NaN
-            throw new NumberFormatException(Messages.getString("math.03")); //$NON-NLS-1$
+            throw new NumberFormatException("Infinity or NaN");
         }
         long bits = Double.doubleToLongBits(val); // IEEE-754
         long mantisa;
@@ -802,8 +798,7 @@
      */
     public static BigDecimal valueOf(double val) {
         if (Double.isInfinite(val) || Double.isNaN(val)) {
-            // math.03=Infinity or NaN
-            throw new NumberFormatException(Messages.getString("math.03")); //$NON-NLS-1$
+            throw new NumberFormatException("Infinity or NaN");
         }
         return new BigDecimal(Double.toString(val));
     }
@@ -1113,8 +1108,7 @@
             throw new NullPointerException();
         }
         if (divisor.isZero()) {
-            // math.04=Division by zero
-            throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
+            throw new ArithmeticException("Division by zero");
         }
 
         long diffScale = ((long)this.scale - divisor.scale) - scale;
@@ -1289,8 +1283,7 @@
         int lastPow = FIVE_POW.length - 1;
 
         if (divisor.isZero()) {
-            // math.04=Division by zero
-            throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
+            throw new ArithmeticException("Division by zero");
         }
         if (p.signum() == 0) {
             return zeroScaledBy(diffScale);
@@ -1320,8 +1313,7 @@
         } while (true);
         // If  abs(q) != 1  then the quotient is periodic
         if (!q.abs().equals(BigInteger.ONE)) {
-            // math.05=Non-terminating decimal expansion; no exact representable decimal result.
-            throw new ArithmeticException(Messages.getString("math.05")); //$NON-NLS-1$
+            throw new ArithmeticException("Non-terminating decimal expansion; no exact representable decimal result");
         }
         // The sign of the is fixed and the quotient will be saved in 'p'
         if (q.signum() < 0) {
@@ -1434,8 +1426,7 @@
         int lastPow = TEN_POW.length - 1;
 
         if (divisor.isZero()) {
-            // math.04=Division by zero
-            throw new ArithmeticException(Messages.getString("math.04")); //$NON-NLS-1$
+            throw new ArithmeticException("Division by zero");
         }
         if ((divisor.aproxPrecision() + newScale > this.aproxPrecision() + 1L)
         || (this.isZero())) {
@@ -1544,9 +1535,7 @@
                     compRemDiv = Math.abs(quotAndRem[1].signum());
                 }
                 if (compRemDiv > 0) {
-                    // The quotient won't fit in 'mc.precision()' digits
-                    // math.06=Division impossible
-                    throw new ArithmeticException(Messages.getString("math.06")); //$NON-NLS-1$
+                    throw new ArithmeticException("Division impossible");
                 }
             }
         }
@@ -1579,8 +1568,7 @@
         }
         // To check if the result fit in 'mc.precision()' digits
         if (resultPrecision > mcPrecision) {
-            // math.06=Division impossible
-            throw new ArithmeticException(Messages.getString("math.06")); //$NON-NLS-1$
+            throw new ArithmeticException("Division impossible");
         }
         integralValue.scale = toIntScale(newScale);
         integralValue.setUnscaledValue(strippedBI);
@@ -1706,14 +1694,12 @@
             return ONE;
         }
         if ((n < 0) || (n > 999999999)) {
-            // math.07=Invalid Operation
-            throw new ArithmeticException(Messages.getString("math.07")); //$NON-NLS-1$
+            throw new ArithmeticException("Invalid operation");
         }
         long newScale = scale * (long)n;
         // Let be: this = [u,s]   so:  this^n = [u^n, s*n]
-        return ((isZero())
-        ? zeroScaledBy(newScale)
-        : new BigDecimal(getUnscaledValue().pow(n), toIntScale(newScale)));
+        return isZero() ? zeroScaledBy(newScale)
+                : new BigDecimal(getUnscaledValue().pow(n), toIntScale(newScale));
     }
 
     /**
@@ -1746,8 +1732,7 @@
         }
         if ((m > 999999999) || ((mcPrecision == 0) && (n < 0))
                 || ((mcPrecision > 0) && (elength > mcPrecision))) {
-            // math.07=Invalid Operation
-            throw new ArithmeticException(Messages.getString("math.07")); //$NON-NLS-1$
+            throw new ArithmeticException("Invalid operation");
         }
         if (mcPrecision > 0) {
             newPrecision = new MathContext( mcPrecision + elength + 1,
@@ -2336,7 +2321,7 @@
             if (exponent >= 0) {
                 result.insert(end - scale, '.');
             } else {
-                result.insert(begin - 1, "0."); //$NON-NLS-1$
+                result.insert(begin - 1, "0.");
                 result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
             }
         } else {
@@ -2380,7 +2365,7 @@
             if (exponent >= 0) {
                 result.insert(end - scale, '.');
             } else {
-                result.insert(begin - 1, "0."); //$NON-NLS-1$
+                result.insert(begin - 1, "0.");
                 result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
             }
         } else {
@@ -2452,7 +2437,7 @@
         if (scale > 0) {
             delta -= (intStr.length() - begin);
             if (delta >= 0) {
-                result.append("0."); //$NON-NLS-1$
+                result.append("0.");
                 // To append zeros after the decimal point
                 for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) {
                     result.append(CH_ZEROS);
@@ -2510,14 +2495,12 @@
             BigInteger[] integerAndFraction;
             // An optimization before do a heavy division
             if ((scale > aproxPrecision()) || (scale > getUnscaledValue().getLowestSetBit())) {
-                // math.08=Rounding necessary
-                throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
+                throw new ArithmeticException("Rounding necessary");
             }
             integerAndFraction = getUnscaledValue().divideAndRemainder(Multiplication.powerOf10(scale));
             if (integerAndFraction[1].signum() != 0) {
                 // It exists a non-zero fractional part
-                // math.08=Rounding necessary
-                throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
+                throw new ArithmeticException("Rounding necessary");
             }
             return integerAndFraction[0];
         }
@@ -2908,8 +2891,7 @@
         switch (roundingMode) {
             case UNNECESSARY:
                 if (fraction != 0) {
-                    // math.08=Rounding necessary
-                    throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
+                    throw new ArithmeticException("Rounding necessary");
                 }
                 break;
             case UP:
@@ -2964,8 +2946,7 @@
             // It fits in the primitive type
             return bigInteger.longValue();
         }
-        // math.08=Rounding necessary
-        throw new ArithmeticException(Messages.getString("math.08")); //$NON-NLS-1$
+        throw new ArithmeticException("Rounding necessary");
     }
 
     /**
@@ -2998,11 +2979,9 @@
      */
     private static int toIntScale(long longScale) {
         if (longScale < Integer.MIN_VALUE) {
-            // math.09=Overflow
-            throw new ArithmeticException(Messages.getString("math.09")); //$NON-NLS-1$
+            throw new ArithmeticException("Overflow");
         } else if (longScale > Integer.MAX_VALUE) {
-            // math.0A=Underflow
-            throw new ArithmeticException(Messages.getString("math.0A")); //$NON-NLS-1$
+            throw new ArithmeticException("Underflow");
         } else {
             return (int)longScale;
         }
diff --git a/math/src/main/java/java/math/BigInt.java b/math/src/main/java/java/math/BigInt.java
index 1eae2e0..d7e9e73 100644
--- a/math/src/main/java/java/math/BigInt.java
+++ b/math/src/main/java/java/math/BigInt.java
@@ -16,10 +16,8 @@
 
 package java.math;
 
-import org.apache.harmony.math.internal.nls.Messages;
-import org.openssl.NativeBN;
-
 import java.util.Random;
+import org.openssl.NativeBN;
 
 /*
  * In contrast to BigIntegers this class doesn't fake two's complement representation.
@@ -85,12 +83,10 @@
         while ((e = NativeBN.ERR_get_error()) != 0) {
             reason = e & 255;
             if (reason == 103) {
-                // math.17=BigInteger divide by zero
-                throw new ArithmeticException(Messages.getString("math.17")); //$NON-NLS-1$
+                throw new ArithmeticException("BigInteger division by zero");
             }
             if (reason == 108) {
-                // math.19=BigInteger not invertible.
-                throw new ArithmeticException(Messages.getString("math.19")); //$NON-NLS-1$
+                throw new ArithmeticException("BigInteger not invertible");
             }
             if (reason == 65) {
                 throw new OutOfMemoryError();
@@ -155,34 +151,85 @@
         Check(NativeBN.putULongInt(this.bignum, val, neg));
     }
 
-    public void putDecString(String str) {
-        if (str == null) throw new NullPointerException();
-        if (str.length() == 0) {
-            // math.12=Zero length BigInteger
-            throw new NumberFormatException(Messages.getString("math.12")); //$NON-NLS-1$
-        }
+    public void putDecString(String original) {
+        String s = checkString(original, 10);
         this.makeValid();
-        int usedLen = NativeBN.BN_dec2bn(this.bignum, str);
+        int usedLen = NativeBN.BN_dec2bn(this.bignum, s);
         Check((usedLen > 0));
-        if (usedLen < str.length()) {
-            throw new NumberFormatException(str);
+        if (usedLen < s.length()) {
+            throw new NumberFormatException(original);
         }
     }
 
-    public void putHexString(String str) {
-        if (str == null) throw new NullPointerException();
-        if (str.length() == 0) {
-            // math.12=Zero length BigInteger
-            throw new NumberFormatException(Messages.getString("math.12")); //$NON-NLS-1$
-        }
+    public void putHexString(String original) {
+        String s = checkString(original, 16);
         this.makeValid();
-        int usedLen = NativeBN.BN_hex2bn(this.bignum, str);
+        int usedLen = NativeBN.BN_hex2bn(this.bignum, s);
         Check((usedLen > 0));
-        if (usedLen < str.length()) {
-            throw new NumberFormatException(str);
+        if (usedLen < s.length()) {
+            throw new NumberFormatException(original);
         }
     }
 
+    /**
+     * Returns a string suitable for passing to OpenSSL.
+     * Throws if 's' doesn't match Java's rules for valid BigInteger strings.
+     * BN_dec2bn and BN_hex2bn do very little checking, so we need to manually
+     * ensure we comply with Java's rules.
+     * http://code.google.com/p/android/issues/detail?id=7036
+     */
+    public String checkString(String s, int base) {
+        if (s == null) {
+            throw new NullPointerException();
+        }
+        // A valid big integer consists of an optional '-' or '+' followed by
+        // one or more digit characters appropriate to the given base,
+        // and no other characters.
+        int charCount = s.length();
+        int i = 0;
+        if (charCount > 0) {
+            char ch = s.charAt(0);
+            if (ch == '+') {
+                // Java supports leading +, but OpenSSL doesn't, so we need to strip it.
+                s = s.substring(1);
+                --charCount;
+            } else if (ch == '-') {
+                ++i;
+            }
+        }
+        if (charCount - i == 0) {
+            throw new NumberFormatException(s);
+        }
+        boolean nonAscii = false;
+        for (; i < charCount; ++i) {
+            char ch = s.charAt(i);
+            if (Character.digit(ch, base) == -1) {
+                throw new NumberFormatException(s);
+            }
+            if (ch > 128) {
+                nonAscii = true;
+            }
+        }
+        return nonAscii ? toAscii(s, base) : s;
+    }
+
+    // Java supports non-ASCII decimal digits, but OpenSSL doesn't.
+    // We need to translate the decimal digits but leave any other characters alone.
+    // This method assumes it's being called on a string that has already been validated.
+    private static String toAscii(String s, int base) {
+        int length = s.length();
+        StringBuilder result = new StringBuilder(length);
+        for (int i = 0; i < length; ++i) {
+            char ch = s.charAt(i);
+            int value = Character.digit(ch, base);
+            if (value >= 0 && value <= 9) {
+                ch = (char) ('0' + value);
+            }
+            result.append(ch);
+        }
+        return result.toString();
+    }
+
     public void putBigEndian(byte[] a, boolean neg) {
         this.makeValid();
         Check(NativeBN.BN_bin2bn(a, a.length, neg, this.bignum));
@@ -254,12 +301,12 @@
     // n > 0: shift left (multiply)
     public static BigInt shift(BigInt a, int n) {
         BigInt r = newBigInt();
-        Check(NativeBN.BN_lshift(r.bignum, a.bignum, n));
+        Check(NativeBN.BN_shift(r.bignum, a.bignum, n));
         return r;
     }
 
     public void shift(int n) {
-        Check(NativeBN.BN_lshift(this.bignum, this.bignum, n));
+        Check(NativeBN.BN_shift(this.bignum, this.bignum, n));
     }
 
     public void addPositiveInt(int w) {
diff --git a/math/src/main/java/java/math/BigInteger.java b/math/src/main/java/java/math/BigInteger.java
index c463b48..adef534 100644
--- a/math/src/main/java/java/math/BigInteger.java
+++ b/math/src/main/java/java/math/BigInteger.java
@@ -29,8 +29,6 @@
 import java.util.Random;
 import java.io.Serializable;
 
-import org.apache.harmony.math.internal.nls.Messages;
-
 /**
  * This class represents immutable integer numbers of arbitrary length. Large
  * numbers are typically used in security applications and therefore BigIntegers
@@ -220,8 +218,7 @@
      */
     public BigInteger(int numBits, Random rnd) {
         if (numBits < 0) {
-            // math.1B=numBits must be non-negative
-            throw new IllegalArgumentException(Messages.getString("math.1B")); //$NON-NLS-1$
+            throw new IllegalArgumentException("numBits must be non-negative");
         }
         if (numBits == 0) {
             sign = 0;
@@ -265,8 +262,7 @@
      */
     public BigInteger(int bitLength, int certainty, Random rnd) {
         if (bitLength < 2) {
-            // math.1C=bitLength < 2
-            throw new ArithmeticException(Messages.getString("math.1C")); //$NON-NLS-1$
+            throw new ArithmeticException("bitLength < 2");
         }
         bigInt = BigInt.generatePrimeDefault(bitLength, rnd, null);
         bigIntIsValid = true;
@@ -275,8 +271,9 @@
 
     /**
      * Constructs a new {@code BigInteger} instance from the string
-     * representation. The string representation consists of an optional minus
+     * representation. The string representation consists of an optional plus or minus
      * sign followed by a non-empty sequence of decimal digits.
+     * Digits are interpreted as if by {@code Character.digit(char, 10)}.
      * 
      * @param val
      *            string representation of the new {@code BigInteger}.
@@ -295,10 +292,9 @@
 
     /**
      * Constructs a new {@code BigInteger} instance from the string
-     * representation. The string representation consists of an optional minus
+     * representation. The string representation consists of an optional plus or minus
      * sign followed by a non-empty sequence of digits in the specified radix.
-     * For the conversion the method {@code Character.digit(char, radix)} is
-     * used.
+     * Digits are interpreted as if by {@code Character.digit(char, radix)}.
      * 
      * @param val
      *            string representation of the new {@code BigInteger}.
@@ -327,12 +323,10 @@
             // !oldReprIsValid
         } else {
             if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) {
-                // math.11=Radix out of range
-                throw new NumberFormatException(Messages.getString("math.11")); //$NON-NLS-1$
+                throw new NumberFormatException("Radix out of range");
             }
             if (val.length() == 0) {
-                // math.12=Zero length BigInteger
-                throw new NumberFormatException(Messages.getString("math.12")); //$NON-NLS-1$
+                throw new NumberFormatException("Zero-length BigInteger");
             }
             BigInteger.setFromString(this, val, radix);
             // oldReprIsValid == true;
@@ -361,15 +355,13 @@
         if (magnitude == null) {
             throw new NullPointerException();
         }
-        if ((signum < -1) || (signum > 1)) {
-            // math.13=Invalid signum value
-            throw new NumberFormatException(Messages.getString("math.13")); //$NON-NLS-1$
+        if (signum < -1 || signum > 1) {
+            throw new NumberFormatException("Invalid signum value");
         }
         if (signum == 0) {
             for (byte element : magnitude) {
                 if (element != 0) {
-                    // math.14=signum-magnitude mismatch
-                    throw new NumberFormatException(Messages.getString("math.14")); //$NON-NLS-1$
+                    throw new NumberFormatException("signum-magnitude mismatch");
                 }
             }
         }
@@ -393,8 +385,7 @@
      */
     public BigInteger(byte[] val) {
         if (val.length == 0) {
-            // math.12=Zero length BigInteger
-            throw new NumberFormatException(Messages.getString("math.12")); //$NON-NLS-1$
+            throw new NumberFormatException("Zero-length BigInteger");
         }
         bigInt = new BigInt();
         bigInt.putBigEndianTwosComplement(val);
@@ -600,8 +591,7 @@
      */
     public boolean testBit(int n) {
         if (n < 0) {
-            // math.15=Negative bit address
-            throw new ArithmeticException(Messages.getString("math.15")); //$NON-NLS-1$
+            throw new ArithmeticException("n < 0");
         }
         int sign = signum();
         if ((sign > 0) && bigIntIsValid && !oldReprIsValid) {
@@ -700,8 +690,7 @@
     public BigInteger flipBit(int n) {
         establishOldRepresentation("flipBit");
         if (n < 0) {
-            // math.15=Negative bit address
-            throw new ArithmeticException(Messages.getString("math.15")); //$NON-NLS-1$
+            throw new ArithmeticException("n < 0");
         }
         return BitLevel.flipBit(this, n);
     }
@@ -1062,8 +1051,7 @@
      */
     public BigInteger pow(int exp) {
         if (exp < 0) {
-            // math.16=Negative exponent
-            throw new ArithmeticException(Messages.getString("math.16")); //$NON-NLS-1$
+            throw new ArithmeticException("exp < 0");
         }
         validate1("pow", this);
         return new BigInteger(BigInt.exp(bigInt, exp, null));
@@ -1151,8 +1139,7 @@
      */
     public BigInteger modInverse(BigInteger m) {
         if (m.signum() <= 0) {
-            // math.18=BigInteger: modulus not positive
-            throw new ArithmeticException(Messages.getString("math.18")); //$NON-NLS-1$
+            throw new ArithmeticException("modulus not positive");
         }
         validate2("modInverse", this, m);
         return new BigInteger(BigInt.modInverse(bigInt, m.bigInt, null));
@@ -1179,8 +1166,7 @@
      */
     public BigInteger modPow(BigInteger exponent, BigInteger m) {
         if (m.signum() <= 0) {
-            // math.18=BigInteger: modulus not positive
-            throw new ArithmeticException(Messages.getString("math.18")); //$NON-NLS-1$
+            throw new ArithmeticException("modulus not positive");
         }
         BigInteger base;
         if (exponent.signum() < 0) {
@@ -1210,8 +1196,7 @@
      */
     public BigInteger mod(BigInteger m) {
         if (m.signum() <= 0) {
-            // math.18=BigInteger: modulus not positive
-            throw new ArithmeticException(Messages.getString("math.18")); //$NON-NLS-1$
+            throw new ArithmeticException("modulus not positive");
         }
         validate2("mod", this, m);
         return new BigInteger(BigInt.modulus(bigInt, m.bigInt, null));
@@ -1230,6 +1215,9 @@
      *         otherwise.
      */
     public boolean isProbablePrime(int certainty) {
+        if (certainty <= 0) {
+            return true;
+        }
         validate1("isProbablePrime", this);
         return bigInt.isPrime(certainty, null, null);
     }
@@ -1239,14 +1227,13 @@
      * a {@code BigInteger} instance. The probability that the returned {@code
      * BigInteger} is prime is beyond (1-1/2^80).
      * 
-     * @return smallest integer > {@code this} which is robably prime.
+     * @return smallest integer > {@code this} which is probably prime.
      * @throws ArithmeticException
      *             if {@code this < 0}.
      */
     public BigInteger nextProbablePrime() {
         if (sign < 0) {
-            // math.1A=start < 0: {0}
-            throw new ArithmeticException(Messages.getString("math.1A", this)); //$NON-NLS-1$
+            throw new ArithmeticException("sign < 0");
         }
         return Primality.nextProbablePrime(this);
     }
diff --git a/math/src/main/java/java/math/Division.java b/math/src/main/java/java/math/Division.java
index ce2519d..e93da7e 100644
--- a/math/src/main/java/java/math/Division.java
+++ b/math/src/main/java/java/math/Division.java
@@ -17,10 +17,6 @@
 
 package java.math;
 
-// BEGIN android-removed
-// import org.apache.harmony.math.internal.nls.Messages;
-// END android-removed
-
 /**
  * Static library that provides all operations related with division and modular
  * arithmetic to {@link BigInteger}. Some methods are provided in both mutable
diff --git a/math/src/main/java/java/math/MathContext.java b/math/src/main/java/java/math/MathContext.java
index cf1d4eb..ba33a88 100644
--- a/math/src/main/java/java/math/MathContext.java
+++ b/math/src/main/java/java/math/MathContext.java
@@ -22,8 +22,6 @@
 import java.io.Serializable;
 import java.io.StreamCorruptedException;
 
-import org.apache.harmony.math.internal.nls.Messages;
-
 /**
  * Immutable objects describing settings such as rounding mode and digit
  * precision for the numerical operations provided by class {@link BigDecimal}.
@@ -130,12 +128,10 @@
      */
     public MathContext(int precision, RoundingMode roundingMode) {
         if (precision < 0) {
-            // math.0C=Digits < 0
-            throw new IllegalArgumentException(Messages.getString("math.0C")); //$NON-NLS-1$
+            throw new IllegalArgumentException("precision < 0");
         }
         if (roundingMode == null) {
-            // math.0D=null RoundingMode
-            throw new NullPointerException(Messages.getString("math.0D")); //$NON-NLS-1$
+            throw new NullPointerException("roundingMode == null");
         }
         this.precision = precision;
         this.roundingMode = roundingMode;
@@ -162,8 +158,7 @@
         int digit; // It will contain the digit parsed
 
         if ((charVal.length < 27) || (charVal.length > 45)) {
-            // math.0E=bad string format
-            throw new IllegalArgumentException(Messages.getString("math.0E")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Bad string format");
         }
         // Parsing "precision=" String
         for (i = 0; (i < chPrecision.length) && (charVal[i] == chPrecision[i]); i++) {
@@ -171,14 +166,12 @@
         }
 
         if (i < chPrecision.length) {
-            // math.0E=bad string format
-            throw new IllegalArgumentException(Messages.getString("math.0E")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Bad string format");
         }
         // Parsing the value for "precision="...
         digit = Character.digit(charVal[i], 10);
         if (digit == -1) {
-            // math.0E=bad string format
-            throw new IllegalArgumentException(Messages.getString("math.0E")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Bad string format");
         }
         // BEGIN android-changed
         this.precision = digit;
@@ -194,14 +187,12 @@
                     break;
                 }
                 // It isn't  a valid digit, and isn't a white space
-                // math.0E=bad string format
-                throw new IllegalArgumentException(Messages.getString("math.0E")); //$NON-NLS-1$
+                throw new IllegalArgumentException("Bad string format");
             }
             // Accumulating the value parsed
             this.precision = this.precision * 10 + digit;
             if (this.precision < 0) {
-                // math.0E=bad string format
-                throw new IllegalArgumentException(Messages.getString("math.0E")); //$NON-NLS-1$
+                throw new IllegalArgumentException("Bad string format");
             }
             i++;
         } while (true);
@@ -212,8 +203,7 @@
         }
 
         if (j < chRoundingMode.length) {
-            // math.0E=bad string format
-            throw new IllegalArgumentException(Messages.getString("math.0E")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Bad string format");
         }
         // Parsing the value for "roundingMode"...
         this.roundingMode = RoundingMode.valueOf(String.valueOf(charVal, i,
@@ -314,16 +304,13 @@
      * @throws StreamCorruptedException
      *             if {@code roundingMode == null}
      */
-    private void readObject(ObjectInputStream s) throws IOException,
-            ClassNotFoundException {
+    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
         s.defaultReadObject();
         if (precision < 0) {
-            // math.0F=bad precision value
-            throw new StreamCorruptedException(Messages.getString("math.0F")); //$NON-NLS-1$
+            throw new StreamCorruptedException("precision < 0");
         }
         if (roundingMode == null) {
-            // math.10=null roundingMode
-            throw new StreamCorruptedException(Messages.getString("math.10")); //$NON-NLS-1$
+            throw new StreamCorruptedException("roundingMode == null");
         }
     }
 
diff --git a/math/src/main/java/java/math/Multiplication.java b/math/src/main/java/java/math/Multiplication.java
index 05c4605..25fd31c 100644
--- a/math/src/main/java/java/math/Multiplication.java
+++ b/math/src/main/java/java/math/Multiplication.java
@@ -17,8 +17,6 @@
 
 package java.math;
 
-import org.apache.harmony.math.internal.nls.Messages;
-
 /**
  * Static library that provides all multiplication of {@link BigInteger} methods.
  */
@@ -142,8 +140,7 @@
         long byteArraySize = 1 + (long)(exp / 2.4082399653118496);
 
         if (byteArraySize > Runtime.getRuntime().freeMemory()) {
-            // math.01=power of ten too big
-            throw new OutOfMemoryError(Messages.getString("math.01")); //$NON-NLS-1$
+            throw new OutOfMemoryError();
         }
         if (exp <= Integer.MAX_VALUE) {
             // To calculate:    5^exp * 2^exp
diff --git a/math/src/main/java/java/math/RoundingMode.java b/math/src/main/java/java/math/RoundingMode.java
index b51564f..f4c181e 100644
--- a/math/src/main/java/java/math/RoundingMode.java
+++ b/math/src/main/java/java/math/RoundingMode.java
@@ -17,8 +17,6 @@
 
 package java.math;
 
-import org.apache.harmony.math.internal.nls.Messages;
-
 /**
  * Specifies the rounding behavior for operations whose results cannot be
  * represented exactly.
@@ -118,8 +116,7 @@
             case BigDecimal.ROUND_UP:
                 return UP;
             default:
-                // math.00=Invalid rounding mode
-                throw new IllegalArgumentException(Messages.getString("math.00")); //$NON-NLS-1$
+                throw new IllegalArgumentException("Invalid rounding mode");
         }
     }
 }
diff --git a/math/src/main/java/java/math/package.html b/math/src/main/java/java/math/package.html
index f6450d0..4c9ba9f 100644
--- a/math/src/main/java/java/math/package.html
+++ b/math/src/main/java/java/math/package.html
@@ -8,6 +8,5 @@
     The user has full control over the rounding behavior (comparable with
     the IEEE754R rounding modes).
     <p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/math/src/main/java/org/apache/harmony/math/internal/nls/Messages.java b/math/src/main/java/org/apache/harmony/math/internal/nls/Messages.java
deleted file mode 100644
index 4b0075a..0000000
--- a/math/src/main/java/org/apache/harmony/math/internal/nls/Messages.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.math.internal.nls;
-
-// BEGIN android-added
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-added
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.math.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.math.internal.nls.messages";
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/math/src/main/java/org/apache/harmony/math/internal/nls/messages.properties b/math/src/main/java/org/apache/harmony/math/internal/nls/messages.properties
deleted file mode 100644
index 0a40a43..0000000
--- a/math/src/main/java/org/apache/harmony/math/internal/nls/messages.properties
+++ /dev/null
@@ -1,45 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# messages for EN locale
-math.00=Invalid rounding mode
-math.01=power of ten too big
-math.02=Scale out of range.
-math.03=Infinite or NaN
-math.04=Division by zero
-math.05=Non-terminating decimal expansion; no exact representable decimal result.
-math.06=Division impossible
-math.07=Invalid Operation
-math.08=Rounding necessary
-math.09=Overflow
-math.0A=Underflow
-math.0B=null unscaled value
-math.0C=Digits < 0
-math.0D=null RoundingMode
-math.0E=bad string format
-math.0F=bad precision value
-math.10=null roundingMode
-math.1B=numBits must be non-negative
-math.1C=bitLength < 2
-math.11=Radix out of range
-math.12=Zero length BigInteger
-math.13=Invalid signum value
-math.14=signum-magnitude mismatch
-math.15=Negative bit address
-math.16=Negative exponent
-math.17=BigInteger divide by zero
-math.18=BigInteger: modulus not positive
-math.19=BigInteger not invertible.
-math.1A=start < 0: {0}
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/AllTests.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/AllTests.java
index 318e4b6..21f2ec5 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/AllTests.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.tests.java.math;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.tests.java.math;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(BigDecimalArithmeticTest.class);
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java
index 3119131..bdb4cf9 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalArithmeticTest.java
@@ -17,18 +17,13 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.MathContext;
 import java.math.RoundingMode;
-@TestTargetClass(BigDecimal.class)
+
 /**
  * Class:  java.math.BigDecimal
  * Methods: add, subtract, multiply, divide 
@@ -38,12 +33,6 @@
     /**
      * Add two numbers of equal positive scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void testAddEqualScalePosPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 10;
@@ -61,12 +50,6 @@
     /**
      * Add two numbers of equal positive scales using MathContext
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Together with all other methods including a MathContext these tests form m a complete test set.",
-        method = "add",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testAddMathContextEqualScalePosPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 10;
@@ -85,12 +68,6 @@
     /**
      * Add two numbers of equal negative scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void testAddEqualScaleNegNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -10;
@@ -108,12 +85,6 @@
     /**
      * Add two numbers of equal negative scales using MathContext
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Together with all other methods including a MathContext these tests form a complete test set.",
-        method = "add",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testAddMathContextEqualScaleNegNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -10;
@@ -132,12 +103,6 @@
     /**
      * Add two numbers of different scales; the first is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void testAddDiffScalePosNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -155,12 +120,6 @@
     /**
      * Add two numbers of different scales using MathContext; the first is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Together with all other methods including a MathContext these tests form a complete test set.",
-        method = "add",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testAddMathContextDiffScalePosNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -179,12 +138,6 @@
     /**
      * Add two numbers of different scales; the first is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void testAddDiffScaleNegPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -15;
@@ -202,12 +155,6 @@
     /**
      * Add two zeroes of different scales; the first is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void testAddDiffScaleZeroZero() {
         String a = "0";
         int aScale = -15;
@@ -225,12 +172,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "add",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testAddMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -259,12 +200,6 @@
     /**
      * Subtract two numbers of equal positive scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class}
-    )
     public void testSubtractEqualScalePosPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 10;
@@ -282,12 +217,6 @@
     /**
      * Subtract two numbers of equal positive scales using MathContext
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testSubtractMathContextEqualScalePosPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 10;
@@ -306,12 +235,6 @@
     /**
      * Subtract two numbers of equal negative scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class}
-    )
     public void testSubtractEqualScaleNegNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -10;
@@ -329,12 +252,6 @@
     /**
      * Subtract two numbers of different scales; the first is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class}
-    )
     public void testSubtractDiffScalePosNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -353,12 +270,6 @@
      * Subtract two numbers of different scales using MathContext;
      *  the first is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testSubtractMathContextDiffScalePosNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -377,12 +288,6 @@
     /**
      * Subtract two numbers of different scales; the first is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class}
-    )
     public void testSubtractDiffScaleNegPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -15;
@@ -401,12 +306,6 @@
      * Subtract two numbers of different scales using MathContext;
      *  the first is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "subtract",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testSubtractMathContextDiffScaleNegPos() {
         String a = "986798656676789766678767876078779810457634781384756794987";
         int aScale = -15;
@@ -425,12 +324,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "subtract",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testSubtractMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -457,12 +350,6 @@
     /**
      * Multiply two numbers of positive scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMultiplyScalePosPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -480,12 +367,6 @@
     /**
      * Multiply two numbers of positive scales using MathContext
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testMultiplyMathContextScalePosPos() {
         String a = "97665696756578755423325476545428779810457634781384756794987";
         int aScale = -25;
@@ -504,12 +385,6 @@
     /**
      * Multiply two numbers of negative scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMultiplyEqualScaleNegNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -15;
@@ -527,12 +402,6 @@
     /**
      * Multiply two numbers of different scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMultiplyDiffScalePosNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 10;
@@ -550,12 +419,6 @@
     /**
      * Multiply two numbers of different scales using MathContext
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testMultiplyMathContextDiffScalePosNeg() {
         String a = "987667796597975765768768767866756808779810457634781384756794987";
         int aScale = 100;
@@ -574,12 +437,6 @@
     /**
      * Multiply two numbers of different scales
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMultiplyDiffScaleNegPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -15;
@@ -597,12 +454,6 @@
     /**
      * Multiply two numbers of different scales using MathContext
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "multiply",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testMultiplyMathContextDiffScaleNegPos() {
         String a = "488757458676796558668876576576579097029810457634781384756794987";
         int aScale = -63;
@@ -621,12 +472,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "multiply",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testMultiplyMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -647,12 +492,6 @@
     /**
      * pow(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPow() {
         String a = "123121247898748298842980";
         int aScale = 10;
@@ -671,12 +510,6 @@
     /**
      * pow(0)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPow0() {
         String a = "123121247898748298842980";
         int aScale = 10;
@@ -692,12 +525,6 @@
     /**
      * ZERO.pow(0)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testZeroPow0() {
         String c = "1";
         int cScale = 0;
@@ -709,12 +536,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowNonTrivial() {
         BigDecimal a, b, res;
 
@@ -736,12 +557,6 @@
     /**
      * pow(int, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "pow",
-        args = {int.class, java.math.MathContext.class}
-    )
     public void testPowMathContext() {
         String a = "123121247898748298842980";
         int aScale = 10;
@@ -758,12 +573,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "pow",
-        args = {int.class, java.math.MathContext.class}
-    )
     public void testPowMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -832,12 +641,6 @@
     /**
      * Divide by zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "ArithmeticException checked.",
-        method = "divide",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideByZero() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -854,12 +657,6 @@
     /**
      * Divide with ROUND_UNNECESSARY
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException only checked.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class}
-    )
     public void testDivideExceptionRM() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -878,12 +675,6 @@
     /**
      * Divide with invalid rounding mode
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "IllegalArgumentException only checked.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class}
-    )
     public void testDivideExceptionInvalidRM() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -902,12 +693,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class}
-    )
     public void testDivideINonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -938,12 +723,6 @@
     /**
      * Divide: local variable exponent is less than zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideExpLessZero() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 15;
@@ -961,12 +740,6 @@
     /**
      * Divide: local variable exponent is equal to zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed. Should be added checking for ArithmeticException to complete functional testing.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideExpEqualsZero() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -15;
@@ -984,12 +757,6 @@
     /**
      * Divide: local variable exponent is greater than zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideExpGreaterZero() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -15;
@@ -1007,12 +774,6 @@
     /**
      * Divide: remainder is zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRemainderIsZero() {
         String a = "8311389578904553209874735431110";
         int aScale = -15;
@@ -1030,12 +791,6 @@
     /**
      * Divide: rounding mode is ROUND_UP, result is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundUpNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1053,12 +808,6 @@
     /**
      * Divide: rounding mode is ROUND_UP, result is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundUpPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1076,12 +825,6 @@
     /**
      * Divide: rounding mode is ROUND_DOWN, result is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundDownNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1099,12 +842,6 @@
     /**
      * Divide: rounding mode is ROUND_DOWN, result is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundDownPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1122,12 +859,6 @@
     /**
      * Divide: rounding mode is ROUND_FLOOR, result is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundFloorPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1145,12 +876,6 @@
     /**
      * Divide: rounding mode is ROUND_FLOOR, result is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundFloorNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1168,12 +893,6 @@
     /**
      * Divide: rounding mode is ROUND_CEILING, result is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundCeilingPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1191,12 +910,6 @@
     /**
      * Divide: rounding mode is ROUND_CEILING, result is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundCeilingNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1214,12 +927,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_UP, result is positive; distance = -1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfUpPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1237,12 +944,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_UP, result is negative; distance = -1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
  public void testDivideRoundHalfUpNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1260,12 +961,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_UP, result is positive; distance = 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfUpPos1() {
         String a = "92948782094488478231212478987482988798104576347813847567949855464535634534563456";
         int aScale = -24;
@@ -1283,12 +978,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_UP, result is negative; distance = 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfUpNeg1() {
         String a = "-92948782094488478231212478987482988798104576347813847567949855464535634534563456";
         int aScale = -24;
@@ -1306,12 +995,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_UP, result is negative; equidistant
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfUpNeg2() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1329,12 +1012,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_DOWN, result is positive; distance = -1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfDownPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1352,12 +1029,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_DOWN, result is negative; distance = -1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfDownNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1375,12 +1046,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_DOWN, result is positive; distance = 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfDownPos1() {
         String a = "92948782094488478231212478987482988798104576347813847567949855464535634534563456";
         int aScale = -24;
@@ -1398,12 +1063,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_DOWN, result is negative; distance = 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfDownNeg1() {
         String a = "-92948782094488478231212478987482988798104576347813847567949855464535634534563456";
         int aScale = -24;
@@ -1421,12 +1080,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_UP, result is negative; equidistant
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfDownNeg2() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1444,12 +1097,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_EVEN, result is positive; distance = -1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfEvenPos() {
         String a = "92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1467,12 +1114,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_EVEN, result is negative; distance = -1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfEvenNeg() {
         String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
         int aScale = -24;
@@ -1490,12 +1131,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_EVEN, result is positive; distance = 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfEvenPos1() {
         String a = "92948782094488478231212478987482988798104576347813847567949855464535634534563456";
         int aScale = -24;
@@ -1513,12 +1148,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_EVEN, result is negative; distance = 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfEvenNeg1() {
         String a = "-92948782094488478231212478987482988798104576347813847567949855464535634534563456";
         int aScale = -24;
@@ -1536,12 +1165,6 @@
     /**
      * Divide: rounding mode is ROUND_HALF_EVEN, result is negative; equidistant
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ROUND_UNNECESSARY and exceptions checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideRoundHalfEvenNeg2() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1559,12 +1182,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void testDivideIINonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -1593,12 +1210,6 @@
     /**
      * Divide to BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Common functionality checked",
-        method = "divide",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideBigDecimal1() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1616,12 +1227,6 @@
     /**
      * Divide to BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Common functionality checked",
-        method = "divide",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideBigDecimal2() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1639,12 +1244,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeUP() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1663,12 +1262,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeDOWN() {
         String a = "-37361671119238118911893939591735";
         int aScale = 10;
@@ -1687,12 +1280,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeCEILING() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 100;
@@ -1711,12 +1298,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeFLOOR() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 100;
@@ -1735,12 +1316,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeHALF_UP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = -51;
@@ -1761,12 +1336,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeHALF_DOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 5;
@@ -1785,12 +1354,6 @@
     /**
      * divide(BigDecimal, scale, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException and UNNECESSARY round mode checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
     public void testDivideBigDecimalScaleRoundingModeHALF_EVEN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 5;
@@ -1809,15 +1372,9 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, java.math.RoundingMode.class}
-    )
-    @KnownFailure("Has a rounding problem. seems like the precision is"
-            + " 1 too small and cuts off the last digit. also this test might"
-            + "not be correct. The name implies that scale should be used.")
+    // Has a rounding problem. seems like the precision is
+    // 1 too small and cuts off the last digit. also this test might
+    // not be correct. The name implies that scale should be used.
     public void testDivideScaleRoundingModeNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -1850,12 +1407,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextUP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 15;
@@ -1876,12 +1427,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextDOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 15;
@@ -1902,12 +1447,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextCEILING() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 15;
@@ -1928,12 +1467,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextFLOOR() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 15;
@@ -1954,12 +1487,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextHALF_UP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -1980,12 +1507,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextHALF_DOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2006,12 +1527,6 @@
     /**
      * divide(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideBigDecimalScaleMathContextHALF_EVEN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2032,14 +1547,7 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
-    @KnownFailure("The same test and the same problem like "
-            + "testDivideScaleRoundingModeNonTrivial")
+    // The same test and the same problem like testDivideScaleRoundingModeNonTrivial.
     public void testDivideMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -2090,11 +1598,6 @@
     /**
      * divideToIntegralValue(BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "divideToIntegralValue",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideToIntegralValue() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2109,11 +1612,6 @@
         assertEquals("incorrect scale", resScale, result.scale());
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "divideToIntegralValue",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideToIntegralValueByZero() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2136,12 +1634,6 @@
     /**
      * divideToIntegralValue(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divideToIntegralValue",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideToIntegralValueMathContextUP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2162,12 +1654,6 @@
     /**
      * divideToIntegralValue(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divideToIntegralValue",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideToIntegralValueMathContextDOWN() {
         String a = "3736186567876876578956958769675785435673453453653543654354365435675671119238118911893939591735";
         int aScale = 45;
@@ -2188,12 +1674,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divideToIntegralValue",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideToIntegralValueMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -2229,12 +1709,6 @@
     /**
      * divideAndRemainder(BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "divideAndRemainder",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideAndRemainder1() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2256,12 +1730,6 @@
     /**
      * divideAndRemainder(BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "divideAndRemainder",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideAndRemainder2() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = -45;
@@ -2285,12 +1753,6 @@
     /**
      * divideAndRemainder(BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "divideAndRemainder",
-        args = {java.math.BigDecimal.class}
-    )
     public void testDivideAndRemainderByZero() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2313,12 +1775,6 @@
     /**
      * divideAndRemainder(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divideAndRemainder",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideAndRemainderMathContextUP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2343,12 +1799,6 @@
     /**
      * divideAndRemainder(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "divideAndRemainder",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideAndRemainderMathContextDOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2373,12 +1823,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divideAndRemainder",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testDivideAndRemainderMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res[];
@@ -2413,11 +1857,6 @@
     /**
      * remainder(BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "remainder",
-        args = {java.math.BigDecimal.class}
-    )
     public void testRemainder1() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2435,11 +1874,6 @@
     /**
      * remainder(BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "remainder",
-        args = {java.math.BigDecimal.class}
-    )
     public void testRemainder2() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = -45;
@@ -2454,11 +1888,6 @@
         assertEquals("incorrect quotient scale", resScale, result.scale());
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "remainder",
-        args = {java.math.BigDecimal.class}
-    )
     public void testRemainderByZero() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2480,12 +1909,6 @@
     /**
      * remainder(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "remainder",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testRemainderMathContextHALF_UP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2506,12 +1929,6 @@
     /**
      * remainder(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "remainder",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testRemainderMathContextHALF_DOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = -45;
@@ -2532,12 +1949,6 @@
     /**
      * Non-trivial tests using MathContext:
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "remainder",
-        args = {java.math.BigDecimal.class, java.math.MathContext.class}
-    )
     public void testRemainderMathContextNonTrivial() {
         MathContext mc;
         BigDecimal a, b, res;
@@ -2572,12 +1983,6 @@
     /**
      * round(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "round",
-        args = {java.math.MathContext.class}
-    )
     public void testRoundMathContextHALF_DOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = -45;
@@ -2595,12 +2000,6 @@
     /**
      * round(BigDecimal, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "round",
-        args = {java.math.MathContext.class}
-    )
     public void testRoundMathContextHALF_UP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2618,12 +2017,6 @@
     /**
      * round(BigDecimal, MathContext) when precision = 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "round",
-        args = {java.math.MathContext.class}
-    )
     public void testRoundMathContextPrecision0() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2637,12 +2030,6 @@
         assertEquals("incorrect quotient scale", aScale, result.scale());
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "round",
-        args = {java.math.MathContext.class}
-    )
     public void testRoundNonTrivial() {
         MathContext mc;
         String biStr = new String( "12345678901234567890123456789012345.0E+10");
@@ -2693,12 +2080,6 @@
     /**
      * ulp() of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for ulp method.",
-        method = "ulp",
-        args = {}
-    )
     public void testUlpPos() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = -45;
@@ -2713,12 +2094,6 @@
     /**
      * ulp() of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for ulp method.",
-        method = "ulp",
-        args = {}
-    )
     public void testUlpNeg() {
         String a = "-3736186567876876578956958765675671119238118911893939591735";
         int aScale = 45;
@@ -2733,12 +2108,6 @@
     /**
      * ulp() of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for ulp method.",
-        method = "ulp",
-        args = {}
-    )
     public void testUlpZero() {
         String a = "0";
         int aScale = 2;
@@ -2755,12 +2124,6 @@
     /**
      * @tests java.math.BigDecimal#add(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_addBigDecimal() {
         BigDecimal add1 = new BigDecimal("23.456");
         BigDecimal add2 = new BigDecimal("3849.235");
@@ -2779,12 +2142,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.MathContext) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeUP() {
         String a = "-37361671119238118911893939591735";
         String b = "74723342238476237823787879183470";
@@ -2800,12 +2157,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeDOWN() {
         String a = "-37361671119238118911893939591735";
         String b = "74723342238476237823787879183470";
@@ -2821,12 +2172,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeCEILING() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         String b = "74723342238476237823787879183470";
@@ -2842,12 +2187,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeFLOOR() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         String b = "74723342238476237823787879183470";
@@ -2863,12 +2202,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeHALF_UP() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         String b = "74723342238476237823787879183470";
@@ -2884,12 +2217,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeHALF_DOWN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         int aScale = 5;
@@ -2909,12 +2236,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingModeHALF_EVEN() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         String b = "74723342238476237823787879183470";
@@ -2930,12 +2251,6 @@
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal,
      *        java.math.RoundingMode) divide(BigDecimal, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, java.math.RoundingMode.class}
-    )
     public void test_DivideBigDecimalRoundingExc() {
         String a = "3736186567876876578956958765675671119238118911893939591735";
         String b = "74723342238476237823787879183470";
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java
index 97e8a5d..b20491b 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalCompareTest.java
@@ -21,17 +21,13 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.MathContext;
 import java.math.RoundingMode;
-@TestTargetClass(BigDecimal.class)
+
 /**
  * Class:  java.math.BigDecimal
  * Methods: abs, compareTo, equals, hashCode, 
@@ -41,12 +37,6 @@
     /**
      * Abs() of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for abs method.",
-        method = "abs",
-        args = {}
-    )
     public void testAbsNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -57,12 +47,6 @@
     /**
      * Abs() of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for abs method.",
-        method = "abs",
-        args = {}
-    )
     public void testAbsPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -73,12 +57,6 @@
     /**
      * Abs(MathContext) of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Together with all other methods including a MathContext these tests for a complete test set.",
-        method = "abs",
-        args = {java.math.MathContext.class}
-    )
     public void testAbsMathContextNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -115,12 +93,6 @@
     /**
      * Abs(MathContext) of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Together with all other methods including a MathContext these tests for a complete test set.",
-        method = "abs",
-        args = {java.math.MathContext.class}
-    )
     public void testAbsMathContextPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -137,12 +109,6 @@
     /**
      * Compare to a number of an equal scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void testCompareEqualScale1() {
         String a = "12380964839238475457356735674573563567890295784902768787678287";
         int aScale = 18;
@@ -157,12 +123,6 @@
     /**
      * Compare to a number of an equal scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void testCompareEqualScale2() {
         String a = "12380964839238475457356735674573563567890295784902768787678287";
         int aScale = 18;
@@ -177,12 +137,6 @@
     /**
      * Compare to a number of an greater scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void testCompareGreaterScale1() {
         String a = "12380964839238475457356735674573563567890295784902768787678287";
         int aScale = 28;
@@ -197,12 +151,6 @@
     /**
      * Compare to a number of an greater scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void testCompareGreaterScale2() {
         String a = "12380964839238475457356735674573563567890295784902768787678287";
         int aScale = 48;
@@ -217,12 +165,6 @@
     /**
      * Compare to a number of an less scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void testCompareLessScale1() {
         String a = "12380964839238475457356735674573563567890295784902768787678287";
         int aScale = 18;
@@ -237,12 +179,6 @@
     /**
      * Compare to a number of an less scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void testCompareLessScale2() {
         String a = "12380964839238475457356735674573";
         int aScale = 36;
@@ -257,12 +193,6 @@
     /**
      * Equals() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsUnequal1() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = -24;
@@ -276,12 +206,6 @@
     /**
      * Equals() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsUnequal2() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = -24;
@@ -295,12 +219,6 @@
     /**
      * Equals() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsUnequal3() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = -24;
@@ -312,12 +230,6 @@
     /**
      * equals() for equal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsEqual() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = -24;
@@ -331,12 +243,6 @@
     /**
      * equals() for equal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsNull() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = -24;
@@ -347,12 +253,6 @@
     /**
      * hashCode() for equal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for hashCode method.",
-        method = "hashCode",
-        args = {}
-    )
     public void testHashCodeEqual() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = -24;
@@ -366,12 +266,6 @@
     /**
      * hashCode() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for hashCode method.",
-        method = "hashCode",
-        args = {}
-    )
     public void testHashCodeUnequal() {
        String a = "8478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -385,12 +279,6 @@
     /**
      * max() for equal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMaxEqual() {
        String a = "8478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -407,12 +295,6 @@
     /**
      * max() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMaxUnequal1() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 24;
@@ -429,12 +311,6 @@
     /**
      * max() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMaxUnequal2() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -451,12 +327,6 @@
     /**
      * min() for equal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for min method.",
-        method = "min",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMinEqual() {
        String a = "8478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -473,12 +343,6 @@
     /**
      * min() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for min method.",
-        method = "min",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMinUnequal1() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 24;
@@ -495,12 +359,6 @@
     /**
      * min() for unequal BigDecimals
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for min method.",
-        method = "min",
-        args = {java.math.BigDecimal.class}
-    )
     public void testMinUnequal2() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -517,12 +375,6 @@
     /**
      * plus() for a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for plus method.",
-        method = "plus",
-        args = {}
-    )
     public void testPlusPositive() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -536,12 +388,6 @@
     /**
      * plus(MathContext) for a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Together with all other methods including a MathContext these tests for a complete test set.",
-        method = "plus",
-        args = {java.math.MathContext.class}
-    )
     public void testPlusMathContextPositive() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -559,12 +405,6 @@
     /**
      * plus() for a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for plus method.",
-        method = "plus",
-        args = {}
-    )
     public void testPlusNegative() {
        String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -578,12 +418,6 @@
     /**
      * plus(MathContext) for a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Together with all other methods including a MathContext these tests for a complete test set.",
-        method = "plus",
-        args = {java.math.MathContext.class}
-    )
     public void testPlusMathContextNegative() {
        String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 49;
@@ -601,12 +435,6 @@
     /**
      * negate() for a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for negate method.",
-        method = "negate",
-        args = {}
-    )
     public void testNegatePositive() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -620,12 +448,6 @@
     /**
      * negate(MathContext) for a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Together with all other methods including a MathContext these tests for a complete test set.",
-        method = "negate",
-        args = {java.math.MathContext.class}
-    )
     public void testNegateMathContextPositive() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        MathContext mc = new MathContext(37, RoundingMode.FLOOR);
@@ -650,12 +472,6 @@
     /**
      * negate() for a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for negate method.",
-        method = "negate",
-        args = {}
-    )
     public void testNegateNegative() {
        String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -669,12 +485,6 @@
     /**
      * negate(MathContext) for a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Together with all other methods including a MathContext these tests for a complete test set.",
-        method = "negate",
-        args = {java.math.MathContext.class}
-    )
     public void testNegateMathContextNegative() {
        String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 49;
@@ -692,12 +502,6 @@
     /**
      * signum() for a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for signum method.",
-        method = "signum",
-        args = {}
-    )
     public void testSignumPositive() {
        String a = "92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -708,12 +512,6 @@
     /**
      * signum() for a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for signum method.",
-        method = "signum",
-        args = {}
-    )
     public void testSignumNegative() {
        String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
        int aScale = 41;
@@ -724,12 +522,6 @@
     /**
      * signum() for zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for signum method.",
-        method = "signum",
-        args = {}
-    )
     public void testSignumZero() {
        String a = "0";
        int aScale = 41;
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java
index 74d0cb0..3657096 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConstructorsTest.java
@@ -21,17 +21,13 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.MathContext;
 import java.math.RoundingMode;
-@TestTargetClass(BigDecimal.class)
+
 /**
  * Class:  java.math.BigDecimal
  * Methods: constructors and fields
@@ -40,11 +36,6 @@
     /**
      * check ONE
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "tests BigDecimal.ONE to be 1.0d",
-        method = "!field:BigDecimal.ONE"
-    )        
     public void testFieldONE() {
         String oneS = "1";
         double oneD = 1.0;
@@ -55,11 +46,6 @@
     /**
      * check TEN
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "tests BigDecimal.TEN to be 10.0d",
-        method = "!field:BigDecimal.TEN"
-    )        
     public void testFieldTEN() {
         String oneS = "10";
         double oneD = 10.0;
@@ -70,11 +56,6 @@
     /**
      * check ZERO
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "tests BigDecimal.ZERO to be 0.0d",
-        method = "!field:BigDecimal.ZERO"
-    )            
     public void testFieldZERO() {
         String oneS = "0";
         double oneD = 0.0;
@@ -85,12 +66,6 @@
     /**
      * new BigDecimal(BigInteger value)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class}
-    )
     public void testConstrBI() {
         String a = "1231212478987482988429808779810457634781384756794987";
         BigInteger bA = new BigInteger(a);
@@ -109,12 +84,6 @@
     /**
      * new BigDecimal(BigInteger value, int scale)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class, int.class}
-    )
     public void testConstrBIScale() {
         String a = "1231212478987482988429808779810457634781384756794987";
         BigInteger bA = new BigInteger(a);
@@ -127,12 +96,6 @@
     /**
      * new BigDecimal(BigInteger value, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class, java.math.MathContext.class}
-    )
     public void testConstrBigIntegerMathContext() {
         String a = "1231212478987482988429808779810457634781384756794987";
         BigInteger bA = new BigInteger(a);
@@ -213,11 +176,6 @@
     /**
      * new BigDecimal(BigInteger value, int scale, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class, int.class, java.math.MathContext.class}
-    )
     public void testConstrBigIntegerScaleMathContext() {
         String a = "1231212478987482988429808779810457634781384756794987";
         BigInteger bA = new BigInteger(a);
@@ -368,11 +326,6 @@
         assertEquals("incorrect value", "-1234567890123456789012345.679", bd.toString());
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class, int.class, java.math.MathContext.class}
-    )
     public void testConstrBigIntegerScaleMathContext_AndroidFailure() {
         MathContext mc;
         BigDecimal bd;
@@ -385,12 +338,6 @@
     /**
      * new BigDecimal(char[] value); 
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {char[].class}
-    )
     public void testConstrChar() {
         char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
         BigDecimal result = new BigDecimal(value);
@@ -410,12 +357,6 @@
     /**
      * new BigDecimal(char[] value, int offset, int len); 
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {char[].class, int.class, int.class}
-    )
     public void testConstrCharIntInt() {
         char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
         int offset = 3;
@@ -437,12 +378,6 @@
     /**
      * new BigDecimal(char[] value, int offset, int len, MathContext mc); 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {char[].class, int.class, int.class, java.math.MathContext.class}
-    )
     public void testConstrCharIntIntMathContext() {
         char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
         int offset = 3;
@@ -536,12 +471,6 @@
     /**
      * new BigDecimal(char[] value, int offset, int len, MathContext mc); 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {char[].class, int.class, int.class, java.math.MathContext.class}
-    )
     public void testConstrCharIntIntMathContextException1() {
         char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
         int offset = 3;
@@ -559,12 +488,6 @@
     /**
      * new BigDecimal(char[] value, MathContext mc);
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {char[].class, java.math.MathContext.class}
-    )
     public void testConstrCharMathContext() {
         try {
             // Regression for HARMONY-783
@@ -617,12 +540,6 @@
     /**
      * new BigDecimal(double value) when value is NaN
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDoubleNaN() {
         double a = Double.NaN;
         try {
@@ -637,12 +554,6 @@
     /**
      * new BigDecimal(double value) when value is positive infinity
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDoublePosInfinity() {
         double a = Double.POSITIVE_INFINITY;
         try {
@@ -657,12 +568,6 @@
     /**
      * new BigDecimal(double value) when value is positive infinity
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDoubleNegInfinity() {
         double a = Double.NEGATIVE_INFINITY;
         try {
@@ -677,12 +582,6 @@
     /**
      * new BigDecimal(double value)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDouble() {
         double a = 732546982374982347892379283571094797.287346782359284756;
         int aScale = 0;
@@ -695,11 +594,6 @@
     /**
      * new BigDecimal(double, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "BigDecimal",
-        args = {double.class, java.math.MathContext.class}
-    )
     public void testConstrDoubleMathContext() {
         double a = 732546982374982347892379283571094797.287346782359284756;
         int precision = 21;
@@ -795,11 +689,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "BigDecimal",
-        args = {double.class, java.math.MathContext.class}
-    )
     public void testConstrDoubleMathContext_AndroidFailure() {
         BigDecimal bd;
         MathContext mc;
@@ -843,12 +732,6 @@
     /**
      * new BigDecimal(0.1)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDouble01() {
         double a = 1.E-1;
         int aScale = 55;
@@ -861,12 +744,6 @@
     /**
      * new BigDecimal(0.555)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDouble02() {
         double a = 0.555;
         int aScale = 53;
@@ -879,12 +756,6 @@
     /**
      * new BigDecimal(-0.1)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDoubleMinus01() {
         double a = -1.E-1;
         int aScale = 55;
@@ -897,12 +768,6 @@
     /**
      * new BigDecimal(int value)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {int.class}
-    )
     public void testConstrInt() {
         int a = 732546982;
         String res = "732546982";
@@ -915,12 +780,6 @@
     /**
      * new BigDecimal(int, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {int.class, java.math.MathContext.class}
-    )
     public void testConstrIntMathContext() {
         int a = 732546982;
         int precision = 21;
@@ -936,12 +795,6 @@
     /**
      * new BigDecimal(long value)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {long.class}
-    )
     public void testConstrLong() {
         long a = 4576578677732546982L;
         String res = "4576578677732546982";
@@ -954,12 +807,6 @@
     /**
      * new BigDecimal(long, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {long.class, java.math.MathContext.class}
-    )
     public void testConstrLongMathContext() {
         long a = 4576578677732546982L;
         int precision = 5;
@@ -1037,12 +884,6 @@
     /**
      * new BigDecimal(double value) when value is denormalized
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(double) constructor.",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void testConstrDoubleDenormalized() {
         double a = 2.274341322658976E-309;
         int aScale = 1073;
@@ -1056,12 +897,6 @@
      * new BigDecimal(String value)
      * when value is not a valid representation of BigDecimal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringException() {
         String a = "-238768.787678287a+10";
         try {
@@ -1075,12 +910,6 @@
     /**
      * new BigDecimal(String value) when exponent is empty.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringExceptionEmptyExponent1() {
         String a = "-238768.787678287e";
         try {
@@ -1093,12 +922,6 @@
     /**
      * new BigDecimal(String value) when exponent is empty.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringExceptionEmptyExponent2() {
         String a = "-238768.787678287e-";
         try {
@@ -1112,12 +935,6 @@
      * new BigDecimal(String value) when exponent is greater than
      * Integer.MAX_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringExceptionExponentGreaterIntegerMax() {
         String a = "-238768.787678287e214748364767876";
         try {
@@ -1131,12 +948,6 @@
      * new BigDecimal(String value) when exponent is less than
      * Integer.MIN_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringExceptionExponentLessIntegerMin() {
         String a = "-238768.787678287e-214748364767876";
         try {
@@ -1150,12 +961,6 @@
      * new BigDecimal(String value)
      * when exponent is Integer.MAX_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringExponentIntegerMax() {
         String a = "-238768.787678287e2147483647";
         int aScale = -2147483638;
@@ -1169,12 +974,6 @@
      * new BigDecimal(String value)
      * when exponent is Integer.MIN_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringExponentIntegerMin() {
         String a = ".238768e-2147483648";
         try {
@@ -1189,12 +988,6 @@
     /**
      * new BigDecimal(String value); value does not contain exponent
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithoutExpPos1() {
         String a = "732546982374982347892379283571094797.287346782359284756";
         int aScale = 18;
@@ -1207,12 +1000,6 @@
     /**
      * new BigDecimal(String value); value does not contain exponent
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithoutExpPos2() {
         String a = "+732546982374982347892379283571094797.287346782359284756";
         int aScale = 18;
@@ -1225,12 +1012,6 @@
     /**
      * new BigDecimal(String value); value does not contain exponent
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithoutExpNeg() {
         String a = "-732546982374982347892379283571094797.287346782359284756";
         int aScale = 18;
@@ -1244,12 +1025,6 @@
      * new BigDecimal(String value); value does not contain exponent
      * and decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithoutExpWithoutPoint() {
         String a = "-732546982374982347892379283571094797287346782359284756";
         int aScale = 0;
@@ -1263,12 +1038,6 @@
      * new BigDecimal(String value); value contains exponent
      * and does not contain decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithoutPoint1() {
         String a = "-238768787678287e214";
         int aScale = -214;
@@ -1282,12 +1051,6 @@
      * new BigDecimal(String value); value contains exponent
      * and does not contain decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithoutPoint2() {
         String a = "-238768787678287e-214";
         int aScale = 214;
@@ -1301,12 +1064,6 @@
      * new BigDecimal(String value); value contains exponent
      * and does not contain decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithoutPoint3() {
         String a = "238768787678287e-214";
         int aScale = 214;
@@ -1320,12 +1077,6 @@
      * new BigDecimal(String value); value contains exponent
      * and does not contain decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithoutPoint4() {
         String a = "238768787678287e+214";
         int aScale = -214;
@@ -1339,12 +1090,6 @@
      * new BigDecimal(String value); value contains exponent
      * and does not contain decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithoutPoint5() {
         String a = "238768787678287E214";
         int aScale = -214;
@@ -1358,12 +1103,6 @@
      * new BigDecimal(String value); 
      * value contains both exponent and decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithPoint1() {
         String a = "23985439837984782435652424523876878.7678287e+214";
         int aScale = -207;
@@ -1377,12 +1116,6 @@
      * new BigDecimal(String value); 
      * value contains both exponent and decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithPoint2() {
         String a = "238096483923847545735673567457356356789029578490276878.7678287e-214";
         int aScale = 221;
@@ -1396,12 +1129,6 @@
      * new BigDecimal(String value); 
      * value contains both exponent and decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithPoint3() {
         String a = "2380964839238475457356735674573563567890.295784902768787678287E+21";
         int aScale = 0;
@@ -1415,12 +1142,6 @@
      * new BigDecimal(String value); 
      * value contains both exponent and decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithPoint4() {
         String a = "23809648392384754573567356745735635678.90295784902768787678287E+21";
         int aScale = 2;
@@ -1434,12 +1155,6 @@
      * new BigDecimal(String value); 
      * value contains both exponent and decimal point
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigDecimal(String) constructor.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void testConstrStringWithExponentWithPoint5() {
         String a = "238096483923847545735673567457356356789029.5784902768787678287E+21";
         int aScale = -2;
@@ -1452,12 +1167,6 @@
     /**
      * new BigDecimal(String value, MathContext)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.lang.String.class, java.math.MathContext.class}
-    )
     public void testConstrStringMathContext() {
         String a = "-238768787678287e214";
         int precision = 5;
@@ -1517,12 +1226,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class, int.class}
-    )
     public void test_Constructor_java_math_BigInteger_int() {
         BigInteger value = new BigInteger("12345908");
         BigDecimal big = new BigDecimal(value);
@@ -1542,12 +1245,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(double)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void test_Constructor_Double() {
         BigDecimal big = new BigDecimal(123E04);
         assertTrue("the BigDecimal value taking a double argument is not initialized properly", big
@@ -1576,12 +1273,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void test_Constructor_java_lang_String() throws NumberFormatException {
         BigDecimal big = new BigDecimal("345.23499600293850");
         assertTrue("the BigDecimal value is not initialized properly", big.toString().equals(
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConvertTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConvertTest.java
index 5015ae0..e9a150e 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConvertTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalConvertTest.java
@@ -21,18 +21,13 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
 import java.math.MathContext;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigDecimal.class)
+
 /**
  * Class:  java.math.BigDecimal
  * Methods: doubleValue, floatValue, intValue, longValue,  
@@ -42,12 +37,6 @@
     /**
      * Double value of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -58,12 +47,6 @@
     /**
      * Double value of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -74,12 +57,6 @@
     /**
      * Double value of a large positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePosInfinity() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+400";
         BigDecimal aNumber = new BigDecimal(a);
@@ -90,12 +67,6 @@
     /**
      * Double value of a large negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegInfinity() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+400";
         BigDecimal aNumber = new BigDecimal(a);
@@ -106,12 +77,6 @@
     /**
      * Double value of a small negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueMinusZero() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E-400";
         BigDecimal aNumber = new BigDecimal(a);
@@ -123,12 +88,6 @@
     /**
      * Double value of a small positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePlusZero() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E-400";
         BigDecimal aNumber = new BigDecimal(a);
@@ -140,12 +99,6 @@
     /**
      * Float value of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNeg() {
         String a = "-1238096483923847.6356789029578E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -156,12 +109,6 @@
     /**
      * Float value of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePos() {
         String a = "1238096483923847.6356789029578E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -172,12 +119,6 @@
     /**
      * Float value of a large positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePosInfinity() {
         String a = "123809648373567356745735.6356789787678287E+200";
         BigDecimal aNumber = new BigDecimal(a);
@@ -188,12 +129,6 @@
     /**
      * Float value of a large negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegInfinity() {
         String a = "-123809648392384755735.63567887678287E+200";
         BigDecimal aNumber = new BigDecimal(a);
@@ -204,12 +139,6 @@
     /**
      * Float value of a small negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueMinusZero() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E-400";
         BigDecimal aNumber = new BigDecimal(a);
@@ -221,12 +150,6 @@
     /**
      * Float value of a small positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePlusZero() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E-400";
         BigDecimal aNumber = new BigDecimal(a);
@@ -238,12 +161,6 @@
     /**
      * Integer value of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValueNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -254,12 +171,6 @@
     /**
      * Integer value of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValuePos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -270,12 +181,6 @@
     /**
      * Long value of a negative BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for longValue method",
-        method = "longValue",
-        args = {}
-    )
     public void testLongValueNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -286,12 +191,6 @@
     /**
      * Long value of a positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for longValue method",
-        method = "longValue",
-        args = {}
-    )
     public void testLongValuePos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -302,12 +201,6 @@
     /**
      * scaleByPowerOfTen(int n)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed",
-        method = "scaleByPowerOfTen",
-        args = {int.class}
-    )
     public void testScaleByPowerOfTen1() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 13;
@@ -322,12 +215,6 @@
     /**
      * scaleByPowerOfTen(int n)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed",
-        method = "scaleByPowerOfTen",
-        args = {int.class}
-    )
     public void testScaleByPowerOfTen2() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -13;
@@ -342,12 +229,6 @@
     /**
      * Convert a positive BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerPos1() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigInteger bNumber = new BigInteger("123809648392384754573567356745735635678902957849027687");
@@ -359,12 +240,6 @@
     /**
      * Convert a positive BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerPos2() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+15";
         BigInteger bNumber = new BigInteger("123809648392384754573567356745735635678902957849");
@@ -376,12 +251,6 @@
     /**
      * Convert a positive BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerPos3() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+45";
         BigInteger bNumber = new BigInteger("123809648392384754573567356745735635678902957849027687876782870000000000000000");
@@ -393,12 +262,6 @@
     /**
      * Convert a negative BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerNeg1() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigInteger bNumber = new BigInteger("-123809648392384754573567356745735635678902957849027687");
@@ -410,12 +273,6 @@
     /**
      * Convert a negative BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerNeg2() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+15";
         BigInteger bNumber = new BigInteger("-123809648392384754573567356745735635678902957849");
@@ -427,12 +284,6 @@
     /**
      * Convert a negative BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerNeg3() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+45";
         BigInteger bNumber = new BigInteger("-123809648392384754573567356745735635678902957849027687876782870000000000000000");
@@ -444,12 +295,6 @@
     /**
      * Convert a small BigDecimal to BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigInteger method",
-        method = "toBigInteger",
-        args = {}
-    )
     public void testToBigIntegerZero() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E-500";
         BigInteger bNumber = new BigInteger("0");
@@ -461,12 +306,6 @@
     /**
      * toBigIntegerExact()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigIntegerExact method",
-        method = "toBigIntegerExact",
-        args = {}
-    )
     public void testToBigIntegerExact1() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+45";
         BigDecimal aNumber = new BigDecimal(a);
@@ -478,12 +317,6 @@
     /**
      * toBigIntegerExact()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toBigIntegerExact method",
-        method = "toBigIntegerExact",
-        args = {}
-    )
     public void testToBigIntegerExactException() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E-10";
         BigDecimal aNumber = new BigDecimal(a);
@@ -498,12 +331,6 @@
     /**
      * Convert a positive BigDecimal to an engineering string representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toEngineeringString method",
-        method = "toEngineeringString",
-        args = {}
-    )
     public void testToEngineeringStringPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E-501";
         BigDecimal aNumber = new BigDecimal(a);
@@ -514,12 +341,6 @@
     /**
      * Convert a negative BigDecimal to an engineering string representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toEngineeringString method",
-        method = "toEngineeringString",
-        args = {}
-    )
     public void testToEngineeringStringNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E-501";
         BigDecimal aNumber = new BigDecimal(a);
@@ -530,12 +351,6 @@
     /**
      * Convert a negative BigDecimal to an engineering string representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toEngineeringString method",
-        method = "toEngineeringString",
-        args = {}
-    )
     public void testToEngineeringStringZeroPosExponent() {
         String a = "0.0E+16";
         BigDecimal aNumber = new BigDecimal(a);
@@ -546,12 +361,6 @@
     /**
      * Convert a negative BigDecimal to an engineering string representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toEngineeringString method",
-        method = "toEngineeringString",
-        args = {}
-    )
     public void testToEngineeringStringZeroNegExponent() {
         String a = "0.0E-16";
         BigDecimal aNumber = new BigDecimal(a);
@@ -563,12 +372,6 @@
      * Convert a negative BigDecimal with a negative exponent to a plain string
      * representation; scale == 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toPlainString method",
-        method = "toPlainString",
-        args = {}
-    )
     public void testToPlainStringNegNegExp() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E-100";
         BigDecimal aNumber = new BigDecimal(a);
@@ -581,12 +384,6 @@
      * to a plain string representation;
      * scale == 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toPlainString method",
-        method = "toPlainString",
-        args = {}
-    )
     public void testToPlainStringNegPosExp() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E100";
         BigDecimal aNumber = new BigDecimal(a);
@@ -599,12 +396,6 @@
      * to a plain string representation;
      * scale == 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toPlainString method",
-        method = "toPlainString",
-        args = {}
-    )
     public void testToPlainStringPosNegExp() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E-100";
         BigDecimal aNumber = new BigDecimal(a);
@@ -617,12 +408,6 @@
      * to a plain string representation;
      * scale == 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toPlainString method",
-        method = "toPlainString",
-        args = {}
-    )
     public void testToPlainStringPosPosExp() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+100";
         BigDecimal aNumber = new BigDecimal(a);
@@ -634,12 +419,6 @@
      * Convert a BigDecimal to a string representation;
      * scale == 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void testToStringZeroScale() {
         String a = "-123809648392384754573567356745735635678902957849027687876782870";
         BigDecimal aNumber = new BigDecimal(new BigInteger(a));
@@ -650,12 +429,6 @@
     /**
      * Convert a positive BigDecimal to a string representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void testToStringPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E-500";
         BigDecimal aNumber = new BigDecimal(a);
@@ -666,12 +439,6 @@
     /**
      * Convert a negative BigDecimal to a string representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void testToStringNeg() {
         String a = "-123.4564563673567380964839238475457356735674573563567890295784902768787678287E-5";
         BigDecimal aNumber = new BigDecimal(a);
@@ -682,12 +449,6 @@
     /**
      * Create a BigDecimal from a positive long value; scale == 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(long) method",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfPosZeroScale() {
         long a = 98374823947823578L;
         BigDecimal aNumber = BigDecimal.valueOf(a);
@@ -698,12 +459,6 @@
     /**
      * Create a BigDecimal from a negative long value; scale is 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(long) method",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfNegZeroScale() {
         long a = -98374823947823578L;
         BigDecimal aNumber = BigDecimal.valueOf(a);
@@ -714,12 +469,6 @@
     /**
      * Create a BigDecimal from a negative long value; scale is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(long) method",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfNegScalePos() {
         long a = -98374823947823578L;
         int scale = 12;
@@ -731,12 +480,6 @@
     /**
      * Create a BigDecimal from a negative long value; scale is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(long) method",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfNegScaleNeg() {
         long a = -98374823947823578L;
         int scale = -12;
@@ -748,12 +491,6 @@
     /**
      * Create a BigDecimal from a negative long value; scale is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(long) method",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfPosScalePos() {
         long a = 98374823947823578L;
         int scale = 12;
@@ -765,12 +502,6 @@
     /**
      * Create a BigDecimal from a negative long value; scale is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(long) method",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfPosScaleNeg() {
         long a = 98374823947823578L;
         int scale = -12;
@@ -782,12 +513,6 @@
     /**
      * Create a BigDecimal from a negative double value
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(double) method",
-        method = "valueOf",
-        args = {double.class}
-    )
     public void testValueOfDoubleNeg() {
         double a = -65678765876567576.98788767;
         BigDecimal result = BigDecimal.valueOf(a);
@@ -800,12 +525,6 @@
     /**
      * Create a BigDecimal from a positive double value
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(double) method",
-        method = "valueOf",
-        args = {double.class}
-    )
     public void testValueOfDoublePos1() {
         double a = 65678765876567576.98788767;
         BigDecimal result = BigDecimal.valueOf(a);
@@ -818,12 +537,6 @@
     /**
      * Create a BigDecimal from a positive double value
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(double) method",
-        method = "valueOf",
-        args = {double.class}
-    )
     public void testValueOfDoublePos2() {
         double a = 12321237576.98788767;
         BigDecimal result = BigDecimal.valueOf(a);
@@ -836,12 +549,6 @@
     /**
      * Create a BigDecimal from a positive double value
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(double) method",
-        method = "valueOf",
-        args = {double.class}
-    )
     public void testValueOfDoublePos3() {
         double a = 12321237576.9878838;
         BigDecimal result = BigDecimal.valueOf(a);
@@ -854,12 +561,6 @@
     /**
      * valueOf(Double.NaN)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf(double) method",
-        method = "valueOf",
-        args = {double.class}
-    )
     public void testValueOfDoubleNaN() {
         double a = Double.NaN;
         try {
@@ -876,12 +577,6 @@
      * @tests java.math.BigDecimal#intValueExact() Integer value of a negative
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValueExact method",
-        method = "intValueExact",
-        args = {}
-    )
     public void test_IntValueExactNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -897,12 +592,6 @@
      * @tests java.math.BigDecimal#intValueExact() Integer value of a positive
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValueExact method",
-        method = "intValueExact",
-        args = {}
-    )
     public void test_IntValueExactPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -918,12 +607,6 @@
      * @tests java.math.BigDecimal#intValueExact() Integer value of a negative
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValueExact method",
-        method = "intValueExact",
-        args = {}
-    )
     public void test_IntValueExactFloatNeg() {
         BigDecimal aNumber = new BigDecimal("-2147483647.999");
         try {
@@ -938,12 +621,6 @@
      * @tests java.math.BigDecimal#intValueExact() Integer value of a positive
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValueExact method",
-        method = "intValueExact",
-        args = {}
-    )
     public void test_IntValueExactFloatPos() {
         float a = 2147483646.99999F;
         BigDecimal aNumber = new BigDecimal(a);
@@ -959,12 +636,6 @@
      * @tests java.math.BigDecimal#intValueExact() Integer value of a positive
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValueExact method",
-        method = "intValueExact",
-        args = {}
-    )
     public void test_IntValueExactLongPos() {
         long a = 2147483647L;
         BigDecimal aNumber = new BigDecimal(a);
@@ -976,12 +647,6 @@
      * @tests java.math.BigDecimal#intValueExact() Integer value of a positive
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValueExact method",
-        method = "intValueExact",
-        args = {}
-    )
     public void test_IntValueExactLongNeg() {
         long a = -2147483648L;
         BigDecimal aNumber = new BigDecimal(a);
@@ -993,12 +658,6 @@
      * @tests java.math.BigDecimal#longValueExact() Long value of a negative
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checked",
-        method = "longValueExact",
-        args = {}
-    )
     public void test_LongValueExactNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -1014,12 +673,6 @@
      * @tests java.math.BigDecimal#longValueExact() Long value of a positive
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "ArithmeticException checked",
-        method = "longValueExact",
-        args = {}
-    )
     public void test_LongValueExactPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -1035,12 +688,6 @@
      * @tests java.math.BigDecimal#longValueExact() Long value of a negative
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "ArithmeticException checked",
-        method = "longValueExact",
-        args = {}
-    )
     public void test_LongValueExactFloatNeg() {
         BigDecimal aNumber = new BigDecimal("-9223372036854775807.99999");
         try {
@@ -1055,12 +702,6 @@
      * @tests java.math.BigDecimal#longValueExact() Long value of a positive
      *        BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "ArithmeticException checked",
-        method = "longValueExact",
-        args = {}
-    )
     public void test_LongValueExactFloatPos() {
         float a = 9223372036854775806.99999F;
         BigDecimal aNumber = new BigDecimal(a);
@@ -1076,12 +717,6 @@
      * @test java.math.BigDecimal#byteValueExact() Convert pisitive BigDesimal
      *       to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactPos() {
         int i = 127;
         BigDecimal bdNumber = new BigDecimal(i);
@@ -1093,12 +728,6 @@
      * @test java.math.BigDecimal#byteValueExact() Convert negative BigDesimal
      *       to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactNeg() {
         String sNumber = "-127.56789";
         int iNumber = -128;
@@ -1114,12 +743,6 @@
      *       from char array to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactCharZero() {
         char[] cNumber = {
                 '-', '0', '.', '0'
@@ -1137,12 +760,6 @@
      *       from String to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactStringZero() {
         String sNumber = "00000000000000";
         int iNumber = 0;
@@ -1158,12 +775,6 @@
      *       from double to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactDoubleMax() {
         double dNumber = Double.MAX_VALUE;
         BigDecimal bdNumber = new BigDecimal(dNumber);
@@ -1180,12 +791,6 @@
      *       from double to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactDoubleMin() {
         double dNumber = Double.MIN_VALUE;
         BigDecimal bdNumber = new BigDecimal(dNumber);
@@ -1202,12 +807,6 @@
      *       from float to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactFloatPos() {
         float fNumber = 123.5445F;
         BigDecimal bdNumber = new BigDecimal(fNumber);
@@ -1224,12 +823,6 @@
      *       from float to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactFloatNeg() {
         float fNumber = -12.987654321F;
         BigDecimal bdNumber = new BigDecimal(fNumber);
@@ -1246,12 +839,6 @@
      *       from double to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactDouble() {
         double dNumber = 123.0000D;
         BigDecimal bdNumber = new BigDecimal(dNumber);
@@ -1264,12 +851,6 @@
      *       from long to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactLongMin() {
         long lNumber = Long.MIN_VALUE;
         BigDecimal bdNumber = new BigDecimal(lNumber);
@@ -1286,12 +867,6 @@
      *       from int to byte type
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for byteValueExact method",
-        method = "byteValueExact",
-        args = {}
-    )
     public void test_ByteValueExactIntMax() {
         int iNumber = Integer.MAX_VALUE;
         BigDecimal bdNumber = new BigDecimal(iNumber);
@@ -1307,11 +882,6 @@
      * @test java.math.BigDecimal#byteValue() Convert pisitive BigDesimal to
      *       byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValuePos() {
         int i = 127;
         BigDecimal bdNumber = new BigDecimal(i);
@@ -1323,11 +893,6 @@
      * @test java.math.BigDecimal#byteValue() Convert negative BigDesimal to
      *       byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueNeg() {
         String sNumber = "-127.56789";
         int iNumber = -128;
@@ -1342,11 +907,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       char array to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueCharZero() {
         char[] cNumber = {
                 '-', '0', '.', '0'
@@ -1363,11 +923,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       String to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueStringZero() {
         String sNumber = "00000";
         int iNumber = 0;
@@ -1382,11 +937,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       double to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueDoubleMax() {
         double dNumber = Double.MAX_VALUE;
         BigDecimal bdNumber = new BigDecimal(dNumber);
@@ -1399,11 +949,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       double to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueDoubleMin() {
         double dNumber = Double.MIN_VALUE;
         BigDecimal bdNumber = new BigDecimal(dNumber);
@@ -1416,11 +961,6 @@
      * @test_ java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *        float to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueFloatNeg() {
         float fNumber = -12.987654321F;
         byte bValue = -12;
@@ -1433,11 +973,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       double to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueDouble() {
         double dNumber = 123.0000D;
         BigDecimal bdNumber = new BigDecimal(dNumber);
@@ -1449,11 +984,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       long to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueLongMin() {
         long lNumber = Long.MIN_VALUE;
         int result = 0;
@@ -1466,11 +996,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       int to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueIntMin() {
         int iNumber = Integer.MIN_VALUE;
         int result = 0;
@@ -1483,11 +1008,6 @@
      * @test java.math.BigDecimal#byteValue() Convert BigDesimal created from
      *       int to byte type
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "byteValue",
-        args = {}
-    )
     public void test_ByteValueIntMax() {
         int iNumber = Integer.MAX_VALUE;
         int result = -1;
@@ -1500,11 +1020,6 @@
      * @test java.math.BigDecimal#shortValue() Short value of a negative
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "shortValue",
-        args = {}
-    )
     public void test_ShortValueNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -1516,11 +1031,6 @@
      * @test java.math.BigDecimal#shortValue() Short value of a positive
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "shortValue",
-        args = {}
-    )
     public void test_ShortValuePos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -1532,12 +1042,6 @@
      * @test java.math.BigDecimal#shortValueExact() Short value of a negative
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shortValueExact method",
-        method = "shortValueExact",
-        args = {}
-    )
     public void test_ShortValueExactNeg() {
         String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -1553,12 +1057,6 @@
      * @test java.math.BigDecimal#shortValueExact() Short value of a positive
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shortValueExact method",
-        method = "shortValueExact",
-        args = {}
-    )
     public void test_ShortValueExactPos() {
         String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
         BigDecimal aNumber = new BigDecimal(a);
@@ -1574,12 +1072,6 @@
      * @test java.math.BigDecimal#shortValueExact() Short value of a negative
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shortValueExact method",
-        method = "shortValueExact",
-        args = {}
-    )
     public void test_ShortValueExactFloatNeg() {
         BigDecimal aNumber = new BigDecimal("-32766.99999");
         try {
@@ -1594,12 +1086,6 @@
      * @test java.math.BigDecimal#shortValueExact() Short value of a positive
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shortValueExact method",
-        method = "shortValueExact",
-        args = {}
-    )
     public void test_ShortValueExactFloatPos() {
         float a = 32767.99999F;
         BigDecimal aNumber = new BigDecimal(a);
@@ -1615,12 +1101,6 @@
      * @test java.math.BigDecimal#shortValueExact() Short value of a positive
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shortValueExact method",
-        method = "shortValueExact",
-        args = {}
-    )
     public void test_ShortValueExactLongPos() {
         long a = 12345L;
         BigDecimal aNumber = new BigDecimal(a);
@@ -1632,12 +1112,6 @@
      * @test java.math.BigDecimal#shortValueExact() Short value of a positive
      *       BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shortValueExact method",
-        method = "shortValueExact",
-        args = {}
-    )
     public void test_ShortValueExactLongNeg() {
         long a = -12345L;
         BigDecimal aNumber = new BigDecimal(a);
@@ -1649,12 +1123,6 @@
      * @tests java.math.BigDecimal#stripTrailingZeros() stripTrailingZeros() for
      *        BigDecimal with zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for stripTrailingZeros method",
-        method = "stripTrailingZeros",
-        args = {}
-    )
     public void test_stripTrailingZerosZeros() {
 
         BigDecimal bdNumber = new BigDecimal("0000000");
@@ -1677,12 +1145,6 @@
      * @tests java.math.BigDecimal#stripTrailingZeros() stripTrailingZeros() for
      *        positive BigDecimal
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for stripTrailingZeros method",
-        method = "stripTrailingZeros",
-        args = {}
-    )
     public void test_stripTrailingZeros() {
 
         String s = "00000000100000000100000000.000000000100000000";
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java
index 17c9a26..aa91f08 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigDecimalScaleOperationsTest.java
@@ -21,17 +21,11 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
 import junit.framework.TestCase;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
-@TestTargetClass(BigDecimal.class)
 /**
  * Class:  java.math.BigDecimal
  * Methods: movePointLeft, movePointRight, scale, setScale, unscaledValue * 
@@ -40,12 +34,6 @@
     /**
      * Check the default scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for scale method.",
-        method = "scale",
-        args = {}
-    )
     public void testScaleDefault() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int cScale = 0;
@@ -56,12 +44,6 @@
     /**
      * Check a negative scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for scale method.",
-        method = "scale",
-        args = {}
-    )
     public void testScaleNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = -10;
@@ -73,12 +55,6 @@
     /**
      * Check a positive scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for scale method.",
-        method = "scale",
-        args = {}
-    )
     public void testScalePos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 10;
@@ -90,12 +66,6 @@
     /**
      * Check the zero scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for scale method.",
-        method = "scale",
-        args = {}
-    )
     public void testScaleZero() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 0;
@@ -107,12 +77,6 @@
     /**
      * Check the unscaled value
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "unscaledValue",
-        args = {}
-    )
     public void testUnscaledValue() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 100;
@@ -124,12 +88,6 @@
     /**
      * Set a greater new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setScale method.",
-        method = "setScale",
-        args = {int.class}
-    )
     public void testSetScaleGreater() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 18;
@@ -143,12 +101,6 @@
     /**
      * Set a less new scale; this.scale == 8; newScale == 5.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setScale method.",
-        method = "setScale",
-        args = {int.class}
-    )
     public void testSetScaleLess() {
         String a = "2.345726458768760000E+10";
         int newScale = 5;
@@ -161,12 +113,6 @@
     /**
      * Verify an exception when setting a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setScale method.",
-        method = "setScale",
-        args = {int.class}
-    )
     public void testSetScaleException() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 28;
@@ -183,12 +129,6 @@
     /**
      * Set the same new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setScale method.",
-        method = "setScale",
-        args = {int.class}
-    )
     public void testSetScaleSame() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 18;
@@ -202,12 +142,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundUp() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478139";
@@ -222,12 +156,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundDown() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478138";
@@ -242,12 +170,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundCeiling() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478139";
@@ -262,12 +184,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundFloor() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478138";
@@ -282,12 +198,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundHalfUp() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478138";
@@ -302,12 +212,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundHalfDown() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478138";
@@ -322,12 +226,6 @@
     /**
      * Set a new scale
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleRoundHalfEven() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478138";
@@ -342,12 +240,6 @@
     /**
      * SetScale(int, RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checking missed.",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void testSetScaleIntRoundingMode() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 28;
@@ -363,11 +255,6 @@
     /**
      * Move the decimal point to the left; the shift value is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "movePointLeft",
-        args = {int.class}
-    )
     public void testMovePointLeftPos() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 28;
@@ -382,11 +269,6 @@
     /**
      * Move the decimal point to the left; the shift value is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "movePointLeft",
-        args = {int.class}
-    )
     public void testMovePointLeftNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 28;
@@ -398,11 +280,6 @@
         assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "movePointLeft",
-        args = {int.class}
-    )
     public void testMovePointLeftEx() {
         BigDecimal a = new BigDecimal("12345.6789012345678901234567890123456789");
         BigDecimal res = a.movePointLeft(10);
@@ -423,12 +300,6 @@
     /**
      * Move the decimal point to the right; the shift value is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for movePointRight method.",
-        method = "movePointRight",
-        args = {int.class}
-    )
     public void testMovePointRightPosGreater() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 28;
@@ -443,12 +314,6 @@
     /**
      * Move the decimal point to the right; the shift value is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for movePointRight method.",
-        method = "movePointRight",
-        args = {int.class}
-    )
     public void testMovePointRightPosLess() {
         String a = "1231212478987482988429808779810457634781384756794987";
         String b = "123121247898748298842980877981045763478138475679498700";
@@ -464,12 +329,6 @@
     /**
      * Move the decimal point to the right; the shift value is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for movePointRight method.",
-        method = "movePointRight",
-        args = {int.class}
-    )
     public void testMovePointRightNeg() {
         String a = "1231212478987482988429808779810457634781384756794987";
         int aScale = 28;
@@ -484,12 +343,6 @@
     /**
      * Move the decimal point to the right when the scale overflows
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for movePointRight method.",
-        method = "movePointRight",
-        args = {int.class}
-    )
     public void testMovePointRightException() {
         String a = "12312124789874829887348723648726347429808779810457634781384756794987";
         int aScale = Integer.MAX_VALUE; //2147483647
@@ -503,11 +356,6 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "movePointRight",
-        args = {int.class}
-    )
     public void testMovePointRightEx() {
         BigDecimal a = new BigDecimal("12345.6789012345678901234567890123456789");
         BigDecimal res = a.movePointRight(10);
@@ -524,12 +372,7 @@
         }
     }
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "movePointRight",
-        args = {int.class}
-    )
-    @KnownFailure("Throws OutOfMemoryError instead of ArithmeticException!")
+    // Throws OutOfMemoryError instead of ArithmeticException!
     public void testMovePointRightEx2() {
         BigDecimal a = new BigDecimal("123456789012345678901234567890123456789E25");
         try {
@@ -543,11 +386,6 @@
     /**
      * scaleByPowerOfTen(int n)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "scaleByPowerOfTen",
-        args = {int.class}
-    )
     public void testScaleByPowerOfTenEx() {
         BigDecimal a = new BigDecimal("12345.6789012345678901234567890123456789");
         BigDecimal res = a.movePointRight(10);
@@ -577,12 +415,6 @@
     /**
      * precision()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "precision",
-        args = {}
-    )
     public void testPrecision() {
         String a = "12312124789874829887348723648726347429808779810457634781384756794987";
         int aScale = 14;
@@ -597,12 +429,6 @@
      * check that setScale with a scale greater to the existing scale does not
      * change the value.
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "precision",
-        args = {}
-    )
     public void testSetScale() {
         BigDecimal x1 = new BigDecimal(1.23400);
         BigDecimal x2 = x1.setScale(75);
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAddTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAddTest.java
index e7041fc..e3129cc 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAddTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAddTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Method: add 
@@ -38,12 +33,6 @@
     /**
      * Add two positive numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase1() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -64,12 +53,6 @@
     /**
      * Add two negative numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase2() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -92,12 +75,6 @@
      * The first one is positive and the second is negative.
      * The first one is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase3() {
         byte aBytes[] = {3, 4, 5, 6, 7, 8, 9};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
@@ -120,12 +97,6 @@
      * The first one is negative and the second is positive.
      * The first one is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase4() {
         byte aBytes[] = {3, 4, 5, 6, 7, 8, 9};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
@@ -148,12 +119,6 @@
      * The first is positive and the second is negative.
      * The first is less in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase5() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {3, 4, 5, 6, 7, 8, 9};
@@ -176,12 +141,6 @@
      * The first one is negative and the second is positive.
      * The first one is less in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase6() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {3, 4, 5, 6, 7, 8, 9};
@@ -203,12 +162,6 @@
      * Add two positive numbers of different length.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase7() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -230,12 +183,6 @@
      * Add two positive numbers of different length.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase8() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -255,12 +202,6 @@
      * Add two negative numbers of different length.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase9() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -282,12 +223,6 @@
      * Add two negative numbers of different length.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase10() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -310,12 +245,6 @@
      * The first is positive.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase11() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -338,12 +267,6 @@
      * The first is positive.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase12() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -366,12 +289,6 @@
      * The first is negative.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase13() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -394,12 +311,6 @@
      * The first is negative.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase14() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -420,12 +331,6 @@
     /**
      * Add two equal numbers of different signs
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase15() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
@@ -445,12 +350,6 @@
     /**
      * Add zero to a number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase16() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {0};
@@ -471,12 +370,6 @@
     /**
      * Add a number to zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase17() {
         byte aBytes[] = {0};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
@@ -497,12 +390,6 @@
     /**
      * Add zero to zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase18() {
         byte aBytes[] = {0};
         byte bBytes[] = {0};
@@ -523,12 +410,6 @@
     /**
      * Add ZERO to a number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase19() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
@@ -547,12 +428,6 @@
     /**
      * Add a number to zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase20() {
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
@@ -571,12 +446,6 @@
     /**
      * Add ZERO to ZERO
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase21() {
         byte rBytes[] = {0};
         BigInteger aNumber = BigInteger.ZERO;
@@ -593,12 +462,6 @@
     /**
      * Add ONE to ONE
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase22() {
         byte rBytes[] = {2};
         BigInteger aNumber = BigInteger.ONE;
@@ -615,12 +478,6 @@
     /**
      * Add two numbers so that carry is 1
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for add method.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase23() {
         byte aBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
         byte bBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1};
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAndTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAndTest.java
index 6dc96e9..fb1f9db 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAndTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerAndTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Method: and 
@@ -38,12 +33,6 @@
     /**
      * And for zero and a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroPos() {
         byte aBytes[] = {0};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -64,12 +53,6 @@
     /**
      * And for zero and a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroNeg() {
         byte aBytes[] = {0};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -90,12 +73,6 @@
     /**
      * And for a positive number and zero 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosZero() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {0};
@@ -116,12 +93,6 @@
     /**
      * And for a negative number and zero  
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPos() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {0};
@@ -142,12 +113,6 @@
     /**
      * And for zero and zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroZero() {
         byte aBytes[] = {0};
         byte bBytes[] = {0};
@@ -168,12 +133,6 @@
     /**
      * And for zero and one
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroOne() {
         BigInteger aNumber = BigInteger.ZERO;
         BigInteger bNumber = BigInteger.ONE;
@@ -185,12 +144,6 @@
     /**
      * And for one and one
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testOneOne() {
         BigInteger aNumber = BigInteger.ONE;
         BigInteger bNumber = BigInteger.ONE;
@@ -202,12 +155,6 @@
     /**
      * And for two positive numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -228,12 +175,6 @@
     /**
      * And for two positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -254,12 +195,6 @@
     /**
      * And for two positive numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -280,12 +215,6 @@
     /**
      * And for two negative numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -306,12 +235,6 @@
     /**
      * And for two negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -332,12 +255,6 @@
     /**
      * And for two negative numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -358,12 +275,6 @@
     /**
      * And for two numbers of different signs and the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -384,12 +295,6 @@
     /**
      * And for two numbers of different signs and the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -410,12 +315,6 @@
     /**
      * And for a negative and a positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -436,12 +335,6 @@
     /**
      * And for a negative and a positive numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -462,12 +355,6 @@
     /**
      * And for a positive and a negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -488,12 +375,6 @@
     /**
      * And for a positive and a negative numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -514,12 +395,6 @@
     /**
      * Test for a special case
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testSpecialCase1() {
         byte aBytes[] = {-1, -1, -1, -1};
         byte bBytes[] = {5, -4, -3, -2};
@@ -540,12 +415,6 @@
     /**
      * Test for a special case
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for and method.",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void testSpecialCase2() {
         byte aBytes[] = {-51};
         byte bBytes[] = {-52, -51, -50, -49, -48};
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerCompareTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerCompareTest.java
index ef982cb..bfd1070b 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerCompareTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerCompareTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Methods: abs, compareTo, equals, max, min, negate, signum
@@ -38,12 +33,6 @@
     /**
      * abs() for a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for abs method.",
-        method = "abs",
-        args = {}
-    )
     public void testAbsPositive() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         int aSign = 1;
@@ -61,12 +50,6 @@
     /**
      * abs() for a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for abs method.",
-        method = "abs",
-        args = {}
-    )
     public void testAbsNegative() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         int aSign = -1;
@@ -86,12 +69,6 @@
      * Compare two positive numbers.
      * The first is greater.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToPosPos1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -107,12 +84,6 @@
      * Compare two positive numbers.
      * The first is less.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToPosPos2() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -127,12 +98,6 @@
      * compareTo(BigInteger a).
      * Compare two equal positive numbers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToEqualPos() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -148,12 +113,6 @@
      * Compare two negative numbers.
      * The first is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToNegNeg1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -169,12 +128,6 @@
      * Compare two negative numbers.
      * The first is less  in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareNegNeg2() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -189,12 +142,6 @@
      * compareTo(BigInteger a).
      * Compare two equal negative numbers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToEqualNeg() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -210,12 +157,6 @@
      * Compare two numbers of different signs.
      * The first is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToDiffSigns1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -231,12 +172,6 @@
      * Compare two numbers of different signs.
      * The first is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToDiffSigns2() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -251,12 +186,6 @@
      * compareTo(BigInteger a).
      * Compare a positive number to ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToPosZero() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -269,12 +198,6 @@
      * compareTo(BigInteger a).
      * Compare ZERO to a positive number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToZeroPos() {
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int bSign = 1;
@@ -287,12 +210,6 @@
      * compareTo(BigInteger a).
      * Compare a negative number to ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToNegZero() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = -1;
@@ -305,12 +222,6 @@
      * compareTo(BigInteger a).
      * Compare ZERO to a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToZeroNeg() {
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int bSign = -1;
@@ -323,12 +234,6 @@
      * compareTo(BigInteger a).
      * Compare ZERO to ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for compareTo method.",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void testCompareToZeroZero() {
         BigInteger aNumber = BigInteger.ZERO;
         BigInteger bNumber = BigInteger.ZERO;
@@ -339,12 +244,6 @@
      * equals(Object obj).
      * obj is not a BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsObject() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -356,12 +255,6 @@
     /**
      * equals(null).
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsNull() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -374,12 +267,6 @@
      * obj is a BigInteger.
      * numbers are equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsBigIntegerTrue() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -395,12 +282,6 @@
      * obj is a BigInteger.
      * numbers are not equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for equals method.",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsBigIntegerFalse() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
@@ -415,12 +296,6 @@
      * max(BigInteger val).
      * the first is greater.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigInteger.class}
-    )
     public void testMaxGreater() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
@@ -442,12 +317,6 @@
      * max(BigInteger val).
      * the first is less.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigInteger.class}
-    )
     public void testMaxLess() {
         byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -469,12 +338,6 @@
      * max(BigInteger val).
      * numbers are equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigInteger.class}
-    )
     public void testMaxEqual() {
         byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
@@ -496,12 +359,6 @@
      * max(BigInteger val).
      * max of negative and ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for max method.",
-        method = "max",
-        args = {java.math.BigInteger.class}
-    )
     public void testMaxNegZero() {
         byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = -1;
@@ -521,12 +378,6 @@
      * min(BigInteger val).
      * the first is greater.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mix method.",
-        method = "min",
-        args = {java.math.BigInteger.class}
-    )
     public void testMinGreater() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
@@ -548,12 +399,6 @@
      * min(BigInteger val).
      * the first is less.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mix method.",
-        method = "min",
-        args = {java.math.BigInteger.class}
-    )
     public void testMinLess() {
         byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -575,12 +420,6 @@
      * min(BigInteger val).
      * numbers are equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mix method.",
-        method = "min",
-        args = {java.math.BigInteger.class}
-    )
     public void testMinEqual() {
         byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
         byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
@@ -602,12 +441,6 @@
      * max(BigInteger val).
      * min of positive and ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mix method.",
-        method = "min",
-        args = {java.math.BigInteger.class}
-    )
     public void testMinPosZero() {
         byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -626,12 +459,6 @@
     /**
      * negate() a positive number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for negate method.",
-        method = "negate",
-        args = {}
-    )
     public void testNegatePositive() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -649,12 +476,6 @@
     /**
      * negate() a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for negate method.",
-        method = "negate",
-        args = {}
-    )
     public void testNegateNegative() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = -1;
@@ -672,12 +493,6 @@
     /**
      * negate() ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for negate method.",
-        method = "negate",
-        args = {}
-    )
     public void testNegateZero() {
         byte rBytes[] = {0};
         BigInteger aNumber = BigInteger.ZERO;
@@ -693,12 +508,6 @@
     /**
      * signum() of a positive number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for signum method.",
-        method = "signum",
-        args = {}
-    )
     public void testSignumPositive() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -709,12 +518,6 @@
     /**
      * signum() of a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for signum method.",
-        method = "signum",
-        args = {}
-    )
     public void testSignumNegative() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = -1;
@@ -725,12 +528,6 @@
     /**
      * signum() of ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for signum method.",
-        method = "signum",
-        args = {}
-    )
     public void testSignumZero() {
         BigInteger aNumber = BigInteger.ZERO;
         assertEquals("incorrect sign", 0, aNumber.signum());
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConstructorsTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConstructorsTest.java
index 043d278..1835d68 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConstructorsTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConstructorsTest.java
@@ -21,16 +21,11 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 import java.util.Random;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Constructors: BigInteger(byte[] a), BigInteger(int sign, byte[] a), 
@@ -41,12 +36,6 @@
      * Create a number from an array of bytes.
      * Verify an exception thrown if an array is zero bytes long
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesException() {
         byte aBytes[] = {};
         try {
@@ -61,12 +50,6 @@
      * Create a positive number from an array of bytes.
      * The number fits in an array of integers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesPositive1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -83,12 +66,6 @@
      * Create a positive number from an array of bytes.
      * The number fits in an integer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesPositive2() {
         byte aBytes[] = {12, 56, 100};
         byte rBytes[] = {12, 56, 100};
@@ -105,12 +82,6 @@
      * Create a positive number from an array of bytes.
      * The number of bytes is 4.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesPositive3() {
         byte aBytes[] = {127, 56, 100, -1};
         byte rBytes[] = {127, 56, 100, -1};
@@ -127,12 +98,6 @@
      * Create a positive number from an array of bytes.
      * The number of bytes is multiple of 4.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesPositive() {
         byte aBytes[] = {127, 56, 100, -1, 14, 75, -24, -100};
         byte rBytes[] = {127, 56, 100, -1, 14, 75, -24, -100};
@@ -149,12 +114,6 @@
      * Create a negative number from an array of bytes.
      * The number fits in an array of integers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesNegative1() {
         byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         byte rBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
@@ -171,12 +130,6 @@
      * Create a negative number from an array of bytes.
      * The number fits in an integer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesNegative2() {
         byte aBytes[] = {-12, 56, 100};
         byte rBytes[] = {-12, 56, 100};
@@ -193,12 +146,6 @@
      * Create a negative number from an array of bytes.
      * The number of bytes is 4.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesNegative3() {
         byte aBytes[] = {-128, -12, 56, 100};
         byte rBytes[] = {-128, -12, 56, 100};
@@ -215,12 +162,6 @@
      * Create a negative number from an array of bytes.
      * The number of bytes is multiple of 4.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesNegative4() {
         byte aBytes[] = {-128, -12, 56, 100, -13, 56, 93, -78};
         byte rBytes[] = {-128, -12, 56, 100, -13, 56, 93, -78};
@@ -236,12 +177,6 @@
     /**
      * Create a zero number from an array of zero bytes.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(byte[]) constructor.",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void testConstructorBytesZero() {
         byte aBytes[] = {0, 0, 0, -0, +0, 0, -0};
         byte rBytes[] = {0};
@@ -258,12 +193,6 @@
      * Create a number from a sign and an array of bytes.
      * Verify an exception thrown if a sign has improper value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesException1() {
         byte aBytes[] = {123, 45, -3, -76};
         int aSign = 3;
@@ -279,12 +208,6 @@
      * Create a number from a sign and an array of bytes.
      * Verify an exception thrown if the array contains non-zero bytes while the sign is 0. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesException2() {
         byte aBytes[] = {123, 45, -3, -76};
         int aSign = 0;
@@ -301,12 +224,6 @@
      * The number fits in an array of integers.
      * The most significant byte is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
         int aSign = 1;
@@ -325,12 +242,6 @@
      * The number fits in an array of integers.
      * The most significant byte is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive2() {
         byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
         int aSign = 1;
@@ -348,12 +259,6 @@
      * Create a positive number from a sign and an array of bytes.
      * The number fits in an integer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive3() {
         byte aBytes[] = {-12, 56, 100};
         int aSign = 1;
@@ -372,12 +277,6 @@
      * The number of bytes is 4.
      * The most significant byte is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive4() {
         byte aBytes[] = {127, 56, 100, -2};
         int aSign = 1;
@@ -396,12 +295,6 @@
      * The number of bytes is 4.
      * The most significant byte is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive5() {
         byte aBytes[] = {-127, 56, 100, -2};
         int aSign = 1;
@@ -420,12 +313,6 @@
      * The number of bytes is multiple of 4.
      * The most significant byte is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive6() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
         int aSign = 1;
@@ -444,12 +331,6 @@
      * The number of bytes is multiple of 4.
      * The most significant byte is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesPositive7() {
         byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
         int aSign = 1;
@@ -468,12 +349,6 @@
      * The number fits in an array of integers.
      * The most significant byte is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
         int aSign = -1;
@@ -492,12 +367,6 @@
      * The number fits in an array of integers.
      * The most significant byte is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative2() {
         byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
         int aSign = -1;
@@ -515,12 +384,6 @@
      * Create a negative number from a sign and an array of bytes.
      * The number fits in an integer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative3() {
         byte aBytes[] = {-12, 56, 100};
         int aSign = -1;
@@ -539,12 +402,6 @@
      * The number of bytes is 4.
      * The most significant byte is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative4() {
         byte aBytes[] = {127, 56, 100, -2};
         int aSign = -1;
@@ -563,12 +420,6 @@
      * The number of bytes is 4.
      * The most significant byte is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative5() {
         byte aBytes[] = {-127, 56, 100, -2};
         int aSign = -1;
@@ -587,12 +438,6 @@
      * The number of bytes is multiple of 4.
      * The most significant byte is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative6() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
         int aSign = -1;
@@ -611,12 +456,6 @@
      * The number of bytes is multiple of 4.
      * The most significant byte is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesNegative7() {
         byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
         int aSign = -1;
@@ -634,12 +473,6 @@
      * Create a zero number from a sign and an array of zero bytes.
      * The sign is -1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesZero1() {
         byte aBytes[] = {-0, 0, +0, 0, 0, 00, 000};
         int aSign = -1;
@@ -657,12 +490,6 @@
      * Create a zero number from a sign and an array of zero bytes.
      * The sign is 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesZero2() {
         byte aBytes[] = {-0, 0, +0, 0, 0, 00, 000};
         int aSign = 0;
@@ -680,12 +507,6 @@
      * Create a zero number from a sign and an array of zero bytes.
      * The sign is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesZero3() {
         byte aBytes[] = {-0, 0, +0, 0, 0, 00, 000};
         int aSign = 1;
@@ -703,12 +524,6 @@
      * Create a zero number from a sign and an array of zero length.
      * The sign is -1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesZeroNull1() {
         byte aBytes[] = {};
         int aSign = -1;
@@ -726,12 +541,6 @@
      * Create a zero number from a sign and an array of zero length.
      * The sign is 0.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesZeroNull2() {
         byte aBytes[] = {};
         int aSign = 0;
@@ -749,12 +558,6 @@
      * Create a zero number from a sign and an array of zero length.
      * The sign is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(int, byte[]) constructor.",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void testConstructorSignBytesZeroNull3() {
         byte aBytes[] = {};
         int aSign = 1;
@@ -772,12 +575,6 @@
      * Create a number from a string value and radix.
      * Verify an exception thrown if a radix is out of range
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringException1() {
         String value = "9234853876401";
         int radix = 45;
@@ -793,12 +590,6 @@
      * Create a number from a string value and radix.
      * Verify an exception thrown if the string starts with a space.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringException2() {
         String value = "   9234853876401";
         int radix = 10;
@@ -813,12 +604,6 @@
      * Create a number from a string value and radix.
      * Verify an exception thrown if the string contains improper characters.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringException3() {
         String value = "92348$*#78987";
         int radix = 34;
@@ -833,12 +618,6 @@
      * Create a number from a string value and radix.
      * Verify an exception thrown if some digits are greater than radix.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringException4() {
         String value = "98zv765hdsaiy";
         int radix = 20;
@@ -852,12 +631,6 @@
     /**
      * Create a positive number from a string value and radix 2.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix2() {
         String value = "10101010101010101";
         int radix = 2;
@@ -874,12 +647,6 @@
     /**
      * Create a positive number from a string value and radix 8.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix8() {
         String value = "76356237071623450";
         int radix = 8;
@@ -896,12 +663,6 @@
     /**
      * Create a positive number from a string value and radix 10.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix10() {
         String value = "987328901348934898";
         int radix = 10;
@@ -918,12 +679,6 @@
     /**
      * Create a positive number from a string value and radix 16.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix16() {
         String value = "fe2340a8b5ce790";
         int radix = 16;
@@ -940,12 +695,6 @@
     /**
      * Create a positive number from a string value and radix 36.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix36() {
         String value = "skdjgocvhdjfkl20jndjkf347ejg457";
         int radix = 36;
@@ -962,12 +711,6 @@
     /**
      * Create a negative number from a string value and radix 10.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix10Negative() {
         String value = "-234871376037";
         int radix = 36;
@@ -984,12 +727,6 @@
     /**
      * Create a zero number from a string value and radix 36.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String, int) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void testConstructorStringRadix10Zero() {
         String value = "-00000000000000";
         int radix = 10;
@@ -1006,12 +743,6 @@
     /**
      * Create a random number of 75 bits length.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "IllegalArgumentException checking missed for negative number of bits.",
-        method = "BigInteger",
-        args = {int.class, java.util.Random.class}
-    )
     public void testConstructorRandom() {
         int bitLen = 75;
         Random rnd = new Random();
@@ -1022,12 +753,6 @@
     /**
      * Create a prime number of 25 bits length.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed for incorrect bitLength parameter.",
-        method = "BigInteger",
-        args = {int.class, int.class, java.util.Random.class}
-    )
     public void testConstructorPrime() {
         int bitLen = 25;
         Random rnd = new Random();
@@ -1058,12 +783,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrString1() {
         String s = "0";
         BigInteger bi_s = new BigInteger(s);
@@ -1074,12 +793,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrString2() {
         String s = "-2147483648";
         BigInteger bi_s = new BigInteger(s);
@@ -1091,12 +804,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrString3() {
         String s = "2147483647";
         BigInteger bi_s = new BigInteger(s);
@@ -1108,12 +815,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrStringExc1() {
         try {
             new BigInteger("01234 56");
@@ -1125,12 +826,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrStringExc2() {
         try {
             new BigInteger("1234#56");
@@ -1142,12 +837,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrStringExc3() {
         try {
             new BigInteger("1234.56");
@@ -1159,12 +848,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for BigInteger(String) constructor.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstrStringExc4() {
         try {
             new BigInteger("1E+1");
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConvertTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConvertTest.java
index aaef132..c0f17b1 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConvertTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerConvertTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Methods: intValue, longValue, toByteArray(), valueOf(long val),
@@ -39,12 +34,6 @@
     /**
      * Return the double value of ZERO. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueZero() {
         String a = "0";
         double result = 0.0;
@@ -56,12 +45,6 @@
      * Convert a positive number to a double value. 
      * The number's length is less than 64 bits.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePositive1() {
         String a = "27467238945";
         double result = 2.7467238945E10;
@@ -73,12 +56,6 @@
      * Convert a positive number to a double value. 
      * The number's bit length is inside [63, 1024].
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePositive2() {
         String a = "2746723894572364578265426346273456972";
         double result = 2.7467238945723645E36;
@@ -90,12 +67,6 @@
      * Convert a negative number to a double value. 
      * The number's bit length is less than 64 bits.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegative1() {
         String a = "-27467238945";
         double result = -2.7467238945E10;
@@ -107,12 +78,6 @@
      * Convert a negative number to a double value. 
      * The number's bit length is inside [63, 1024].
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegative2() {
         String a = "-2746723894572364578265426346273456972";
         double result = -2.7467238945723645E36;
@@ -125,12 +90,6 @@
      * Rounding is needed.
      * The rounding bit is 1 and the next bit to the left is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePosRounded1() {
         byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
         int aSign = 1;
@@ -145,12 +104,6 @@
      * The rounding bit is 1 and the next bit to the left is 0
      * but some of dropped bits are 1s.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePosRounded2() {
         byte[] a = {-128, 1, 2, 3, 4, 5, 36, 23, 1, -3, -5};
         int aSign = 1;
@@ -162,12 +115,6 @@
      * Convert a positive number to a double value. 
      * Rounding is NOT needed.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePosNotRounded() {
         byte[] a = {-128, 1, 2, 3, 4, 5, -128, 23, 1, -3, -5};
         int aSign = 1;
@@ -180,12 +127,6 @@
      * Convert a positive number to a double value. 
      * Rounding is needed.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegRounded1() {
         byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
         int aSign = -1;
@@ -200,12 +141,6 @@
      * The rounding bit is 1 and the next bit to the left is 0
      * but some of dropped bits are 1s.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegRounded2() {
         byte[] a = {-128, 1, 2, 3, 4, 5, 36, 23, 1, -3, -5};
         int aSign = -1;
@@ -218,12 +153,6 @@
      * Convert a positive number to a double value. 
      * Rounding is NOT needed.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegNotRounded() {
         byte[] a = {-128, 1, 2, 3, 4, 5, -128, 23, 1, -3, -5};
         int aSign = -1;
@@ -238,12 +167,6 @@
      * The rounding bit is 0.
      * The result is Double.MAX_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePosMaxValue() {
         byte[] a = {0, -1, -1, -1, -1, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -264,12 +187,6 @@
      * The exponent is 1023 and the mantissa is all 1s.
      * The result is -Double.MAX_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegMaxValue() {
         byte[] a = {0, -1, -1, -1, -1, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -291,12 +208,6 @@
      * The rounding bit is 1.
      * The result is Double.POSITIVE_INFINITY.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePositiveInfinity1() {
         byte[] a = {-1, -1, -1, -1, -1, -1, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -316,12 +227,6 @@
      * Convert a positive number to a double value. 
      * The number's bit length is greater than 1024.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePositiveInfinity2() {
         String a = "2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
         double aNumber = new BigInteger(a).doubleValue();
@@ -332,12 +237,6 @@
      * Convert a negative number to a double value. 
      * The number's bit length is greater than 1024.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegativeInfinity1() {
         String a = "-2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
         double aNumber = new BigInteger(a).doubleValue();
@@ -350,12 +249,6 @@
      * The rounding bit is 0.
      * The result is Double.NEGATIVE_INFINITY.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegativeInfinity2() {
         byte[] a = {-1, -1, -1, -1, -1, -1, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -376,12 +269,6 @@
      * The exponent is 1023 and the mantissa is all 0s
      * but the 54th bit (implicit) is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValuePosMantissaIsZero() {
         byte[] a = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -403,12 +290,6 @@
      * The exponent is 1023 and the mantissa is all 0s
      * but the 54th bit (implicit) is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for doubleValue method.",
-        method = "doubleValue",
-        args = {}
-    )
     public void testDoubleValueNegMantissaIsZero() {
         byte[] a = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -427,12 +308,6 @@
     /**
      * Return the float value of ZERO. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueZero() {
         String a = "0";
         float result = 0.0f;
@@ -444,12 +319,6 @@
      * Convert a positive number to a float value. 
      * The number's length is less than 32 bits.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePositive1() {
         String a = "27467238";
         float result = 2.7467238E7f;
@@ -461,12 +330,6 @@
      * Convert a positive number to a float value. 
      * The number's bit length is inside [32, 127].
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePositive2() {
         String a = "27467238945723645782";
         float result = 2.7467239E19f;
@@ -478,12 +341,6 @@
      * Convert a negative number to a float value. 
      * The number's bit length is less than 32 bits.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegative1() {
         String a = "-27467238";
         float result = -2.7467238E7f;
@@ -495,12 +352,6 @@
      * Convert a negative number to a doufloatble value. 
      * The number's bit length is inside [63, 1024].
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegative2() {
         String a = "-27467238945723645782";
         float result = -2.7467239E19f;
@@ -513,12 +364,6 @@
      * Rounding is needed.
      * The rounding bit is 1 and the next bit to the left is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePosRounded1() {
         byte[] a = {-128, 1, -1, -4, 4, 5, 60, 23, 1, -3, -5};
         int aSign = 1;
@@ -533,12 +378,6 @@
      * The rounding bit is 1 and the next bit to the left is 0
      * but some of dropped bits are 1s.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePosRounded2() {
         byte[] a = {-128, 1, 2, -128, 4, 5, 60, 23, 1, -3, -5};
         int aSign = 1;
@@ -550,12 +389,6 @@
      * Convert a positive number to a float value. 
      * Rounding is NOT needed.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePosNotRounded() {
         byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
         int aSign = 1;
@@ -568,12 +401,6 @@
      * Convert a positive number to a float value. 
      * Rounding is needed.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegRounded1() {
         byte[] a = {-128, 1, -1, -4, 4, 5, 60, 23, 1, -3, -5};
         int aSign = -1;
@@ -588,12 +415,6 @@
      * The rounding bit is 1 and the next bit to the left is 0
      * but some of dropped bits are 1s.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegRounded2() {
         byte[] a = {-128, 1, 2, -128, 4, 5, 60, 23, 1, -3, -5};
         int aSign = -1;
@@ -606,12 +427,6 @@
      * Convert a positive number to a float value. 
      * Rounding is NOT needed.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegNotRounded() {
         byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
         int aSign = -1;
@@ -626,12 +441,6 @@
      * The rounding bit is 0.
      * The result is Float.MAX_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePosMaxValue() {
         byte[] a = {0, -1, -1, -1, 0, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1};
         int aSign = 1;
@@ -645,12 +454,6 @@
      * The rounding bit is 0.
      * The result is -Float.MAX_VALUE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegMaxValue() {
         byte[] a = {0, -1, -1, -1, 0, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1};
         int aSign = -1;
@@ -664,12 +467,6 @@
      * The rounding bit is 1.
      * The result is Float.POSITIVE_INFINITY.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePositiveInfinity1() {
         byte[] a = {0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
         int aSign = 1;
@@ -681,12 +478,6 @@
      * Convert a positive number to a float value. 
      * The number's bit length is greater than 127.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePositiveInfinity2() {
         String a = "2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
         float aNumber = new BigInteger(a).floatValue();
@@ -697,12 +488,6 @@
      * Convert a negative number to a float value. 
      * The number's bit length is greater than 127.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegativeInfinity1() {
         String a = "-2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
         float aNumber = new BigInteger(a).floatValue();
@@ -715,12 +500,6 @@
      * The rounding bit is 0.
      * The result is Float.NEGATIVE_INFINITY.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegativeInfinity2() {
         byte[] a = {0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
         int aSign = -1;
@@ -733,12 +512,6 @@
      * The exponent is 1023 and the mantissa is all 0s
      * but the 54th bit (implicit) is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValuePosMantissaIsZero() {
         byte[] a = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = 1;
@@ -752,12 +525,6 @@
      * The exponent is 1023 and the mantissa is all 0s
      * but the 54th bit (implicit) is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueNegMantissaIsZero() {
         byte[] a = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = -1;
@@ -769,12 +536,6 @@
      * Convert a negative number to a float value. 
      * The number's bit length is less than 32 bits.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for floatValue method.",
-        method = "floatValue",
-        args = {}
-    )
     public void testFloatValueBug2482() {
         String a = "2147483649";
         float result = 2.14748365E9f;
@@ -786,12 +547,6 @@
      * Convert a positive BigInteger to an integer value. 
      * The low digit is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValuePositive1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3};
         int resInt = 1496144643;
@@ -803,12 +558,6 @@
      * Convert a positive BigInteger to an integer value. 
      * The low digit is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValuePositive2() {
         byte aBytes[] = {12, 56, 100};
         int resInt = 800868;
@@ -820,12 +569,6 @@
      * Convert a positive BigInteger to an integer value. 
      * The low digit is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValuePositive3() {
         byte aBytes[] = {56, 13, 78, -12, -5, 56, 100};
         int sign = 1;
@@ -838,12 +581,6 @@
      * Convert a negative BigInteger to an integer value.
      * The low digit is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValueNegative1() {
         byte aBytes[] = {12, 56, 100, -2, -76, -128, 45, 91, 3};
         int sign = -1;
@@ -856,12 +593,6 @@
      * Convert a negative BigInteger to an integer value.
      * The low digit is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValueNegative2() {
         byte aBytes[] = {-12, 56, 100};
         int result = -771996;
@@ -873,12 +604,6 @@
      * Convert a negative BigInteger to an integer value. 
      * The low digit is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for intValue method.",
-        method = "intValue",
-        args = {}
-    )
     public void testIntValueNegative3() {
         byte aBytes[] = {12, 56, 100, -2, -76, 127, 45, 91, 3};
         int sign = -1;
@@ -891,12 +616,6 @@
      * Convert a BigInteger to a positive long value
      * The BigInteger is longer than int.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for longValue method.",
-        method = "longValue",
-        args = {}
-    )
     public void testLongValuePositive1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, 120, -34, -12, 45, 98};
         long result = 3268209772258930018L;
@@ -908,12 +627,6 @@
      * Convert a number to a positive long value
      * The number fits in a long.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for longValue method.",
-        method = "longValue",
-        args = {}
-    )
     public void testLongValuePositive2() {
         byte aBytes[] = {12, 56, 100, 18, -105, 34, -18, 45};
         long result = 880563758158769709L;
@@ -925,12 +638,6 @@
      * Convert a number to a negative long value
      * The BigInteger is longer than int.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for longValue method.",
-        method = "longValue",
-        args = {}
-    )
     public void testLongValueNegative1() {
         byte aBytes[] = {12, -1, 100, -2, -76, -128, 45, 91, 3};
         long result = -43630045168837885L;
@@ -942,12 +649,6 @@
      * Convert a number to a negative long value
      * The number fits in a long.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for longValue method.",
-        method = "longValue",
-        args = {}
-    )
     public void testLongValueNegative2() {
         byte aBytes[] = {-12, 56, 100, 45, -101, 45, 98};
         long result = -3315696807498398L;
@@ -958,12 +659,6 @@
     /**
      * valueOf (long val): convert Integer.MAX_VALUE to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfIntegerMax() {
         long longVal = Integer.MAX_VALUE;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -979,12 +674,6 @@
     /**
      * valueOf (long val): convert Integer.MIN_VALUE to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfIntegerMin() {
         long longVal = Integer.MIN_VALUE;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1000,12 +689,6 @@
     /**
      * valueOf (long val): convert Long.MAX_VALUE to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongMax() {
         long longVal = Long.MAX_VALUE;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1021,12 +704,6 @@
     /**
      * valueOf (long val): convert Long.MIN_VALUE to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongMin() {
         long longVal = Long.MIN_VALUE;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1042,12 +719,6 @@
     /**
      * valueOf (long val): convert a positive long value to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongPositive1() {
         long longVal = 268209772258930018L;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1064,12 +735,6 @@
      * valueOf (long val): convert a positive long value to a BigInteger.
      * The long value fits in integer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongPositive2() {
         long longVal = 58930018L;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1085,12 +750,6 @@
     /**
      * valueOf (long val): convert a negative long value to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongNegative1() {
         long longVal = -268209772258930018L;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1107,12 +766,6 @@
      * valueOf (long val): convert a negative long value to a BigInteger.
      * The long value fits in integer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongNegative2() {
         long longVal = -58930018L;
         BigInteger aNumber = BigInteger.valueOf(longVal);
@@ -1127,12 +780,6 @@
     /**
      * valueOf (long val): convert a zero long value to a BigInteger.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for valueOf method.",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void testValueOfLongZero() {
         long longVal = 0L;
         BigInteger aNumber = BigInteger.valueOf(longVal);
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerDivideTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerDivideTest.java
index f46a6ec..b3fec51 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerDivideTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerDivideTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Methods: divide, remainder, mod, and divideAndRemainder 
@@ -38,12 +33,6 @@
     /**
      * Divide by zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase1() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {0};
@@ -62,12 +51,6 @@
     /**
      * Divide by ZERO
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase2() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         int aSign = 1;
@@ -84,12 +67,6 @@
     /**
      * Divide two equal positive numbers
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase3() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
         byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
@@ -110,12 +87,6 @@
     /**
      * Divide two equal in absolute value numbers of different signs.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase4() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
         byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
@@ -137,12 +108,6 @@
      * Divide two numbers of different length and different signs.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase5() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
         byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 1, 2, 3, 4, 5};
@@ -164,12 +129,6 @@
      * Divide two positive numbers of the same length.
      * The second is greater.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase6() {
         byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127};
         byte bBytes[] = {15, 100, 56, 7, 98, -1, 39, -128, 127};
@@ -190,12 +149,6 @@
     /**
      * Divide two positive numbers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase7() {
         byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
         byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
@@ -216,12 +169,6 @@
     /**
      * Divide a positive number by a negative one.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase8() {
         byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
         byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
@@ -242,12 +189,6 @@
     /**
      * Divide a negative number by a positive one.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase9() {
         byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
         byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
@@ -268,12 +209,6 @@
     /**
      * Divide two negative numbers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase10() {
         byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
         byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
@@ -294,12 +229,6 @@
     /**
      * Divide zero by a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase11() {
         byte aBytes[] = {0};
         byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
@@ -320,12 +249,6 @@
     /**
      * Divide ZERO by a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase12() {
         byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
         int bSign = -1;        
@@ -344,12 +267,6 @@
     /**
      * Divide a positive number by ONE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase13() {
         byte aBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
         int aSign = 1;        
@@ -368,12 +285,6 @@
     /**
      * Divide ONE by ONE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase14() {
         byte rBytes[] = {1};
         BigInteger aNumber = BigInteger.ONE;
@@ -390,12 +301,6 @@
     /**
      * Verifies the case when borrow != 0 in the private divide method.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testDivisionKnuth1() {
         byte aBytes[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {-3, -3, -3, -3};
@@ -416,12 +321,6 @@
     /**
      * Verifies the case when the divisor is already normalized.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testDivisionKnuthIsNormalized() {
         byte aBytes[] = {-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
         byte bBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1};
@@ -443,12 +342,6 @@
      * Verifies the case when the first digits of the dividend
      * and divisor equal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testDivisionKnuthFirstDigitsEqual() {
         byte aBytes[] = {2, -3, -4, -5, -1, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
         byte bBytes[] = {2, -3, -4, -5, -1, -1, -1, -1};
@@ -469,12 +362,6 @@
     /**
      * Divide the number of one digit by the number of one digit 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testDivisionKnuthOneDigitByOneDigit() {
         byte aBytes[] = {113, -83, 123, -5};
         byte bBytes[] = {2, -3, -4, -5};
@@ -495,12 +382,6 @@
     /**
      * Divide the number of multi digits by the number of one digit 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for divide method.",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void testDivisionKnuthMultiDigitsByOneDigit() {
         byte aBytes[] = {113, -83, 123, -5, 18, -34, 67, 39, -29};
         byte bBytes[] = {2, -3, -4, -5};
@@ -521,12 +402,6 @@
     /**
      * Remainder of division by zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase15() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {0};
@@ -545,12 +420,6 @@
     /**
      * Remainder of division of equal numbers
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase16() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
         byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
@@ -571,12 +440,6 @@
     /**
      * Remainder of division of two positive numbers
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase17() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
@@ -597,12 +460,6 @@
     /**
      * Remainder of division of two negative numbers
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase18() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
@@ -624,12 +481,6 @@
      * Remainder of division of two numbers of different signs.
      * The first is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase19() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
@@ -651,12 +502,6 @@
      * Remainder of division of two numbers of different signs.
      * The first is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase20() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
@@ -677,12 +522,6 @@
     /**
      * Tests the step D6 from the Knuth algorithm
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testRemainderKnuth1() {
         byte aBytes[] = {-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1};
         byte bBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
@@ -703,12 +542,6 @@
     /**
      * Divide the number of one digit by the number of one digit 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testRemainderKnuthOneDigitByOneDigit() {
         byte aBytes[] = {113, -83, 123, -5};
         byte bBytes[] = {2, -3, -4, -50};
@@ -729,12 +562,6 @@
     /**
      * Divide the number of multi digits by the number of one digit 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for remainder method.",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testRemainderKnuthMultiDigitsByOneDigit() {
         byte aBytes[] = {113, -83, 123, -5, 18, -34, 67, 39, -29};
         byte bBytes[] = {2, -3, -4, -50};
@@ -756,11 +583,6 @@
      * divideAndRemainder of two numbers of different signs.
      * The first is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "divideAndRemainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase21() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
@@ -793,11 +615,6 @@
     /**
      * divideAndRemainder of division by zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        method = "divideAndRemainder",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase21byZero() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {0};
@@ -816,12 +633,6 @@
     /**
      * mod when modulus is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mod method.",
-        method = "mod",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase22() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {1, 30, 40, 56, -1, 45};
@@ -840,12 +651,6 @@
     /**
      * mod when a divisor is positive
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mod method.",
-        method = "mod",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase23() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
@@ -866,12 +671,6 @@
     /**
      * mod when a divisor is negative
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for mod method.",
-        method = "mod",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase24() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
         byte bBytes[] = {27, -15, 65, 39, 100};
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerHashCodeTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerHashCodeTest.java
index d351fa8..a63a514 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerHashCodeTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerHashCodeTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Method: hashCode()
@@ -38,12 +33,6 @@
     /**
      * Test hash codes for the same object
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for hashCode method.",
-        method = "hashCode",
-        args = {}
-    )
     public void testSameObject() {
         String value1 = "12378246728727834290276457386374882976782849";
         String value2 = "-5634562095872038262928728727834290276457386374882976782849";
@@ -62,12 +51,6 @@
     /**
      * Test hash codes for equal objects.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for hashCode method.",
-        method = "hashCode",
-        args = {}
-    )
     public void testEqualObjects() {
         String value1 = "12378246728727834290276457386374882976782849";
         String value2 = "12378246728727834290276457386374882976782849";
@@ -84,12 +67,6 @@
      * Test hash codes for unequal objects.
      * The codes are unequal.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for hashCode method.",
-        method = "hashCode",
-        args = {}
-    )
     public void testUnequalObjectsUnequal() {
         String value1 = "12378246728727834290276457386374882976782849";
         String value2 = "-5634562095872038262928728727834290276457386374882976782849";
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerModPowTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerModPowTest.java
index 7142f16..1c5cba3 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerModPowTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerModPowTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Methods: modPow, modInverse, and gcd 
@@ -38,12 +33,6 @@
     /**
      * modPow: non-positive modulus
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modPow method.",
-        method = "modPow",
-        args = {java.math.BigInteger.class, java.math.BigInteger.class}
-    )
     public void testModPowException() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte eBytes[] = {1, 2, 3, 4, 5};
@@ -65,12 +54,6 @@
     /**
      * modPow: positive exponent
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modPow method.",
-        method = "modPow",
-        args = {java.math.BigInteger.class, java.math.BigInteger.class}
-    )
     public void testModPowPosExp() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75, 48, -7};
         byte eBytes[] = {27, -15, 65, 39};
@@ -94,12 +77,6 @@
     /**
      * modPow: negative exponent
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modPow method.",
-        method = "modPow",
-        args = {java.math.BigInteger.class, java.math.BigInteger.class}
-    )
     public void testModPowNegExp() {
         byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75, 48, -7};
         byte eBytes[] = {27, -15, 65, 39};
@@ -123,12 +100,6 @@
     /**
      * modInverse: non-positive modulus
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modInverse method.",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void testmodInverseException() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         byte mBytes[] = {1, 2, 3};
@@ -147,12 +118,6 @@
     /**
      * modInverse: non-invertible number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modInverse method.",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void testmodInverseNonInvertible() {
         byte aBytes[] = {-15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
         byte mBytes[] = {-12, 1, 0, 0, 0, 23, 44, 55, 66};
@@ -171,12 +136,6 @@
     /**
      * modInverse: positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modInverse method.",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void testmodInversePos1() {
         byte aBytes[] = {24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
         byte mBytes[] = {122, 45, 36, 100, 122, 45};
@@ -197,12 +156,6 @@
     /**
      * modInverse: positive number (another case: a < 0)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modInverse method.",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void testmodInversePos2() {
         byte aBytes[] = {15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
         byte mBytes[] = {2, 122, 45, 36, 100};
@@ -223,12 +176,6 @@
     /**
      * modInverse: negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modInverse method.",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void testmodInverseNeg1() {
         byte aBytes[] = {15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
         byte mBytes[] = {2, 122, 45, 36, 100};
@@ -249,12 +196,6 @@
     /**
      * modInverse: negative number (another case: x < 0)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for modInverse method.",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void testmodInverseNeg2() {
         byte aBytes[] = {-15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
         byte mBytes[] = {122, 2, 4, 122, 2, 4};
@@ -273,12 +214,6 @@
     /**
      * gcd: the second number is zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for gcd method.",
-        method = "gcd",
-        args = {java.math.BigInteger.class}
-    )
     public void testGcdSecondZero() {
         byte aBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
         byte bBytes[] = {0};
@@ -299,12 +234,6 @@
     /**
      * gcd: the first number is zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for gcd method.",
-        method = "gcd",
-        args = {java.math.BigInteger.class}
-    )
     public void testGcdFirstZero() {
         byte aBytes[] = {0};
         byte bBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
@@ -325,12 +254,6 @@
     /**
      * gcd: the first number is ZERO
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for gcd method.",
-        method = "gcd",
-        args = {java.math.BigInteger.class}
-    )
     public void testGcdFirstZERO() {
         byte bBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
         int bSign = 1;
@@ -349,12 +272,6 @@
     /**
      * gcd: both numbers are zeros
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for gcd method.",
-        method = "gcd",
-        args = {java.math.BigInteger.class}
-    )
     public void testGcdBothZeros() {
         byte rBytes[] = {0};
         BigInteger aNumber = new BigInteger("0");
@@ -370,12 +287,6 @@
     /**
      * gcd: the first number is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for gcd method.",
-        method = "gcd",
-        args = {java.math.BigInteger.class}
-    )
     public void testGcdFirstLonger() {
         byte aBytes[] = {-15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
         byte bBytes[] = {-12, 1, 0, 0, 0, 23, 44, 55, 66};
@@ -396,12 +307,6 @@
     /**
      * gcd: the second number is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for gcd method.",
-        method = "gcd",
-        args = {java.math.BigInteger.class}
-    )
     public void testGcdSecondLonger() {
         byte aBytes[] = {-12, 1, 0, 0, 0, 23, 44, 55, 66};
         byte bBytes[] = {-15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerMultiplyTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerMultiplyTest.java
index 59ff3c6..e016294 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerMultiplyTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerMultiplyTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Method: multiply 
@@ -38,12 +33,6 @@
     /**
      * Multiply two negative numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase1() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -65,12 +54,6 @@
      * Multiply two numbers of the same length and different signs.
      * The first is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase2() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -92,12 +75,6 @@
      * Multiply two positive numbers of different length.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase3() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -120,12 +97,6 @@
      * Multiply two positive numbers of different length.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase4() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
@@ -149,12 +120,6 @@
      * The first is positive.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase5() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -178,12 +143,6 @@
      * The first is positive.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase6() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
@@ -205,12 +164,6 @@
     /**
      * Multiply a number by zero.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase7() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
         byte bBytes[] = {0};
@@ -231,12 +184,6 @@
     /**
      * Multiply a number by ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase8() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
         int aSign = 1;
@@ -255,12 +202,6 @@
     /**
      * Multiply a positive number by ONE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase9() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
         int aSign = 1;
@@ -279,12 +220,6 @@
     /**
      * Multiply a negative number by ONE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase10() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
         int aSign = -1;
@@ -303,12 +238,6 @@
     /**
      * Multiply two numbers of 4 bytes length.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testIntbyInt1() {
         byte aBytes[] = {10, 20, 30, 40};
         byte bBytes[] = {1, 2, 3, 4};
@@ -329,12 +258,6 @@
     /**
      * Multiply two numbers of 4 bytes length.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for multiply method.",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void testIntbyInt2() {
         byte aBytes[] = {-1, -1, -1, -1};
         byte bBytes[] = {-1, -1, -1, -1};
@@ -355,12 +278,6 @@
     /**
      * Negative exponent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for pow method.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowException() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
         int aSign = 1;
@@ -377,12 +294,6 @@
     /**
      * Exponentiation of a negative number to an odd exponent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for pow method.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowNegativeNumToOddExp() {
         byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
         int aSign = -1;
@@ -404,12 +315,6 @@
     /**
      * Exponentiation of a negative number to an even exponent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for pow method.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowNegativeNumToEvenExp() {
         byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
         int aSign = -1;
@@ -430,12 +335,6 @@
     /**
      * Exponentiation of a negative number to zero exponent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for pow method.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowNegativeNumToZeroExp() {
         byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
         int aSign = -1;
@@ -454,12 +353,6 @@
     /**
      * Exponentiation of a positive number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for pow method.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowPositiveNum() {
         byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
         int aSign = 1;
@@ -481,12 +374,6 @@
     /**
      * Exponentiation of a negative number to zero exponent.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for pow method.",
-        method = "pow",
-        args = {int.class}
-    )
     public void testPowPositiveNumToZeroExp() {
         byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
         int aSign = 1;
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerNotTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerNotTest.java
index 6ca350b..c88c412 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerNotTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerNotTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Methods: and, andNot
@@ -38,12 +33,6 @@
     /**
      * andNot for two positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for andNot method.",
-        method = "andNot",
-        args = {java.math.BigInteger.class}
-    )
     public void testAndNotPosPosFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -64,12 +53,6 @@
     /**
      * andNot for two positive numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for andNot method.",
-        method = "andNot",
-        args = {java.math.BigInteger.class}
-    )
     public void testAndNotPosPosFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -90,12 +73,6 @@
     /**
      * andNot for two negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for andNot method.",
-        method = "andNot",
-        args = {java.math.BigInteger.class}
-    )
     public void testAndNotNegNegFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -116,12 +93,6 @@
     /**
      * andNot for a negative and a positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for andNot method.",
-        method = "andNot",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -142,12 +113,6 @@
     /**
      * Not for ZERO 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for not method.",
-        method = "not",
-        args = {}
-    )
     public void testNotZero() {
         byte rBytes[] = {-1};
         BigInteger aNumber = BigInteger.ZERO;
@@ -163,12 +128,6 @@
     /**
      * Not for ONE
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for not method.",
-        method = "not",
-        args = {}
-    )
     public void testNotOne() {
         byte rBytes[] = {-2};
         BigInteger aNumber = BigInteger.ONE;
@@ -184,12 +143,6 @@
     /**
      * Not for a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for not method.",
-        method = "not",
-        args = {}
-    )
     public void testNotPos() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         int aSign = 1;
@@ -207,12 +160,6 @@
     /**
      * Not for a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for not method.",
-        method = "not",
-        args = {}
-    )
     public void testNotNeg() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         int aSign = -1;
@@ -231,12 +178,6 @@
      * Not for a negative number
      */
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for not method.",
-        method = "not",
-        args = {}
-    )
     public void testNotSpecialCase() {
         byte aBytes[] = {-1, -1, -1, -1};
         int aSign = 1;
@@ -250,4 +191,4 @@
         }
         assertEquals("incorrect sign", -1, result.signum());
     }
-}
\ No newline at end of file
+}
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOperateBitsTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOperateBitsTest.java
index f28ec43..d55a992 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOperateBitsTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOperateBitsTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Methods: bitLength, shiftLeft, shiftRight,
@@ -39,12 +34,6 @@
     /**
      * bitCount() of zero.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitCount method.",
-        method = "bitCount",
-        args = {}
-    )
     public void testBitCountZero() {
         BigInteger aNumber = new BigInteger("0");
         assertEquals(0, aNumber.bitCount());
@@ -53,12 +42,6 @@
     /**
      * bitCount() of a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitCount method.",
-        method = "bitCount",
-        args = {}
-    )
     public void testBitCountNeg() {
         BigInteger aNumber = new BigInteger("-12378634756382937873487638746283767238657872368748726875");
         assertEquals(87, aNumber.bitCount());
@@ -67,12 +50,6 @@
     /**
      * bitCount() of a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitCount method.",
-        method = "bitCount",
-        args = {}
-    )
     public void testBitCountPos() {
         BigInteger aNumber = new BigInteger("12378634756343564757582937873487638746283767238657872368748726875");
         assertEquals(107, aNumber.bitCount());
@@ -81,12 +58,6 @@
     /**
      * bitLength() of zero.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthZero() {
         BigInteger aNumber = new BigInteger("0");
         assertEquals(0, aNumber.bitLength());
@@ -95,12 +66,6 @@
     /**
      * bitLength() of a positive number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthPositive1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = 1;
@@ -111,12 +76,6 @@
     /**
      * bitLength() of a positive number with the leftmost bit set
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthPositive2() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -127,12 +86,6 @@
     /**
      * bitLength() of a positive number which is a power of 2
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthPositive3() {
         byte aBytes[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = 1;
@@ -143,12 +96,6 @@
     /**
      * bitLength() of a negative number.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthNegative1() {
         byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
         int aSign = -1;
@@ -159,12 +106,6 @@
     /**
      * bitLength() of a negative number with the leftmost bit set
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthNegative2() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -175,12 +116,6 @@
     /**
      * bitLength() of a negative number which is a power of 2
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for bitLength method.",
-        method = "bitLength",
-        args = {}
-    )
     public void testBitLengthNegative3() {
         byte aBytes[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = -1;
@@ -191,12 +126,6 @@
     /**
      * clearBit(int n) of a negative n
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitException() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -213,12 +142,6 @@
     /**
      * clearBit(int n) outside zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitZero() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -237,12 +160,6 @@
     /**
      * clearBit(int n) outside zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitZeroOutside1() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -261,12 +178,6 @@
     /**
      * clearBit(int n) inside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeInside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -285,12 +196,6 @@
     /**
      * clearBit(int n) inside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeInside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -309,12 +214,6 @@
     /**
      * clearBit(2) in the negative number with all ones in bit representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeInside3() {
         String as = "-18446744073709551615";
         int number = 2;
@@ -328,12 +227,6 @@
      * with all ones in bit representation.
      * the resulting number's length is 2.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeInside4() {
         String as = "-4294967295";
         String res = "-4294967296";
@@ -348,12 +241,6 @@
      * with all ones in bit representation.
      * the resulting number's length is 3.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeInside5() {
         String as = "-18446744073709551615";
         String res = "-18446744073709551616";
@@ -366,12 +253,6 @@
     /**
      * clearBit(int n) outside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeOutside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -390,12 +271,6 @@
     /**
      * clearBit(int n) outside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitNegativeOutside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -414,12 +289,6 @@
     /**
      * clearBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveInside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -438,12 +307,6 @@
     /**
      * clearBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveInside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -462,12 +325,6 @@
     /**
      * clearBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveInside3() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -486,12 +343,6 @@
     /**
      * clearBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveInside4 () {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -510,12 +361,6 @@
     /**
      * clearBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveInside5 () {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -534,12 +379,6 @@
     /**
      * clearBit(int n) outside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveOutside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -558,12 +397,6 @@
     /**
      * clearBit(int n) outside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitPositiveOutside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -582,12 +415,6 @@
     /**
      * clearBit(int n) the leftmost bit in a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for clearBit method.",
-        method = "clearBit",
-        args = {int.class}
-    )
     public void testClearBitTopNegative() {
         byte aBytes[] = {1, -128, 56, 100, -15, 35, 26};
         int aSign = -1;
@@ -606,12 +433,6 @@
     /**
      * flipBit(int n) of a negative n
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitException() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -628,12 +449,6 @@
     /**
      * flipBit(int n) zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitZero() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -652,12 +467,6 @@
     /**
      * flipBit(int n) outside zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitZeroOutside1() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -676,12 +485,6 @@
     /**
      * flipBit(int n) outside zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitZeroOutside2() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -700,12 +503,6 @@
     /**
      * flipBit(int n) the leftmost bit in a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitLeftmostNegative() {
         byte aBytes[] = {1, -128, 56, 100, -15, 35, 26};
         int aSign = -1;
@@ -724,12 +521,6 @@
     /**
      * flipBit(int n) the leftmost bit in a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitLeftmostPositive() {
         byte aBytes[] = {1, -128, 56, 100, -15, 35, 26};
         int aSign = 1;
@@ -748,12 +539,6 @@
     /**
      * flipBit(int n) inside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeInside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -772,12 +557,6 @@
     /**
      * flipBit(int n) inside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeInside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -796,12 +575,6 @@
     /**
      * flipBit(int n) inside a negative number with all ones in bit representation 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeInside3() {
         String as = "-18446744073709551615";
         String res = "-18446744073709551611";
@@ -816,12 +589,6 @@
      * with all ones in bit representation.
      * the resulting number's length is 2.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeInside4() {
         String as = "-4294967295";
         String res = "-4294967296";
@@ -836,12 +603,6 @@
      * with all ones in bit representation.
      * the resulting number's length is 3.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeInside5() {
         String as = "-18446744073709551615";
         String res = "-18446744073709551616";
@@ -854,12 +615,6 @@
     /**
      * flipBit(int n) outside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeOutside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -878,12 +633,6 @@
     /**
      * flipBit(int n) outside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitNegativeOutside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -902,12 +651,6 @@
     /**
      * flipBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitPositiveInside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -926,12 +669,6 @@
     /**
      * flipBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitPositiveInside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -950,12 +687,6 @@
     /**
      * flipBit(int n) outside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitPositiveOutside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -974,12 +705,6 @@
     /**
      * flipBit(int n) outside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for flipBit method.",
-        method = "flipBit",
-        args = {int.class}
-    )
     public void testFlipBitPositiveOutside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -998,12 +723,6 @@
     /**
      * setBit(int n) of a negative n
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitException() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1020,12 +739,6 @@
     /**
      * setBit(int n) outside zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitZero() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -1044,12 +757,6 @@
     /**
      * setBit(int n) outside zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitZeroOutside1() {
         byte aBytes[] = {0};
         int aSign = 0;
@@ -1068,12 +775,6 @@
     /**
      * setBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitPositiveInside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1092,12 +793,6 @@
     /**
      * setBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitPositiveInside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1116,12 +811,6 @@
     /**
      * setBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitPositiveInside3() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1140,12 +829,6 @@
     /**
      * setBit(int n) inside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitPositiveInside4 () {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1164,12 +847,6 @@
     /**
      * setBit(int n) outside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitPositiveOutside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1188,12 +865,6 @@
     /**
      * setBit(int n) outside a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitPositiveOutside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1212,12 +883,6 @@
     /**
      * setBit(int n) the leftmost bit in a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitTopPositive() {
         byte aBytes[] = {1, -128, 56, 100, -15, 35, 26};
         int aSign = 1;
@@ -1236,12 +901,6 @@
     /**
      * setBit(int n) the leftmost bit in a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitLeftmostNegative() {
         byte aBytes[] = {1, -128, 56, 100, -15, 35, 26};
         int aSign = -1;
@@ -1260,12 +919,6 @@
     /**
      * setBit(int n) inside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeInside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1284,12 +937,6 @@
     /**
      * setBit(int n) inside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeInside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1308,12 +955,6 @@
     /**
      * setBit(int n) inside a negative number with all ones in bit representation
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeInside3() {
         String as = "-18446744073709551615";
         String res = "-18446744073709551611";
@@ -1328,12 +969,6 @@
      * with all ones in bit representation.
      * the resulting number's length is 2.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeInside4() {
         String as = "-4294967295";
         int number = 0;
@@ -1347,12 +982,6 @@
      * with all ones in bit representation.
      * the resulting number's length is 3.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeInside5() {
         String as = "-18446744073709551615";
         int number = 0;
@@ -1364,12 +993,6 @@
     /**
      * setBit(int n) outside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeOutside1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1388,12 +1011,6 @@
     /**
      * setBit(int n) outside a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitNegativeOutside2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1414,12 +1031,6 @@
      * represented as n * 32 + 31, where n is an arbitrary integer.
      * Here 191 = 5 * 32 + 31 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for setBit method.",
-        method = "setBit",
-        args = {int.class}
-    )
     public void testSetBitBug1331() {
         BigInteger result = BigInteger.valueOf(0L).setBit(191);
         assertEquals("incorrect value", "3138550867693340381917894711603833208051177722232017256448", result.toString());
@@ -1429,12 +1040,6 @@
     /**
      * shiftLeft(int n), n = 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftLeft method.",
-        method = "shiftLeft",
-        args = {int.class}
-    )
     public void testShiftLeft1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1453,12 +1058,6 @@
     /**
      * shiftLeft(int n), n < 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftLeft method.",
-        method = "shiftLeft",
-        args = {int.class}
-    )
     public void testShiftLeft2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1477,12 +1076,6 @@
     /**
      * shiftLeft(int n) a positive number, n > 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftLeft method.",
-        method = "shiftLeft",
-        args = {int.class}
-    )
     public void testShiftLeft3() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1501,12 +1094,6 @@
     /**
      * shiftLeft(int n) a positive number, n > 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftLeft method.",
-        method = "shiftLeft",
-        args = {int.class}
-    )
     public void testShiftLeft4() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1525,12 +1112,6 @@
     /**
      * shiftLeft(int n) a negative number, n > 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftLeft method.",
-        method = "shiftLeft",
-        args = {int.class}
-    )
     public void testShiftLeft5() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1549,12 +1130,6 @@
     /**
      * shiftRight(int n), n = 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRight1() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1573,12 +1148,6 @@
     /**
      * shiftRight(int n), n < 0
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRight2() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1597,12 +1166,6 @@
     /**
      * shiftRight(int n), 0 < n < 32
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRight3() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1621,12 +1184,6 @@
     /**
      * shiftRight(int n), n > 32
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRight4() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1645,12 +1202,6 @@
     /**
      * shiftRight(int n), n is greater than bitLength()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRight5() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1671,12 +1222,6 @@
      * shift distance is multiple of 32;
      * shifted bits are NOT zeroes. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRightNegNonZeroesMul32() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 1, 0, 0, 0, 0, 0, 0, 0};
         int aSign = -1;
@@ -1697,12 +1242,6 @@
      * shift distance is NOT multiple of 32;
      * shifted bits are NOT zeroes. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRightNegNonZeroes() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = -1;
@@ -1723,12 +1262,6 @@
      * shift distance is NOT multiple of 32;
      * shifted bits are zeroes. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRightNegZeroes() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = -1;
@@ -1749,12 +1282,6 @@
      * shift distance is multiple of 32;
      * shifted bits are zeroes. 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void testShiftRightNegZeroesMul32() {
         byte aBytes[] = {1, -128, 56, 100, -2, -76, 89, 45, 91, 0, 0, 0, 0, 0, 0, 0, 0};
         int aSign = -1;
@@ -1773,12 +1300,6 @@
     /**
      * testBit(int n) of a negative n
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitException() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1795,12 +1316,6 @@
     /**
      * testBit(int n) of a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitPositive1() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1812,12 +1327,6 @@
     /**
      * testBit(int n) of a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitPositive2() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1829,12 +1338,6 @@
     /**
      * testBit(int n) of a positive number, n > bitLength()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitPositive3() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = 1;
@@ -1846,12 +1349,6 @@
     /**
      * testBit(int n) of a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitNegative1() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1863,12 +1360,6 @@
     /**
      * testBit(int n) of a positive n
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitNegative2() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1880,12 +1371,6 @@
     /**
      * testBit(int n) of a positive n, n > bitLength()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for shiftRight method.",
-        method = "testBit",
-        args = {int.class}
-    )
     public void testTestBitNegative3() {
         byte aBytes[] = {-1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26};
         int aSign = -1;
@@ -1900,12 +1385,6 @@
      * @tests java.math.BigInteger#getLowestSetBit() getLowestSetBit for
      *        negative BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for getLowestSetBit method.",
-        method = "getLowestSetBit",
-        args = {}
-    )
     public void test_getLowestSetBitNeg() {
         byte aBytes[] = {
                 -1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26
@@ -1921,12 +1400,6 @@
      * @tests java.math.BigInteger#getLowestSetBit() getLowestSetBit for
      *        positive BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for getLowestSetBit method.",
-        method = "getLowestSetBit",
-        args = {}
-    )
     public void test_getLowestSetBitPos() {
         byte aBytes[] = {
                 -1, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26
@@ -1958,12 +1431,6 @@
      * @tests java.math.BigInteger#getLowestSetBit() getLowestSetBit for zero
      *        BigInteger
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for getLowestSetBit method.",
-        method = "getLowestSetBit",
-        args = {}
-    )
     public void test_getLowestSetBitZero() {
         byte[] aBytes = {
             0
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOrTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOrTest.java
index 7b0e076..175a7a7 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOrTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerOrTest.java
@@ -21,16 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.BrokenTest;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Method: or 
@@ -39,12 +33,6 @@
     /**
      * Or for zero and a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroPos() {
         byte aBytes[] = {0};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -65,12 +53,6 @@
     /**
      * Or for zero and a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroNeg() {
         byte aBytes[] = {0};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -91,12 +73,6 @@
     /**
      * Or for a positive number and zero 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosZero() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {0};
@@ -117,12 +93,6 @@
     /**
      * Or for a negative number and zero  
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPos() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {0};
@@ -143,12 +113,6 @@
     /**
      * Or for zero and zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroZero() {
         byte aBytes[] = {0};
         byte bBytes[] = {0};
@@ -169,12 +133,6 @@
     /**
      * Or for zero and one
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroOne() {
         byte aBytes[] = {0};
         byte bBytes[] = {1};
@@ -195,12 +153,6 @@
     /**
      * Or for one and one
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testOneOne() {
         byte aBytes[] = {1};
         byte bBytes[] = {1};
@@ -221,12 +173,6 @@
     /**
      * Or for two positive numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -247,12 +193,6 @@
     /**
      * Or for two positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -273,12 +213,6 @@
     /**
      * Or for two positive numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -299,12 +233,6 @@
     /**
      * Or for two negative numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -325,12 +253,6 @@
     /**
      * Or for two negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -351,12 +273,6 @@
     /**
      * Or for two negative numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -377,12 +293,6 @@
     /**
      * Or for two numbers of different signs and the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -403,12 +313,6 @@
     /**
      * Or for two numbers of different signs and the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosSameLength() {
         byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -429,12 +333,6 @@
     /**
      * Or for a negative and a positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -455,12 +353,6 @@
     /**
      * Or for two negative numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -481,12 +373,6 @@
     /**
      * Or for a positive and a negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegFirstLonger() {
         byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
         byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
@@ -507,12 +393,6 @@
     /**
      * Or for a positive and a negative number; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegFirstShorter() {
         byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
         byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
@@ -530,13 +410,6 @@
         assertEquals("incorrect sign", -1, result.signum());
     }
     
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for or operation",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
-    @BrokenTest("Fails in CTS environment, but passes in CoreTestRunner")
     public void testRegression() {
         // Regression test for HARMONY-1996
         BigInteger x = new BigInteger("-1023");
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerSubtractTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerSubtractTest.java
index 29d8405..1103a08 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerSubtractTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerSubtractTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Method: subtract 
@@ -39,12 +34,6 @@
      * Subtract two positive numbers of the same length.
      * The first is greater.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase1() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
@@ -66,12 +55,6 @@
      * Subtract two positive numbers of the same length.
      * The second is greater.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase2() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -94,12 +77,6 @@
      * The first is positive.
      * The first is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase3() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
@@ -122,12 +99,6 @@
      * The first is positive.
      * The second is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase4() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -149,12 +120,6 @@
      * Subtract two negative numbers of the same length.
      * The first is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase5() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
@@ -176,12 +141,6 @@
      * Subtract two negative numbers of the same length.
      * The second is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase6() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -204,12 +163,6 @@
      * The first is negative.
      * The first is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase7() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
@@ -232,12 +185,6 @@
      * The first is negative.
      * The second is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase8() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -259,12 +206,6 @@
      * Subtract two positive numbers of different length.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase9() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -286,12 +227,6 @@
      * Subtract two positive numbers of different length.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase10() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -314,12 +249,6 @@
      * The first is positive.
      * The first is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase11() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -342,12 +271,6 @@
      * The first is positive.
      * The second is greater in absolute value.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase12() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -370,12 +293,6 @@
      * The first is negative.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase13() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -398,12 +315,6 @@
      * The first is negative.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase14() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -425,12 +336,6 @@
      * Subtract two negative numbers of different length.
      * The first is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase15() {
         byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
         byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
@@ -452,12 +357,6 @@
      * Subtract two negative numbers of different length.
      * The second is longer.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase16() {
         byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
         byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
@@ -478,12 +377,6 @@
     /**
      * Subtract two positive equal in absolute value numbers.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase17() {
         byte aBytes[] = {-120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
         byte bBytes[] = {-120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
@@ -505,12 +398,6 @@
      * Subtract zero from a number.
      * The number is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase18() {
         byte aBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
         byte bBytes[] = {0};
@@ -532,12 +419,6 @@
      * Subtract a number from zero.
      * The number is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase19() {
         byte aBytes[] = {0};
         byte bBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
@@ -558,12 +439,6 @@
     /**
      * Subtract zero from zero.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase20() {
         byte aBytes[] = {0};
         byte bBytes[] = {0};
@@ -585,12 +460,6 @@
      * Subtract ZERO from a number.
      * The number is positive.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase21() {
         byte aBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
         byte rBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
@@ -610,12 +479,6 @@
      * Subtract a number from ZERO.
      * The number is negative.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase22() {
         byte bBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
         byte rBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
@@ -634,12 +497,6 @@
     /**
      * Subtract ZERO from ZERO.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase23() {
         byte rBytes[] = {0};
         BigInteger aNumber = BigInteger.ZERO;
@@ -656,12 +513,6 @@
     /**
      * Subtract ONE from ONE.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase24() {
         byte rBytes[] = {0};
         BigInteger aNumber = BigInteger.ONE;
@@ -678,12 +529,6 @@
     /**
      * Subtract two numbers so that borrow is 1.
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for subtract method",
-        method = "subtract",
-        args = {java.math.BigInteger.class}
-    )
     public void testCase25() {
         byte aBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1};
         byte bBytes[] = {-128, -128, -128, -128, -128, -128, -128, -128, -128};
@@ -701,4 +546,3 @@
         assertEquals(-1, result.signum());
     }
 }
-
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerToStringTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerToStringTest.java
index c405553..34b4b19 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerToStringTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerToStringTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:   java.math.BigInteger
  * Method: toString(int radix)
@@ -38,12 +33,6 @@
     /**
      * If 36 < radix < 2 it should be set to 10
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadixOutOfRange() {
         String value = "442429234853876401";
         int radix = 10;
@@ -55,12 +44,6 @@
     /**
      * test negative number of radix 2
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix2Neg() {
         String value = "-101001100010010001001010101110000101010110001010010101010101010101010101010101010101010101010010101";
         int radix = 2;
@@ -72,12 +55,6 @@
     /**
      * test positive number of radix 2
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix2Pos() {
         String value = "101000011111000000110101010101010101010001001010101010101010010101010101010000100010010";
         int radix = 2;
@@ -89,12 +66,6 @@
     /**
      * test negative number of radix 10
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix10Neg() {
         String value = "-2489756308572364789878394872984";
         int radix = 16;
@@ -106,12 +77,6 @@
     /**
      * test positive number of radix 10
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix10Pos() {
         String value = "2387627892347567398736473476";
         int radix = 16;
@@ -123,12 +88,6 @@
     /**
      * test negative number of radix 16
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix16Neg() {
         String value = "-287628a883451b800865c67e8d7ff20";
         int radix = 16;
@@ -140,12 +99,6 @@
     /**
      * test positive number of radix 16
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix16Pos() {
         String value = "287628a883451b800865c67e8d7ff20";
         int radix = 16;
@@ -157,12 +110,6 @@
     /**
      * test negative number of radix 24
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix24Neg() {
         String value = "-287628a88gmn3451b8ijk00865c67e8d7ff20";
         int radix = 24;
@@ -174,12 +121,6 @@
     /**
      * test positive number of radix 24
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix24Pos() {
         String value = "287628a883451bg80ijhk0865c67e8d7ff20";
         int radix = 24;
@@ -191,12 +132,6 @@
     /**
      * test negative number of radix 24
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix36Neg() {
         String value = "-uhguweut98iu4h3478tq3985pq98yeiuth33485yq4aiuhalai485yiaehasdkr8tywi5uhslei8";
         int radix = 36;
@@ -208,12 +143,6 @@
     /**
      * test positive number of radix 24
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {int.class}
-    )
     public void testRadix36Pos() {
         String value = "23895lt45y6vhgliuwhgi45y845htsuerhsi4586ysuerhtsio5y68peruhgsil4568ypeorihtse48y6";
         int radix = 36;
@@ -227,12 +156,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void test_toString1() {
 
         String s = "0000000000";
@@ -244,12 +167,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void test_toString2() {
         String s = "1234567890987654321";
         BigInteger bi = new BigInteger(s);
@@ -260,12 +177,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void test_toString3() {
         String s = "-1234567890987654321";
         BigInteger bi = new BigInteger(s);
@@ -276,12 +187,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void test_toString4() {
         String s = "12345678901234";
         long l = 12345678901234L;
@@ -293,12 +198,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void test_toString5() {
         String s = "-12345678901234";
         long l = -12345678901234L;
@@ -310,12 +209,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "This is a complete subset of tests for toString method",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         byte aBytes[] = {
                 12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91
diff --git a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerXorTest.java b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerXorTest.java
index 4e2dbcf..b55b60b 100644
--- a/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerXorTest.java
+++ b/math/src/test/java/org/apache/harmony/math/tests/java/math/BigIntegerXorTest.java
@@ -21,15 +21,10 @@
 
 package org.apache.harmony.math.tests.java.math;
 
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-
 import java.math.BigInteger;
 
 import junit.framework.TestCase;
-@TestTargetClass(BigInteger.class)
+
 /**
  * Class:  java.math.BigInteger
  * Method: xor
@@ -38,12 +33,6 @@
     /**
      * Xor for zero and a positive number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroPos() {
         String numA = "0";
         String numB = "27384627835298756289327365";
@@ -57,12 +46,6 @@
     /**
      * Xor for zero and a negative number
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroNeg() {
         String numA = "0";
         String numB = "-27384627835298756289327365";
@@ -76,12 +59,6 @@
     /**
      * Xor for a positive number and zero 
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosZero() {
         String numA = "27384627835298756289327365";
         String numB = "0";
@@ -95,12 +72,6 @@
     /**
      * Xor for a negative number and zero  
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPos() {
         String numA = "-27384627835298756289327365";
         String numB = "0";
@@ -114,12 +85,6 @@
     /**
      * Xor for zero and zero
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroZero() {
         String numA = "0";
         String numB = "0";
@@ -133,12 +98,6 @@
     /**
      * Xor for zero and one
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testZeroOne() {
         String numA = "0";
         String numB = "1";
@@ -152,12 +111,6 @@
     /**
      * Xor for one and one
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testOneOne() {
         String numA = "1";
         String numB = "1";
@@ -171,12 +124,6 @@
     /**
      * Xor for two positive numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosSameLength() {
         String numA = "283746278342837476784564875684767";
         String numB = "293478573489347658763745839457637";
@@ -190,12 +137,6 @@
     /**
      * Xor for two positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosFirstLonger() {
         String numA = "2837462783428374767845648748973847593874837948575684767";
         String numB = "293478573489347658763745839457637";
@@ -209,12 +150,6 @@
     /**
      * Xor for two positive numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosPosFirstShorter() {
         String numA = "293478573489347658763745839457637";
         String numB = "2837462783428374767845648748973847593874837948575684767";
@@ -228,12 +163,6 @@
     /**
      * Xor for two negative numbers of the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegSameLength() {
         String numA = "-283746278342837476784564875684767";
         String numB = "-293478573489347658763745839457637";
@@ -247,12 +176,6 @@
     /**
      * Xor for two negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegFirstLonger() {
         String numA = "-2837462783428374767845648748973847593874837948575684767";
         String numB = "-293478573489347658763745839457637";
@@ -266,12 +189,6 @@
     /**
      * Xor for two negative numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegNegFirstShorter() {
         String numA = "293478573489347658763745839457637";
         String numB = "2837462783428374767845648748973847593874837948575684767";
@@ -285,12 +202,6 @@
     /**
      * Xor for two numbers of different signs and the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegSameLength() {
         String numA = "283746278342837476784564875684767";
         String numB = "-293478573489347658763745839457637";
@@ -304,12 +215,6 @@
     /**
      * Xor for two numbers of different signs and the same length
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosSameLength() {
         String numA = "-283746278342837476784564875684767";
         String numB = "293478573489347658763745839457637";
@@ -323,12 +228,6 @@
     /**
      * Xor for a negative and a positive numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstLonger() {
         String numA = "-2837462783428374767845648748973847593874837948575684767";
         String numB = "293478573489347658763745839457637";
@@ -342,12 +241,6 @@
     /**
      * Xor for two negative numbers; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testNegPosFirstShorter() {
         String numA = "-293478573489347658763745839457637";
         String numB = "2837462783428374767845648748973847593874837948575684767";
@@ -361,12 +254,6 @@
     /**
      * Xor for a positive and a negative numbers; the first is longer
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegFirstLonger() {
         String numA = "2837462783428374767845648748973847593874837948575684767";
         String numB = "-293478573489347658763745839457637";
@@ -380,12 +267,6 @@
     /**
      * Xor for a positive and a negative number; the first is shorter
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "This is a complete subset of tests for xor operation.",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void testPosNegFirstShorter() {
         String numA = "293478573489347658763745839457637";
         String numB = "-2837462783428374767845648748973847593874837948575684767";
diff --git a/math/src/test/java/tests/api/java/math/AllTests.java b/math/src/test/java/tests/api/java/math/AllTests.java
index 483e08a..a3fb664 100644
--- a/math/src/test/java/tests/api/java/math/AllTests.java
+++ b/math/src/test/java/tests/api/java/math/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the Math project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.math");
+        TestSuite suite = new TestSuite("Tests for java.math");
         // $JUnit-BEGIN$
         suite.addTestSuite(BigDecimalTest.class);
         suite.addTestSuite(BigIntegerTest.class);
diff --git a/math/src/test/java/tests/api/java/math/BigDecimalTest.java b/math/src/test/java/tests/api/java/math/BigDecimalTest.java
index 29d68a2..a053cef 100644
--- a/math/src/test/java/tests/api/java/math/BigDecimalTest.java
+++ b/math/src/test/java/tests/api/java/math/BigDecimalTest.java
@@ -17,12 +17,6 @@
 
 package tests.api.java.math;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.AndroidOnly;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
@@ -32,7 +26,6 @@
 import java.math.RoundingMode;
 import java.math.MathContext;
 
-@TestTargetClass(BigDecimal.class)
 public class BigDecimalTest extends junit.framework.TestCase {
     BigInteger value = new BigInteger("12345908");
 
@@ -41,12 +34,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class}
-    )
     public void test_ConstructorLjava_math_BigInteger() {
         BigDecimal big = new BigDecimal(value);
         assertTrue("the BigDecimal value is not initialized properly", big
@@ -57,12 +44,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.math.BigInteger, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.math.BigInteger.class, int.class}
-    )
     public void test_ConstructorLjava_math_BigIntegerI() {
         BigDecimal big = new BigDecimal(value2, 5);
         assertTrue("the BigDecimal value is not initialized properly", big
@@ -75,12 +56,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(double)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = ".",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void test_ConstructorD() {
         //
         // These numbers have an exact representation as doubles:
@@ -132,12 +107,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() throws NumberFormatException {
         BigDecimal big = new BigDecimal("345.23499600293850");
         assertTrue("the BigDecimal value is not initialized properly", big
@@ -158,12 +127,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "",
-        method = "BigDecimal",
-        args = {double.class}
-    )
     public void test_constructor_String_plus_exp() {
         /*
          * BigDecimal does not support a + sign in the exponent when converting
@@ -181,12 +144,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checked.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void test_constructor_String_empty() {
         try {
             new BigDecimal("");            
@@ -198,12 +155,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checked.",
-        method = "BigDecimal",
-        args = {java.lang.String.class}
-    )
     public void test_constructor_String_plus_minus_exp() {
         try {
             new BigDecimal("+35e+-2");            
@@ -221,12 +172,6 @@
     /**
      * @tests java.math.BigDecimal#BigDecimal(char[])
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Exception checked.",
-        method = "BigDecimal",
-        args = {char[].class}
-    )
     public void test_constructor_CC_plus_minus_exp() {
         try {
             new BigDecimal("+35e+-2".toCharArray());          
@@ -244,12 +189,6 @@
     /**
      * @tests java.math.BigDecimal#abs()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {}
-    )
     public void test_abs() {
         BigDecimal big = new BigDecimal("-1234");
         BigDecimal bigabs = big.abs();
@@ -264,12 +203,6 @@
     /**
      * @tests java.math.BigDecimal#add(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "add",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_addLjava_math_BigDecimal() {
         BigDecimal add1 = new BigDecimal("23.456");
         BigDecimal add2 = new BigDecimal("3849.235");
@@ -287,12 +220,6 @@
     /**
      * @tests java.math.BigDecimal#compareTo(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_compareToLjava_math_BigDecimal() {
         BigDecimal comp1 = new BigDecimal("1.00");
         BigDecimal comp2 = new BigDecimal(1.000000D);
@@ -309,12 +236,6 @@
     /**
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "IllegalArgumentException checking missed. Used only ROUND_UP & ROUND_DOWN round modes.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class}
-    )
     public void test_divideLjava_math_BigDecimalI() {
         BigDecimal divd1 = new BigDecimal(value, 2);
         BigDecimal divd2 = new BigDecimal("2.335");
@@ -342,12 +263,6 @@
     /**
      * @tests java.math.BigDecimal#divide(java.math.BigDecimal, int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "IllegalArgumentException checking missed. Used only ROUND_UP & ROUND_DOWN round modes.",
-        method = "divide",
-        args = {java.math.BigDecimal.class, int.class, int.class}
-    )
     public void test_divideLjava_math_BigDecimalII() {
         BigDecimal divd1 = new BigDecimal(value2, 4);
         BigDecimal divd2 = new BigDecimal("0.0023");
@@ -372,12 +287,6 @@
     /**
      * @tests java.math.BigDecimal#doubleValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Narrowing limitations of double representation are not checked.",
-        method = "doubleValue",
-        args = {}
-    )
     public void test_doubleValue() {
         BigDecimal bigDB = new BigDecimal(-1.234E-112);
 //        Commenting out this part because it causes an endless loop (see HARMONY-319 and HARMONY-329)
@@ -409,12 +318,6 @@
     /**
      * @tests java.math.BigDecimal#equals(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         BigDecimal equal1 = new BigDecimal(1.00D);
         BigDecimal equal2 = new BigDecimal("1.0");
@@ -442,12 +345,6 @@
     /**
      * @tests java.math.BigDecimal#floatValue()
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Narrowing limitations of float representation are not checked.",
-        method = "floatValue",
-        args = {}
-    )
     public void test_floatValue() {
         BigDecimal fl1 = new BigDecimal("234563782344567");
         assertTrue("the float representation of bigDecimal 234563782344567",
@@ -475,12 +372,6 @@
     /**
      * @tests java.math.BigDecimal#hashCode()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
     public void test_hashCode() {
         // anything that is equal must have the same hashCode
         BigDecimal hash = new BigDecimal("1.00");
@@ -509,12 +400,6 @@
     /**
      * @tests java.math.BigDecimal#intValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "intValue",
-        args = {}
-    )
     public void test_intValue() {
         BigDecimal int1 = new BigDecimal(value, 3);
         assertTrue("the int value of 12345.908 is not 12345",
@@ -533,12 +418,6 @@
     /**
      * @tests java.math.BigDecimal#longValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "longValue",
-        args = {}
-    )
     public void test_longValue() {
         BigDecimal long1 = new BigDecimal(value2.negate(), 0);
         assertTrue("the long value of 12334560000 is not 12334560000", long1
@@ -557,12 +436,6 @@
     /**
      * @tests java.math.BigDecimal#max(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "max",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_maxLjava_math_BigDecimal() {
         BigDecimal max1 = new BigDecimal(value2, 1);
         BigDecimal max2 = new BigDecimal(value2, 4);
@@ -580,12 +453,6 @@
     /**
      * @tests java.math.BigDecimal#min(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "min",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_minLjava_math_BigDecimal() {
         BigDecimal min1 = new BigDecimal(-12345.4D);
         BigDecimal min2 = new BigDecimal(-12345.39D);
@@ -600,12 +467,6 @@
     /**
      * @tests java.math.BigDecimal#movePointLeft(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "movePointLeft",
-        args = {int.class}
-    )
     public void test_movePointLeftI() {
         BigDecimal movePtLeft = new BigDecimal("123456265.34");
         BigDecimal alreadyMoved = movePtLeft.movePointLeft(5);
@@ -635,12 +496,6 @@
     /**
      * @tests java.math.BigDecimal#movePointRight(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed.",
-        method = "movePointRight",
-        args = {int.class}
-    )
     public void test_movePointRightI() {
         BigDecimal movePtRight = new BigDecimal("-1.58796521458");
         BigDecimal alreadyMoved = movePtRight.movePointRight(8);
@@ -667,12 +522,6 @@
     /**
      * @tests java.math.BigDecimal#multiply(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "multiply",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_multiplyLjava_math_BigDecimal() {
         BigDecimal multi1 = new BigDecimal(value, 5);
         BigDecimal multi2 = new BigDecimal(2.345D);
@@ -708,12 +557,6 @@
     /**
      * @tests java.math.BigDecimal#negate()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "negate",
-        args = {}
-    )
     public void test_negate() {
         BigDecimal negate1 = new BigDecimal(value2, 7);
         assertTrue("the negate of 1233.4560000 is not -1233.4560000", negate1
@@ -729,12 +572,6 @@
     /**
      * @tests java.math.BigDecimal#scale()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "scale",
-        args = {}
-    )
     public void test_scale() {
         BigDecimal scale1 = new BigDecimal(value2, 8);
         assertTrue("the scale of the number 123.34560000 is wrong", scale1
@@ -758,12 +595,6 @@
     /**
      * @tests java.math.BigDecimal#setScale(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setScale",
-        args = {int.class}
-    )
     public void test_setScaleI() {
         // rounding mode defaults to zero
         BigDecimal setScale1 = new BigDecimal(value, 3);
@@ -783,12 +614,6 @@
     /**
      * @tests java.math.BigDecimal#setScale(int, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setScale",
-        args = {int.class, int.class}
-    )
     public void test_setScaleII() {
         BigDecimal setScale1 = new BigDecimal(2.323E102);
         BigDecimal setScale2 = setScale1.setScale(4);
@@ -924,12 +749,6 @@
     /**
      * @tests java.math.BigDecimal#setScale(int, java.math.RoundingMode)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "setScale",
-        args = {int.class, java.math.RoundingMode.class}
-    )
     public void test_setScaleILjava_math_RoundingMode() {
         BigDecimal setScale1 = new BigDecimal(2.323E102);
         BigDecimal setScale2 = setScale1.setScale(4);
@@ -1065,12 +884,6 @@
     /**
      * @tests java.math.BigDecimal#signum()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "signum",
-        args = {}
-    )
     public void test_signum() {
         BigDecimal sign = new BigDecimal(123E-104);
         assertTrue("123E-104 is not positive in signum()", sign.signum() == 1);
@@ -1084,12 +897,6 @@
     /**
      * @tests java.math.BigDecimal#subtract(java.math.BigDecimal)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "subtract",
-        args = {java.math.BigDecimal.class}
-    )
     public void test_subtractLjava_math_BigDecimal() {
         BigDecimal sub1 = new BigDecimal("13948");
         BigDecimal sub2 = new BigDecimal("2839.489");
@@ -1122,12 +929,6 @@
     /**
      * @tests java.math.BigDecimal#toBigInteger()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toBigInteger",
-        args = {}
-    )
     public void test_toBigInteger() {
         BigDecimal sub1 = new BigDecimal("-29830.989");
         BigInteger result = sub1.toBigInteger();
@@ -1151,12 +952,6 @@
     /**
      * @tests java.math.BigDecimal#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         BigDecimal toString1 = new BigDecimal("1234.000");
         assertTrue("the toString representation of 1234.000 is wrong",
@@ -1175,12 +970,6 @@
     /**
      * @tests java.math.BigDecimal#unscaledValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "unscaledValue",
-        args = {}
-    )
     public void test_unscaledValue() {
         BigDecimal unsVal = new BigDecimal("-2839485.000");
         assertTrue("the unscaledValue of -2839485.000 is wrong", unsVal
@@ -1201,12 +990,6 @@
     /**
      * @tests java.math.BigDecimal#valueOf(long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void test_valueOfJ() {
         BigDecimal valueOfL = BigDecimal.valueOf(9223372036854775806L);
         assertTrue("the bigDecimal equivalent of 9223372036854775806 is wrong",
@@ -1225,12 +1008,6 @@
     /**
      * @tests java.math.BigDecimal#valueOf(long, int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {long.class, int.class}
-    )
     public void test_valueOfJI() {
         BigDecimal valueOfJI = BigDecimal.valueOf(9223372036854775806L, 5);
         assertTrue(
@@ -1260,12 +1037,6 @@
 
     }
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "Checks serialization",
-        method = "!SerializationSelf",
-        args = {}
-    )
     public void test_BigDecimal_serialization() throws Exception {
         // Regression for HARMONY-1896
         char[] in = { '1', '5', '6', '7', '8', '7', '.', '0', '0' };
@@ -1287,12 +1058,6 @@
     /**
      * @tests java.math.BigDecimal#stripTrailingZero(long)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "The RI fails the Zero Test: has scale 4 for BigDecimal('0.0000')",
-        method = "stripTrailingZeros",
-        args = {}
-    )
     public void test_stripTrailingZero() {
         BigDecimal sixhundredtest = new BigDecimal("600.0");
         assertTrue("stripTrailingZero failed for 600.0",
@@ -1314,12 +1079,6 @@
         // END android-changed
     }
 
-    @TestTargetNew(
-            level = TestLevel.PARTIAL_COMPLETE,
-            notes = "",
-            method = "abs",
-            args = {MathContext.class}
-    )
     public void testMathContextConstruction() {
         String a = "-12380945E+61";
         BigDecimal aNumber = new BigDecimal(a);
diff --git a/math/src/test/java/tests/api/java/math/BigIntegerTest.java b/math/src/test/java/tests/api/java/math/BigIntegerTest.java
index b84aa17..77eabb4 100644
--- a/math/src/test/java/tests/api/java/math/BigIntegerTest.java
+++ b/math/src/test/java/tests/api/java/math/BigIntegerTest.java
@@ -17,16 +17,9 @@
 
 package tests.api.java.math;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
 import java.math.BigInteger;
 import java.util.Random;
 
-@TestTargetClass(BigInteger.class)
 public class BigIntegerTest extends junit.framework.TestCase {
 
     BigInteger minusTwo = new BigInteger("-2", 10);
@@ -87,12 +80,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(int, java.util.Random)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigInteger",
-        args = {int.class, java.util.Random.class}
-    )
     public void test_ConstructorILjava_util_Random() {
         // regression test for HARMONY-1047
         try {
@@ -123,12 +110,7 @@
     /**
      * @tests java.math.BigInteger#BigInteger(int, int, java.util.Random)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "BigInteger",
-        args = {int.class, int.class, java.util.Random.class}
-    )
-    @KnownFailure("BIGNUM returns no Primes smaller than 16 bits.")
+    // BIGNUM returns no Primes smaller than 16 bits.
     public void test_ConstructorIILjava_util_Random() {
         bi = new BigInteger(10, 5, rand);
         bi2 = new BigInteger(10, 5, rand);
@@ -168,12 +150,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(byte[])
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "NumberFormatException checking missed",
-        method = "BigInteger",
-        args = {byte[].class}
-    )
     public void test_Constructor$B() {
         byte[] myByteArray;
         myByteArray = new byte[] { (byte) 0x00, (byte) 0xFF, (byte) 0xFE };
@@ -188,12 +164,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(int, byte[])
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BigInteger",
-        args = {int.class, byte[].class}
-    )
     public void test_ConstructorI$B() {
         byte[] myByteArray;
         myByteArray = new byte[] { (byte) 0xFF, (byte) 0xFE };
@@ -218,12 +188,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Checks NumberFormatException",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_constructor_String_empty() {
         try {
             new BigInteger("");            
@@ -235,12 +199,6 @@
     /**
      * @tests java.math.BigInteger#toByteArray()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toByteArray",
-        args = {}
-    )
     public void test_toByteArray() {
         byte[] myByteArray, anotherByteArray;
         myByteArray = new byte[] { 97, 33, 120, 124, 50, 2, 0, 0, 0, 12, 124,
@@ -274,20 +232,6 @@
     /**
      * @tests java.math.BigInteger#isProbablePrime(int)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "isProbablePrime",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "probablePrime",
-            args = {int.class, java.util.Random.class}
-        )
-    })
     public void test_isProbablePrimeI() {
         int fails = 0;
         bi = new BigInteger(20, 20, rand);
@@ -355,20 +299,6 @@
     /**
      * @tests java.math.BigInteger#nextProbablePrime()
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "nextProbablePrime",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "isProbablePrime",
-            args = {int.class}
-        )
-    })
     public void test_nextProbablePrime() {
         largePrimesProduct(
                 new BigInteger("2537895984043447429238717358455377929009126353874925049325287329295635198252046158619999217453233889378619619008359011789"),
@@ -400,12 +330,6 @@
     /**
      * @tests java.math.BigInteger#probablePrime(int, java.util.Random)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "probablePrime",
-        args = {int.class, java.util.Random.class}
-    )
     public void test_probablePrime() {
         for (int bitLength = 50; bitLength <= 1050; bitLength += 100) {
             BigInteger a = BigInteger.probablePrime(bitLength, rand);
@@ -478,12 +402,6 @@
     /**
      * @tests java.math.BigInteger#equals(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void test_equalsLjava_lang_Object() {
         assertTrue("0=0", zero.equals(BigInteger.valueOf(0)));
         assertTrue("-123=-123", BigInteger.valueOf(-123).equals(
@@ -499,12 +417,6 @@
     /**
      * @tests java.math.BigInteger#compareTo(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compareTo",
-        args = {java.math.BigInteger.class}
-    )
     public void test_compareToLjava_math_BigInteger() {
         assertTrue("Smaller number returned >= 0", one.compareTo(two) < 0);
         assertTrue("Larger number returned >= 0", two.compareTo(one) > 0);
@@ -516,12 +428,6 @@
     /**
      * @tests java.math.BigInteger#intValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "intValue",
-        args = {}
-    )
     public void test_intValue() {
         assertTrue("Incorrect intValue for 2**70",
                 twoToTheSeventy.intValue() == 0);
@@ -531,12 +437,6 @@
     /**
      * @tests java.math.BigInteger#longValue()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "longValue",
-        args = {}
-    )
     public void test_longValue() {
         assertTrue("Incorrect longValue for 2**70",
                 twoToTheSeventy.longValue() == 0);
@@ -546,12 +446,6 @@
     /**
      * @tests java.math.BigInteger#valueOf(long)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {long.class}
-    )
     public void test_valueOfJ() {
         assertTrue("Incurred number returned for 2", BigInteger.valueOf(2L)
                 .equals(two));
@@ -562,12 +456,6 @@
     /**
      * @tests java.math.BigInteger#add(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Test is OK, but some cases listed below can be reasonable.",
-        method = "add",
-        args = {java.math.BigInteger.class}
-    )
     public void test_addLjava_math_BigInteger() {
         assertTrue("Incorrect sum--wanted a zillion", aZillion.add(aZillion)
                 .add(aZillion.negate()).equals(aZillion));
@@ -609,12 +497,6 @@
     /**
      * @tests java.math.BigInteger#negate()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "negate",
-        args = {}
-    )
     public void test_negate() {
         assertTrue("Single negation of zero did not result in zero", zero
                 .negate().equals(zero));
@@ -643,12 +525,6 @@
     /**
      * @tests java.math.BigInteger#signum()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "signum",
-        args = {}
-    )
     public void test_signum() {
         assertTrue("Wrong positive signum", two.signum() == 1);
         assertTrue("Wrong zero signum", zero.signum() == 0);
@@ -659,12 +535,6 @@
     /**
      * @tests java.math.BigInteger#abs()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "abs",
-        args = {}
-    )
     public void test_abs() {
         assertTrue("Invalid number returned for zillion", aZillion.negate()
                 .abs().equals(aZillion.abs()));
@@ -678,12 +548,6 @@
     /**
      * @tests java.math.BigInteger#pow(int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checking missed",
-        method = "pow",
-        args = {int.class}
-    )
     public void test_powI() {
         assertTrue("Incorrect exponent returned for 2**10", two.pow(10).equals(
                 twoToTheTen));
@@ -696,12 +560,6 @@
     /**
      * @tests java.math.BigInteger#modInverse(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "modInverse",
-        args = {java.math.BigInteger.class}
-    )
     public void test_modInverseLjava_math_BigInteger() {
         BigInteger a = zero, mod, inv;
         for (int j = 3; j < 50; j++) {
@@ -751,12 +609,6 @@
     /**
      * @tests java.math.BigInteger#shiftRight(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "shiftRight",
-        args = {int.class}
-    )
     public void test_shiftRightI() {
         assertTrue("1 >> 0", BigInteger.valueOf(1).shiftRight(0).equals(
                 BigInteger.ONE));
@@ -814,12 +666,6 @@
     /**
      * @tests java.math.BigInteger#shiftLeft(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "shiftLeft",
-        args = {int.class}
-    )
     public void test_shiftLeftI() {
         assertTrue("1 << 0", one.shiftLeft(0).equals(one));
         assertTrue("1 << 1", one.shiftLeft(1).equals(two));
@@ -861,12 +707,6 @@
     /**
      * @tests java.math.BigInteger#multiply(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "multiply",
-        args = {java.math.BigInteger.class}
-    )
     public void test_multiplyLjava_math_BigInteger() {
         assertTrue("Incorrect sum--wanted three zillion", aZillion
                 .add(aZillion).add(aZillion).equals(
@@ -893,12 +733,6 @@
     /**
      * @tests java.math.BigInteger#divide(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "divide",
-        args = {java.math.BigInteger.class}
-    )
     public void test_divideLjava_math_BigInteger() {
         testAllDivs(bi33, bi3);
         testAllDivs(bi22, bi2);
@@ -957,12 +791,6 @@
     /**
      * @tests java.math.BigInteger#remainder(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checked",
-        method = "remainder",
-        args = {java.math.BigInteger.class}
-    )
     public void test_remainderLjava_math_BigInteger() {
         try {
             largePos.remainder(zero);
@@ -992,12 +820,6 @@
     /**
      * @tests java.math.BigInteger#mod(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checked",
-        method = "mod",
-        args = {java.math.BigInteger.class}
-    )
     public void test_modLjava_math_BigInteger() {
         try {
             largePos.mod(zero);
@@ -1027,12 +849,6 @@
     /**
      * @tests java.math.BigInteger#divideAndRemainder(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "ArithmeticException checked",
-        method = "divideAndRemainder",
-        args = {java.math.BigInteger.class}
-    )
     public void test_divideAndRemainderLjava_math_BigInteger() {
         try {
             largePos.divideAndRemainder(zero);
@@ -1062,12 +878,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "NumberFormatException checking missed.",
-        method = "BigInteger",
-        args = {java.lang.String.class}
-    )
     public void test_ConstructorLjava_lang_String() {
         assertTrue("new(0)", new BigInteger("0").equals(BigInteger.valueOf(0)));
         assertTrue("new(1)", new BigInteger("1").equals(BigInteger.valueOf(1)));
@@ -1082,12 +892,6 @@
     /**
      * @tests java.math.BigInteger#BigInteger(java.lang.String, int)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "NumberFormatException checking missed.",
-        method = "BigInteger",
-        args = {java.lang.String.class, int.class}
-    )
     public void test_ConstructorLjava_lang_StringI() {
         assertTrue("new(0,16)", new BigInteger("0", 16).equals(BigInteger
                 .valueOf(0)));
@@ -1112,12 +916,6 @@
     /**
      * @tests java.math.BigInteger#toString()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {}
-    )
     public void test_toString() {
         assertTrue("0.toString", "0".equals(BigInteger.valueOf(0).toString()));
         assertTrue("1.toString", "1".equals(BigInteger.valueOf(1).toString()));
@@ -1132,12 +930,6 @@
     /**
      * @tests java.math.BigInteger#toString(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "toString",
-        args = {int.class}
-    )
     public void test_toStringI() {
         assertTrue("0.toString(16)", "0".equals(BigInteger.valueOf(0).toString(
                 16)));
@@ -1156,12 +948,6 @@
     /**
      * @tests java.math.BigInteger#and(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "and",
-        args = {java.math.BigInteger.class}
-    )
     public void test_andLjava_math_BigInteger() {
         for (BigInteger[] element : booleanPairs) {
             BigInteger i1 = element[0], i2 = element[1];
@@ -1178,12 +964,6 @@
     /**
      * @tests java.math.BigInteger#or(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "or",
-        args = {java.math.BigInteger.class}
-    )
     public void test_orLjava_math_BigInteger() {
         for (BigInteger[] element : booleanPairs) {
             BigInteger i1 = element[0], i2 = element[1];
@@ -1200,12 +980,6 @@
     /**
      * @tests java.math.BigInteger#xor(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "xor",
-        args = {java.math.BigInteger.class}
-    )
     public void test_xorLjava_math_BigInteger() {
         for (BigInteger[] element : booleanPairs) {
             BigInteger i1 = element[0], i2 = element[1];
@@ -1222,12 +996,6 @@
     /**
      * @tests java.math.BigInteger#not()
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "not",
-        args = {}
-    )
     public void test_not() {
         for (BigInteger[] element : booleanPairs) {
             BigInteger i1 = element[0];
@@ -1242,12 +1010,6 @@
     /**
      * @tests java.math.BigInteger#andNot(java.math.BigInteger)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "andNot",
-        args = {java.math.BigInteger.class}
-    )
     public void test_andNotLjava_math_BigInteger() {
         for (BigInteger[] element : booleanPairs) {
             BigInteger i1 = element[0], i2 = element[1];
@@ -1279,12 +1041,6 @@
     }
     
 
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Regression test",
-        method = "clone",
-        args = {}
-    )
     public void testClone() {
         // Regression test for HARMONY-1770
         MyBigInteger myBigInteger = new MyBigInteger("12345");
diff --git a/math/src/test/java/tests/api/java/math/MathContextTest.java b/math/src/test/java/tests/api/java/math/MathContextTest.java
index 0051b44..dadfd12 100644
--- a/math/src/test/java/tests/api/java/math/MathContextTest.java
+++ b/math/src/test/java/tests/api/java/math/MathContextTest.java
@@ -17,71 +17,15 @@
 
 package tests.api.java.math;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
 
-@TestTargetClass(MathContext.class)
 public class MathContextTest extends junit.framework.TestCase {
 
     /**
      * @tests java.math.MathContext#MathContext(...)
      */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "MathContext",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "MathContext",
-            args = {int.class, java.math.RoundingMode.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "MathContext",
-            args = {java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getPrecision",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getRoundingMode",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "equals",
-            args = {java.lang.Object.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "hashCode",
-            args = {}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "toString",
-            args = {}
-        )
-    })
     public void test_MathContextConstruction() {
         String a = "-12380945E+61";
         BigDecimal aNumber = new BigDecimal(a);
@@ -132,4 +76,4 @@
                 res);
     }
 
-}
\ No newline at end of file
+}
diff --git a/math/src/test/java/tests/api/java/math/RoundingModeTest.java b/math/src/test/java/tests/api/java/math/RoundingModeTest.java
index e0946b3..1549301 100644
--- a/math/src/test/java/tests/api/java/math/RoundingModeTest.java
+++ b/math/src/test/java/tests/api/java/math/RoundingModeTest.java
@@ -17,26 +17,14 @@
 
 package tests.api.java.math;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 
-@TestTargetClass(RoundingMode.class)
 public class RoundingModeTest extends junit.framework.TestCase {
 
     /**
      * @tests java.math.RoundingMode#valueOf(int)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "valueOf",
-        args = {int.class}
-    )
     public void test_valueOfI() {
         assertEquals("valueOf failed for ROUND_CEILING", RoundingMode.valueOf(BigDecimal.ROUND_CEILING), RoundingMode.CEILING);
         assertEquals("valueOf failed for ROUND_DOWN", RoundingMode.valueOf(BigDecimal.ROUND_DOWN), RoundingMode.DOWN);
diff --git a/math/src/test/java/tests/math/AllTests.java b/math/src/test/java/tests/math/AllTests.java
index 2773ad6..64fb60d 100644
--- a/math/src/test/java/tests/math/AllTests.java
+++ b/math/src/test/java/tests/math/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the Math project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Math test suites");
+        TestSuite suite = new TestSuite("All Math test suites");
 
         suite.addTest(tests.api.java.math.AllTests.suite());
         suite.addTest(org.apache.harmony.math.tests.java.math.AllTests.suite());
diff --git a/nio/src/main/java/java/nio/Buffer.java b/nio/src/main/java/java/nio/Buffer.java
index b4bdc1c..02e3a14 100644
--- a/nio/src/main/java/java/nio/Buffer.java
+++ b/nio/src/main/java/java/nio/Buffer.java
@@ -52,7 +52,7 @@
     final static int UNSET_MARK = -1;
 
     /**
-     * The capacity of this buffer, which never change.
+     * The capacity of this buffer, which never changes.
      */
     final int capacity;
 
@@ -79,41 +79,18 @@
     /**
      * The log base 2 of the element size of this buffer.  Each typed subclass
      * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this
-     * value.  The value is used by native code to avoid the need for costly
-     * 'instanceof' tests.
-     *
+     * value.  The value is used by JNI code in frameworks/base/ to avoid the
+     * need for costly 'instanceof' tests.
      */
     int _elementSizeShift;
 
     /**
-     * Returns the array associated with this buffer, or null if none exists.
-     * Each typed subclass (ByteBuffer, CharBuffer, etc.) overrides this method
-     * to call its array() method with appropriate checks.
-     *
-     * @return a primitive array or null
-     */
-    Object _array() {
-        return null;
-    }
-
-    /**
-     * Returns the offset into the backing array, if one exists, otherwise 0.
-     * Each typed subclass (ByteBuffer, CharBuffer, etc.) overrides this method
-     * to call its arrayOffset() method with appropriate checks.
-     *
-     * @return the array offset, or 0
-     */
-    int _arrayOffset() {
-        return 0;
-    }
-
-    /**
      * For direct buffers, the effective address of the data.  This is set
      * on first use.  If the field is zero, this is either not a direct
      * buffer or the field has not been initialized, and you need to issue
      * the getEffectiveAddress() call and use the result of that.
      *
-     * This is strictly an optimization.
+     * This is an optimization used by the GetDirectBufferAddress JNI call.
      */
     int effectiveDirectAddress = 0;
     // END android-added
@@ -133,6 +110,44 @@
     }
 
     /**
+     * Returns the array that backs this buffer (optional operation).
+     * The returned value is the actual array, not a copy, so modifications
+     * to the array write through to the buffer.
+     *
+     * <p>Subclasses should override this method with a covariant return type
+     * to provide the exact type of the array.
+     *
+     * <p>Use {@code hasArray} to ensure this method won't throw.
+     * (A separate call to {@code isReadOnly} is not necessary.)
+     *
+     * @return the array
+     * @throws ReadOnlyBufferException if the buffer is read-only
+     *         UnsupportedOperationException if the buffer does not expose an array
+     * @since 1.6
+     * @hide
+     */
+    public abstract Object array();
+
+    /**
+     * Returns the offset into the array returned by {@code array} of the first
+     * element of the buffer (optional operation). The backing array (if there is one)
+     * is not necessarily the same size as the buffer, and position 0 in the buffer is
+     * not necessarily the 0th element in the array. Use
+     * {@code buffer.array()[offset + buffer.arrayOffset()} to access element {@code offset}
+     * in {@code buffer}.
+     *
+     * <p>Use {@code hasArray} to ensure this method won't throw.
+     * (A separate call to {@code isReadOnly} is not necessary.)
+     *
+     * @return the offset
+     * @throws ReadOnlyBufferException if the buffer is read-only
+     *         UnsupportedOperationException if the buffer does not expose an array
+     * @since 1.6
+     * @hide
+     */
+    public abstract int arrayOffset();
+
+    /**
      * Returns the capacity of this buffer.
      * 
      * @return the number of elements that are contained in this buffer.
@@ -176,6 +191,16 @@
     }
 
     /**
+     * Returns true if {@code array} and {@code arrayOffset} won't throw. This method does not
+     * return true for buffers not backed by arrays because the other methods would throw
+     * {@code UnsupportedOperationException}, nor does it return true for buffers backed by
+     * read-only arrays, because the other methods would throw {@code ReadOnlyBufferException}.
+     * @since 1.6
+     * @hide
+     */
+    public abstract boolean hasArray();
+
+    /**
      * Indicates if there are elements remaining in this buffer, that is if
      * {@code position < limit}.
      * 
@@ -187,6 +212,13 @@
     }
 
     /**
+     * Returns true if this is a direct buffer.
+     * @since 1.6
+     * @hide
+     */
+    public abstract boolean isDirect();
+
+    /**
      * Indicates whether this buffer is read-only.
      * 
      * @return {@code true} if this buffer is read-only, {@code false}
diff --git a/nio/src/main/java/java/nio/ByteBuffer.java b/nio/src/main/java/java/nio/ByteBuffer.java
index 821bbed..71db2d3 100644
--- a/nio/src/main/java/java/nio/ByteBuffer.java
+++ b/nio/src/main/java/java/nio/ByteBuffer.java
@@ -126,9 +126,7 @@
      */
     ByteBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 0;
-        // END android-added
     }
 
     /**
@@ -161,24 +159,6 @@
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override
-    Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override
-    int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a char buffer which is based on the remaining content of this
      * byte buffer.
@@ -631,13 +611,6 @@
      */
     public abstract short getShort(int index);
 
-    /**
-     * Indicates whether this buffer is based on a byte array and provides
-     * read/write access.
-     * 
-     * @return {@code true} if this buffer is based on a byte array and provides
-     *         read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/CharBuffer.java b/nio/src/main/java/java/nio/CharBuffer.java
index ea31234..d743017 100644
--- a/nio/src/main/java/java/nio/CharBuffer.java
+++ b/nio/src/main/java/java/nio/CharBuffer.java
@@ -153,59 +153,17 @@
      */
     CharBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 1;
-        // END android-added
     }
 
-    /**
-     * Returns the char array which this buffer is based on, if there is one.
-     * 
-     * @return the char array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final char[] array() {
         return protectedArray();
     }
 
-    /**
-     * Returns the offset of the char array which this buffer is based on, if
-     * there is one.
-     * <p>
-     * The offset is the index of the array corresponds to the zero position of
-     * the buffer.
-     *
-     * @return the offset of the char array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int arrayOffset() {
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override
-    Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override
-    int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a read-only buffer that shares its content with this buffer.
      * <p>
@@ -404,12 +362,6 @@
      */
     public abstract char get(int index);
 
-    /**
-     * Indicates whether this buffer is based on a char array and is read/write.
-     *
-     * @return {@code true} if this buffer is based on a byte array and provides
-     *         read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/DirectByteBuffer.java b/nio/src/main/java/java/nio/DirectByteBuffer.java
index 9bf6813..f8b16e0 100644
--- a/nio/src/main/java/java/nio/DirectByteBuffer.java
+++ b/nio/src/main/java/java/nio/DirectByteBuffer.java
@@ -20,7 +20,6 @@
 import org.apache.harmony.luni.platform.PlatformAddress;
 import org.apache.harmony.luni.platform.PlatformAddressFactory;
 import org.apache.harmony.nio.internal.DirectBuffer;
-import org.apache.harmony.nio.internal.nls.Messages;
 
 /**
  * DirectByteBuffer, ReadWriteDirectByteBuffer and ReadOnlyDirectByteBuffer
@@ -227,9 +226,7 @@
 
     public final void addressValidityCheck() {
         if (!isAddressValid()) {
-            // nio.08=Cannot use the direct byte buffer after it has been
-            // explicitly freed.
-            throw new IllegalStateException(Messages.getString("nio.08")); //$NON-NLS-1$
+            throw new IllegalStateException("Cannot use a direct byte buffer after it has been explicitly freed");
         }
     }
 
diff --git a/nio/src/main/java/java/nio/DoubleBuffer.java b/nio/src/main/java/java/nio/DoubleBuffer.java
index 3bea69e..5aece85 100644
--- a/nio/src/main/java/java/nio/DoubleBuffer.java
+++ b/nio/src/main/java/java/nio/DoubleBuffer.java
@@ -103,59 +103,17 @@
      */
     DoubleBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 3;
-        // END android-added
     }
 
-    /**
-     * Returns the double array which this buffer is based on, if there is one.
-     * 
-     * @return the double array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final double[] array() {
         return protectedArray();
     }
 
-    /**
-     * Returns the offset of the double array which this buffer is based on, if
-     * there is one.
-     * <p>
-     * The offset is the index of the array corresponding to the zero position
-     * of the buffer.
-     *
-     * @return the offset of the double array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int arrayOffset() {
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override
-    Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override
-    int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a read-only buffer that shares its content with this buffer.
      * <p>
@@ -344,13 +302,6 @@
      */
     public abstract double get(int index);
 
-    /**
-     * Indicates whether this buffer is based on a double array and is
-     * read/write.
-     *
-     * @return {@code true} if this buffer is based on a double array and
-     *         provides read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/FloatBuffer.java b/nio/src/main/java/java/nio/FloatBuffer.java
index 15239b1..ee1606c 100644
--- a/nio/src/main/java/java/nio/FloatBuffer.java
+++ b/nio/src/main/java/java/nio/FloatBuffer.java
@@ -105,57 +105,17 @@
      */
     FloatBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 2;
-        // END android-added
     }
 
-    /**
-     * Returns the float array which this buffer is based on, if there is one.
-     * 
-     * @return the float array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final float[] array() {
         return protectedArray();
     }
 
-    /**
-     * Returns the offset of the float array which this buffer is based on, if
-     * there is one.
-     * <p>
-     * The offset is the index of the array and corresponds to the zero position
-     * of the buffer.
-     *
-     * @return the offset of the float array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int arrayOffset() {
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a read-only buffer that shares its content with this buffer.
      * <p>
@@ -344,13 +304,6 @@
      */
     public abstract float get(int index);
 
-    /**
-     * Indicates whether this buffer is based on a float array and is
-     * read/write.
-     *
-     * @return {@code true} if this buffer is based on a float array and
-     *         provides read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/IntBuffer.java b/nio/src/main/java/java/nio/IntBuffer.java
index d95783b..83e8364 100644
--- a/nio/src/main/java/java/nio/IntBuffer.java
+++ b/nio/src/main/java/java/nio/IntBuffer.java
@@ -102,57 +102,17 @@
      */
     IntBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 2;
-        // END android-added
     }
 
-    /**
-     * Returns the int array which this buffer is based on, if there is one.
-     * 
-     * @return the int array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int[] array() {
         return protectedArray();
     }
 
-    /**
-     * Returns the offset of the int array which this buffer is based on, if
-     * there is one.
-     * <p>
-     * The offset is the index of the array corresponds to the zero position of
-     * the buffer.
-     *
-     * @return the offset of the int array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int arrayOffset() {
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a read-only buffer that shares its content with this buffer.
      * <p>
@@ -332,12 +292,6 @@
      */
     public abstract int get(int index);
 
-    /**
-     * Indicates whether this buffer is based on a int array and is read/write.
-     *
-     * @return {@code true} if this buffer is based on a int array and provides
-     *         read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/LongBuffer.java b/nio/src/main/java/java/nio/LongBuffer.java
index eecbf5e..e268b10 100644
--- a/nio/src/main/java/java/nio/LongBuffer.java
+++ b/nio/src/main/java/java/nio/LongBuffer.java
@@ -104,57 +104,17 @@
      */
     LongBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 3;
-        // END android-added
     }
 
-    /**
-     * Returns the long array which this buffer is based on, if there is one.
-     * 
-     * @return the long array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final long[] array() {
         return protectedArray();
     }
 
-    /**
-     * Returns the offset of the long array which this buffer is based on, if
-     * there is one.
-     * <p>
-     * The offset is the index of the array and corresponds to the zero position
-     * of the buffer.
-     *
-     * @return the offset of the long array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int arrayOffset() {
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a read-only buffer that shares its content with this buffer.
      * <p>
@@ -335,12 +295,6 @@
      */
     public abstract long get(int index);
 
-    /**
-     * Indicates whether this buffer is based on a long array and is read/write.
-     *
-     * @return {@code true} if this buffer is based on a long array and provides
-     *         read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/NIOAccess.java b/nio/src/main/java/java/nio/NIOAccess.java
index 979ee19..431cb8b 100644
--- a/nio/src/main/java/java/nio/NIOAccess.java
+++ b/nio/src/main/java/java/nio/NIOAccess.java
@@ -20,8 +20,7 @@
 import org.apache.harmony.nio.internal.DirectBuffer;
 
 /**
- * A class allowing native code to access the underlying data of
- * an NIO Buffer, breaking encapsulation in the name of efficiency.
+ * This class is used via JNI by code in frameworks/base/.
  */
 class NIOAccess {
 
@@ -68,7 +67,7 @@
      * there is none
      */
     static Object getBaseArray(Buffer b) {
-        return b._array();
+        return b.hasArray() ? b.array() : null;
     }
 
     /**
@@ -81,7 +80,6 @@
      * @return the data offset in bytes to the start of this Buffer's data
      */
     static int getBaseArrayOffset(Buffer b) {
-        return b._arrayOffset() << b._elementSizeShift;
+        return b.hasArray() ? (b.arrayOffset() << b._elementSizeShift) : 0;
     }
 }
-
diff --git a/nio/src/main/java/java/nio/ShortBuffer.java b/nio/src/main/java/java/nio/ShortBuffer.java
index 22d1b25..596dad2 100644
--- a/nio/src/main/java/java/nio/ShortBuffer.java
+++ b/nio/src/main/java/java/nio/ShortBuffer.java
@@ -104,57 +104,17 @@
      */
     ShortBuffer(int capacity) {
         super(capacity);
-        // BEGIN android-added
         _elementSizeShift = 1;
-        // END android-added
     }
 
-    /**
-     * Returns the short array which this buffer is based on, if there is one.
-     * 
-     * @return the short array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final short[] array() {
         return protectedArray();
     }
 
-    /**
-     * Returns the offset of the short array which this buffer is based on, if
-     * there is one.
-     * <p>
-     * The offset is the index of the array corresponding to the zero position
-     * of the buffer.
-     *
-     * @return the offset of the short array which this buffer is based on.
-     * @exception ReadOnlyBufferException
-     *                if this buffer is based on an array, but it is read-only.
-     * @exception UnsupportedOperationException
-     *                if this buffer is not based on an array.
-     */
     public final int arrayOffset() {
         return protectedArrayOffset();
     }
 
-    // BEGIN android-added
-    @Override Object _array() {
-        if (hasArray()) {
-            return array();
-        }
-        return null;
-    }
-
-    @Override int _arrayOffset() {
-        if (hasArray()) {
-            return arrayOffset();
-        }
-        return 0;
-    }
-    // END android-added
-
     /**
      * Returns a read-only buffer that shares its content with this buffer.
      * <p>
@@ -333,13 +293,6 @@
      */
     public abstract short get(int index);
 
-    /**
-     * Indicates whether this buffer is based on a short array and is
-     * read/write.
-     *
-     * @return {@code true} if this buffer is based on a short array and
-     *         provides read/write access, {@code false} otherwise.
-     */
     public final boolean hasArray() {
         return protectedHasArray();
     }
diff --git a/nio/src/main/java/java/nio/channels/package.html b/nio/src/main/java/java/nio/channels/package.html
index 7ca1a48..c16c811 100644
--- a/nio/src/main/java/java/nio/channels/package.html
+++ b/nio/src/main/java/java/nio/channels/package.html
@@ -5,6 +5,5 @@
       files, sockets or other structures that allow input and/or output of
       data. Selectors support multiplexing of non-blocking channels.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java b/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
index b474afa..ab898af 100644
--- a/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
+++ b/nio/src/main/java/java/nio/channels/spi/SelectorProvider.java
@@ -17,10 +17,7 @@
 
 package java.nio.channels.spi;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
 import java.nio.channels.Channel;
 import java.nio.channels.DatagramChannel;
 import java.nio.channels.Pipe;
@@ -28,8 +25,7 @@
 import java.nio.channels.SocketChannel;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.Enumeration;
-
+import java.util.ServiceLoader;
 import org.apache.harmony.luni.platform.Platform;
 import org.apache.harmony.nio.internal.SelectorProviderImpl;
 
@@ -38,19 +34,12 @@
  * providing instances of {@link DatagramChannel}, {@link Pipe},
  * {@link java.nio.channels.Selector} , {@link ServerSocketChannel}, and
  * {@link SocketChannel}. All the methods of this class are thread-safe.
- * <p>
- * A provider instance can be retrieved through a system property or the
- * configuration file in a jar file; if no provide is available that way then
+ *
+ * <p>A provider instance can be retrieved through a system property or the
+ * configuration file in a jar file; if no provider is available that way then
  * the system default provider is returned.
  */
-public abstract class SelectorProvider extends Object {
-
-    private static final String SYMBOL_COMMENT = "#"; //$NON-NLS-1$
-
-    private static final String PROVIDER_IN_SYSTEM_PROPERTY = "java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$
-
-    private static final String PROVIDER_IN_JAR_RESOURCE = "META-INF/services/java.nio.channels.spi.SelectorProvider"; //$NON-NLS-1$
-
+public abstract class SelectorProvider {
     private static SelectorProvider provider = null;
 
     private static Channel inheritedChannel;
@@ -87,107 +76,29 @@
      * @return the provider.
      */
     synchronized public static SelectorProvider provider() {
-        if (null == provider) {
-            provider = loadProviderByProperty();
-            if (null == provider) {
+        if (provider == null) {
+            provider = ServiceLoader.loadFromSystemProperty(SelectorProvider.class);
+            if (provider == null) {
                 provider = loadProviderByJar();
             }
-            if (null == provider) {
-                provider = AccessController
-                        .doPrivileged(new PrivilegedAction<SelectorProvider>() {
-                            public SelectorProvider run() {
-                                return new SelectorProviderImpl();
-                            }
-                        });
+            if (provider == null) {
+                provider = AccessController.doPrivileged(new PrivilegedAction<SelectorProvider>() {
+                    public SelectorProvider run() {
+                        return new SelectorProviderImpl();
+                    }
+                });
             }
         }
         return provider;
     }
 
-    /*
-     * load the provider in the jar file of class path.
-     */
-    static SelectorProvider loadProviderByJar() {
-        Enumeration<URL> enumeration = null;
-
-        ClassLoader classLoader = AccessController
-                .doPrivileged(new PrivilegedAction<ClassLoader>() {
-                    public ClassLoader run() {
-                        return ClassLoader.getSystemClassLoader();
-                    }
-                });
-        try {
-            enumeration = classLoader.getResources(PROVIDER_IN_JAR_RESOURCE);
-        } catch (IOException e) {
-            throw new Error(e);
-        }
-        if (null == enumeration) {
-            return null;
-        }
-        // for every jar, read until we find the provider name.
-        while (enumeration.hasMoreElements()) {
-            BufferedReader br = null;
-            String className = null;
-            try {
-                // BEGIN android-modified
-                br = new BufferedReader(
-                        new InputStreamReader(
-                                (enumeration.nextElement()).openStream()),
-                        8192);
-                // END android-modified
-            } catch (Exception e) {
-                continue;
-            }
-            try {
-                // only the first class is loaded ,as spec says, not the same as
-                // we do before.
-                while ((className = br.readLine()) != null) {
-                    className = className.trim();
-                    int siteComment = className.indexOf(SYMBOL_COMMENT);
-                    className = (-1 == siteComment) ? className : className
-                            .substring(0, siteComment);
-                    if (0 < className.length()) {
-                        return (SelectorProvider) classLoader.loadClass(
-                                className).newInstance();
-                    }
-                }
-            } catch (Exception e) {
-                throw new Error(e);
-            } finally {
-                try {
-                    br.close();
-                } catch (IOException ioe) {
-                    // Ignore
-                }
-            }
+    private static SelectorProvider loadProviderByJar() {
+        for (SelectorProvider provider : ServiceLoader.load(SelectorProvider.class, null)) {
+            return provider;
         }
         return null;
     }
 
-    /*
-     * Load by system property.
-     */
-    static SelectorProvider loadProviderByProperty() {
-        return AccessController
-                .doPrivileged(new PrivilegedAction<SelectorProvider>() {
-                    public SelectorProvider run() {
-                        try {
-                            final String className = System
-                                    .getProperty(PROVIDER_IN_SYSTEM_PROPERTY);
-                            if (null != className) {
-                                Class<?> spClass = ClassLoader
-                                        .getSystemClassLoader().loadClass(
-                                                className);
-                                return (SelectorProvider) spClass.newInstance();
-                            }
-                            return null;
-                        } catch (Exception e) {
-                            throw new Error(e);
-                        }
-                    }
-                });
-    }
-
     /**
      * Creates a new open {@code DatagramChannel}.
      * 
diff --git a/nio/src/main/java/java/nio/channels/spi/package.html b/nio/src/main/java/java/nio/channels/spi/package.html
index fde3d3e..e7b8a49 100644
--- a/nio/src/main/java/java/nio/channels/spi/package.html
+++ b/nio/src/main/java/java/nio/channels/spi/package.html
@@ -3,6 +3,5 @@
     <p>
       Service-provider classes for nio channels.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/nio/src/main/java/java/nio/package.html b/nio/src/main/java/java/nio/package.html
index 46b6aaf..b521b67 100644
--- a/nio/src/main/java/java/nio/package.html
+++ b/nio/src/main/java/java/nio/package.html
@@ -11,6 +11,5 @@
       array. Buffers also manage the position of the current element in the
       buffer, they can be rewound to the beginning and allow skipping of elements.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java b/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java
index e44422d..4a3b853 100644
--- a/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java
+++ b/nio/src/main/java/org/apache/harmony/nio/FileChannelFactory.java
@@ -27,7 +27,6 @@
 import org.apache.harmony.nio.internal.ReadOnlyFileChannel;
 import org.apache.harmony.nio.internal.ReadWriteFileChannel;
 import org.apache.harmony.nio.internal.WriteOnlyFileChannel;
-import org.apache.harmony.nio.internal.nls.Messages;
 import org.apache.harmony.luni.platform.IFileSystem;
 
 /**
@@ -48,8 +47,7 @@
             case IFileSystem.O_APPEND:
                 return new WriteOnlyFileChannel(stream, fd, true);
             default:
-                // nio.09=Unknown file channel type: {0}
-                throw new RuntimeException(Messages.getString("nio.09", mode)); //$NON-NLS-1$
+                throw new RuntimeException("Unknown file channel type " + mode);
         }
     }
 }
diff --git a/nio/src/main/java/org/apache/harmony/nio/Util.java b/nio/src/main/java/org/apache/harmony/nio/Util.java
deleted file mode 100644
index f895a51..0000000
--- a/nio/src/main/java/org/apache/harmony/nio/Util.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.nio;
-
-import org.apache.harmony.nio.internal.nls.Messages;
-
-/*
- * Static methods. Used by io and nio packages.
- * 
- */
-public final class Util {
-
-    // -------------------------------------------------------------------
-    // Constructor
-    // -------------------------------------------------------------------
-
-    /*
-     * No instance.
-     */
-    private Util() {
-        super();
-    }
-
-    // -------------------------------------------------------------------
-    // Routine methods.
-    // -------------------------------------------------------------------
-
-    /*
-     * Check array bounds method for methods like doSomething(Object[], offset,
-     * length). Exception throws order is IndexOutOfBoundsException for negative
-     * index, NullPointerException for null array, IndexOutOfBoundsException for
-     * offset+length > array.length
-     */
-    public static void assertArrayIndex(Object[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(boolean[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(byte[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(short[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(int[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(long[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(float[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(double[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    public static void assertArrayIndex(char[] array, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > array.length) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-
-    /*
-     * Check array bounds method for methods like doSomething(Object[], offset,
-     * length). Exception throws order is IndexOutOfBoundsException for negative
-     * index, IndexOutOfBoundsException for offset+length > array.length
-     */
-    public static void assertArrayIndex(int arrayLength, int offset, int length) {
-        if (offset < 0 || length < 0) {
-            // nio.05=Negative index specified
-            throw new IndexOutOfBoundsException(Messages.getString("nio.05")); //$NON-NLS-1$
-        }
-        if ((long) offset + (long) length > arrayLength) {
-            // nio.04=Size mismatch
-            throw new IndexOutOfBoundsException(Messages.getString("nio.04")); //$NON-NLS-1$
-        }
-    }
-}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java
index 9e72082..b289f2c 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/FileChannelImpl.java
@@ -41,7 +41,6 @@
 import org.apache.harmony.luni.platform.Platform;
 import org.apache.harmony.luni.platform.PlatformAddress;
 import org.apache.harmony.luni.platform.PlatformAddressFactory;
-import org.apache.harmony.nio.internal.nls.Messages;
 
 /*
  * The file channel impl class is the bridge between the logical channels
@@ -112,12 +111,10 @@
 
     protected FileLock basicLock(long position, long size, boolean shared,
             boolean wait) throws IOException {
-        if ((position < 0) || (size < 0)) {
-            // nio.0A=Lock position and size must be non-negative.
-            throw new IllegalArgumentException(Messages.getString("nio.0A")); //$NON-NLS-1$
+        if (position < 0 || size < 0) {
+            throw new IllegalArgumentException("Lock position and size must be non-negative");
         }
-        int lockType = shared ? IFileSystem.SHARED_LOCK_TYPE
-                : IFileSystem.EXCLUSIVE_LOCK_TYPE;
+        int lockType = shared ? IFileSystem.SHARED_LOCK_TYPE : IFileSystem.EXCLUSIVE_LOCK_TYPE;
         FileLock pendingLock = new FileLockImpl(this, position, size, shared);
         lockManager.addLock(pendingLock);
 
@@ -222,8 +219,7 @@
     public FileChannel position(long newPosition) throws IOException {
         openCheck();
         if (newPosition < 0) {
-            // nio.0B=New position must be non-negative.
-            throw new IllegalArgumentException(Messages.getString("nio.0B")); //$NON-NLS-1$
+            throw new IllegalArgumentException("New position must be non-negative");
         }
 
         synchronized (repositioningLock) {
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java b/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java
index 816afcf..8a98928 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/IOUtil.java
@@ -26,9 +26,6 @@
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
 
-import org.apache.harmony.nio.Util;
-import org.apache.harmony.nio.internal.nls.Messages;
-
 /**
  * Static methods for I/O util. Used by io package and nio package.
  */
@@ -59,8 +56,16 @@
                 }
                 return chars.get();
             }
-            // nio.06=InputStreamReader is closed.
-            throw new IOException(Messages.getString("nio.06")); //$NON-NLS-1$
+            throw new IOException("InputStreamReader is closed");
+        }
+    }
+
+    private static void assertArrayIndex(int arrayLength, int offset, int length) {
+        if (offset < 0 || length < 0) {
+            throw new IndexOutOfBoundsException("Negative index specified");
+        }
+        if ((long) offset + (long) length > arrayLength) {
+            throw new IndexOutOfBoundsException("Size mismatch");
         }
     }
 
@@ -75,7 +80,7 @@
                 if (length == 0) {
                     return 0;
                 }
-                Util.assertArrayIndex(buf, offset, length);
+                assertArrayIndex(buf.length, offset, length);
                 // read at least once
                 if (chars.limit() == chars.position()) {
                     fillBuf(in, bytes, chars, decoder);
@@ -105,8 +110,7 @@
                 chars.position(chars.position() + needChars);
                 return length;
             }
-            // nio.06=InputStreamReader is closed.
-            throw new IOException(Messages.getString("nio.06")); //$NON-NLS-1$
+            throw new IOException("InputStreamReader is closed");
         }
     }
 
@@ -143,11 +147,17 @@
     public static void writeOutputStreamWriter(String str, int offset,
             int count, OutputStream out, ByteBuffer bytes,
             CharsetEncoder encoder, Object lock) throws IOException {
-        Util.assertArrayIndex(str.length(), offset, count);
+        assertArrayIndex(str.length(), offset, count);
         CharBuffer chars = CharBuffer.wrap(str, offset, count + offset);
         convert(lock, encoder, bytes, chars, out);
     }
 
+    private static void checkEncoder(CharsetEncoder encoder) throws IOException {
+        if (encoder == null) {
+            throw new IOException("Writer is closed");
+        }
+    }
+
     /*
      * Write method for OutputStreamWriter and Channels.
      */
@@ -155,10 +165,7 @@
             ByteBuffer bytes, CharsetEncoder encoder, Object lock)
             throws IOException {
         synchronized (lock) {
-            if (encoder == null) {
-                // nio.07=Writer is closed.
-                throw new IOException(Messages.getString("nio.07")); //$NON-NLS-1$
-            }
+            checkEncoder(encoder);
             CharBuffer chars = CharBuffer.wrap(new char[] { (char) oneChar });
             convert(lock, encoder, bytes, chars, out);
         }
@@ -170,7 +177,7 @@
     public static void writeOutputStreamWriter(char[] buf, int offset,
             int count, OutputStream out, ByteBuffer bytes,
             CharsetEncoder encoder, Object lock) throws IOException {
-        Util.assertArrayIndex(buf, offset, count);
+        assertArrayIndex(buf.length, offset, count);
         CharBuffer chars = CharBuffer.wrap(buf, offset, count);
         convert(lock, encoder, bytes, chars, out);
     }
@@ -182,10 +189,7 @@
             ByteBuffer bytes, CharsetEncoder encoder, Object lock)
             throws IOException {
         synchronized (lock) {
-            if (encoder == null) {
-                // nio.07=Writer is closed.
-                throw new IOException(Messages.getString("nio.07")); //$NON-NLS-1$
-            }
+            checkEncoder(encoder);
             int position;
             if ((position = bytes.position()) > 0) {
                 bytes.flip();
@@ -203,10 +207,7 @@
             ByteBuffer bytes, CharBuffer chars, OutputStream out)
             throws IOException {
         synchronized (lock) {
-            if (encoder == null) {
-                // nio.07=Writer is closed.
-                throw new IOException(Messages.getString("nio.07")); //$NON-NLS-1$
-            }
+            checkEncoder(encoder);
             CoderResult result = encoder.encode(chars, bytes, true);
             while (true) {
                 if (result.isError()) {
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java b/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java
index b598c15..94d6219 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/MappedByteBufferFactory.java
@@ -56,7 +56,7 @@
          * than Integer.MAX_VALUE, so long to int cast is safe here.
          */
         return (MappedByteBuffer) constructor.newInstance(new Object[] { addr,
-                new Integer((int) size), new Integer(offset),
-                new Integer(mapmode) });
+                Integer.valueOf((int) size), Integer.valueOf(offset),
+                Integer.valueOf(mapmode) });
     }
 }
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
index 22d1b4a..3aa063c 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
@@ -46,15 +46,6 @@
 public class ServerSocketChannelImpl extends ServerSocketChannel implements
         FileDescriptorHandler {
 
-    // status un-init, not initialized.
-    private static final int SERVER_STATUS_UNINIT = -1;
-
-    // status after open and before closed.
-    private static final int SERVER_STATUS_OPEN = 0;
-
-    // status closed.
-    private static final int SERVER_STATUS_CLOSED = 1;
-
     // The fd to interact with native code
     private final FileDescriptor fd;
 
@@ -63,8 +54,6 @@
 
     private final SocketImpl impl;
 
-    int status = SERVER_STATUS_UNINIT;
-
     // whether the socket is bound
     boolean isBound = false;
 
@@ -77,7 +66,6 @@
      */
     public ServerSocketChannelImpl(SelectorProvider sp) throws IOException {
         super(sp);
-        status = SERVER_STATUS_OPEN;
         fd = new FileDescriptor();
         Platform.getNetworkSystem().createStreamSocket(fd,
                 NetUtil.preferIPv4Stack());
@@ -89,7 +77,6 @@
     @SuppressWarnings("unused")
     private ServerSocketChannelImpl() throws IOException {
         super(SelectorProvider.provider());
-        status = SERVER_STATUS_OPEN;
         fd = new FileDescriptor();
         impl = new PlainServerSocketImpl(fd);
         socket = new ServerSocketAdapter(impl, this);
@@ -175,7 +162,6 @@
      * @see java.nio.channels.spi.AbstractSelectableChannel#implCloseSelectableChannel()
      */
     synchronized protected void implCloseSelectableChannel() throws IOException {
-        status = SERVER_STATUS_CLOSED;
         if (!socket.isClosed()) {
             socket.close();
         }
@@ -296,7 +282,6 @@
                 } else {
                     super.close();
                 }
-                channelImpl.status = SERVER_STATUS_CLOSED;
             }
         }
     }
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
index 40915f6..c6a170d 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
@@ -53,7 +53,6 @@
 //import org.apache.harmony.luni.util.ErrorCodeException; android-removed
 import org.apache.harmony.luni.util.Msg;
 import org.apache.harmony.nio.AddressUtil;
-import org.apache.harmony.nio.internal.nls.Messages;
 
 /*
  * The default implementation class of java.nio.channels.SocketChannel.
@@ -868,7 +867,7 @@
                 throws SocketException {
             checkOpen();
             if (size < 1) {
-                throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$
+                throw new IllegalArgumentException(Msg.getString("K0035"));
             }
             socketImpl
                     .setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
@@ -885,7 +884,7 @@
         public synchronized void setSendBufferSize(int size) throws SocketException {
             checkOpen();
             if (size < 1) {
-                throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$
+                throw new IllegalArgumentException(Msg.getString("K0035"));
             }
             socketImpl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
         }
@@ -894,7 +893,7 @@
         public void setSoLinger(boolean on, int timeout) throws SocketException {
             checkOpen();
             if (on && timeout < 0) {
-                throw new IllegalArgumentException(Msg.getString("K0045")); //$NON-NLS-1$
+                throw new IllegalArgumentException(Msg.getString("K0045"));
             }
             int val = on ? (65535 < timeout ? 65535 : timeout) : -1;
             socketImpl.setOption(SocketOptions.SO_LINGER, Integer.valueOf(val));
@@ -904,7 +903,7 @@
         public synchronized void setSoTimeout(int timeout) throws SocketException {
             checkOpen();
             if (timeout < 0) {
-                throw new IllegalArgumentException(Msg.getString("K0036")); //$NON-NLS-1$
+                throw new IllegalArgumentException(Msg.getString("K0036"));
             }
             socketImpl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
         }
@@ -929,17 +928,9 @@
          */
         @Override
         public OutputStream getOutputStream() throws IOException {
-            if (!channel.isOpen()) {
-                // nio.00=Socket is closed
-                throw new SocketException(Messages.getString("nio.00")); //$NON-NLS-1$
-            }
-            if (!channel.isConnected()) {
-                // nio.01=Socket is not connected
-                throw new SocketException(Messages.getString("nio.01")); //$NON-NLS-1$
-            }
+            checkOpenAndConnected();
             if (isOutputShutdown()) {
-                // nio.02=Socket output is shutdown
-                throw new SocketException(Messages.getString("nio.02")); //$NON-NLS-1$
+                throw new SocketException("Socket output is shutdown");
             }
             return new SocketChannelOutputStream(channel);
         }
@@ -949,28 +940,28 @@
          */
         @Override
         public InputStream getInputStream() throws IOException {
-            if (!channel.isOpen()) {
-                // nio.00=Socket is closed
-                throw new SocketException(Messages.getString("nio.00")); //$NON-NLS-1$
-            }
-            if (!channel.isConnected()) {
-                // nio.01=Socket is not connected
-                throw new SocketException(Messages.getString("nio.01")); //$NON-NLS-1$
-            }
+            checkOpenAndConnected();
             if (isInputShutdown()) {
-                // nio.03=Socket input is shutdown
-                throw new SocketException(Messages.getString("nio.03")); //$NON-NLS-1$
+                throw new SocketException("Socket input is shutdown");
             }
             return new SocketChannelInputStream(channel);
         }
-
+        
+        private void checkOpenAndConnected() throws SocketException {
+            if (!channel.isOpen()) {
+                throw new SocketException("Socket is closed");
+            }
+            if (!channel.isConnected()) {
+                throw new SocketException("Socket is not connected");
+            }
+        }
+        
         /*
          * Checks whether the channel is open.
          */
         private void checkOpen() throws SocketException {
             if (isClosed()) {
-                // nio.00=Socket is closed
-                throw new SocketException(Messages.getString("nio.00")); //$NON-NLS-1$
+                throw new SocketException("Socket is closed");
             }
         }
 
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/nls/Messages.java b/nio/src/main/java/org/apache/harmony/nio/internal/nls/Messages.java
deleted file mode 100644
index d291f12..0000000
--- a/nio/src/main/java/org/apache/harmony/nio/internal/nls/Messages.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-package org.apache.harmony.nio.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.nio.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.nio.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/nls/messages.properties b/nio/src/main/java/org/apache/harmony/nio/internal/nls/messages.properties
deleted file mode 100644
index 79d1c84..0000000
--- a/nio/src/main/java/org/apache/harmony/nio/internal/nls/messages.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# messages for EN locale
-nio.00=Socket is closed
-nio.01=Socket is not connected
-nio.02=Socket output is shutdown
-nio.03=Socket input is shutdown
-nio.04=Size mismatch
-nio.05=Negative index specified
-nio.06=InputStreamReader is closed.
-nio.07=Writer is closed.
-nio.08=Cannot use the direct byte buffer after it has been explicitly freed.
-nio.09=Unknown file channel type: {0}
-nio.0A=Lock position and size must be non-negative.
-nio.0B=New position must be non-negative.
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java
index 6bf13f1..e88de9a 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/AllTests.java
@@ -25,13 +25,8 @@
  * 
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.nio");
+        TestSuite suite = new TestSuite("Tests for java.nio");
         //$JUnit-BEGIN$
         suite.addTestSuite(BufferOverflowExceptionTest.class);
         suite.addTestSuite(BufferUnderflowExceptionTest.class);
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java
index 069b056..d348c3d 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/ByteOrderTest.java
@@ -32,10 +32,6 @@
 @TestTargetClass(ByteOrder.class)
 public class ByteOrderTest extends TestCase {
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(ByteOrderTest.class);
-    }
-
     @TestTargetNew(
         level = TestLevel.COMPLETE,
         notes = "",
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AllTests.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AllTests.java
index 8031c5f..29cd201 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AllTests.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(AllTests.class.getName());
+        TestSuite suite = new TestSuite(AllTests.class.getName());
         //$JUnit-BEGIN$
         suite.addTestSuite(AlreadyConnectedExceptionTest.class);
         suite.addTestSuite(AsynchronousCloseExceptionTest.class);
diff --git a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AllTests.java b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AllTests.java
index 1b5e12e..bd94f8d 100644
--- a/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AllTests.java
+++ b/nio/src/test/java/org/apache/harmony/nio/tests/java/nio/channels/spi/AllTests.java
@@ -22,8 +22,7 @@
 public class AllTests {
 
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "Test for tests.api.java.nio.channels.spi");
+        TestSuite suite = new TestSuite("Test for tests.api.java.nio.channels.spi");
         //$JUnit-BEGIN$
         suite.addTestSuite(AbstractInterruptibleChannelTest.class);
         suite.addTestSuite(AbstractSelectorTest.class);
diff --git a/nio/src/test/java/tests/nio/AllTests.java b/nio/src/test/java/tests/nio/AllTests.java
index ff50aa5..07f0491 100644
--- a/nio/src/test/java/tests/nio/AllTests.java
+++ b/nio/src/test/java/tests/nio/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the Math project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Math test suites");
+        TestSuite suite = new TestSuite("All Math test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.nio.tests.java.nio.AllTests.suite());
         suite.addTest(org.apache.harmony.nio.tests.java.nio.channels.AllTests.suite());
diff --git a/nio_char/src/main/java/java/nio/charset/Charset.java b/nio_char/src/main/java/java/nio/charset/Charset.java
index 724699f..7135d00 100644
--- a/nio_char/src/main/java/java/nio/charset/Charset.java
+++ b/nio_char/src/main/java/java/nio/charset/Charset.java
@@ -17,6 +17,7 @@
 
 package java.nio.charset;
 
+import com.ibm.icu4jni.charset.NativeConverter;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -34,14 +35,10 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
-import java.util.Vector;
-
-// BEGIN android-changed
-import com.ibm.icu4jni.charset.CharsetProviderICU;
-// END android-changed
 
 /**
  * A charset defines a mapping between a Unicode character sequence and a byte
@@ -94,13 +91,7 @@
 
     private static ClassLoader systemClassLoader;
 
-    // built in provider instance, assuming thread-safe
-    // BEGIN android-changed
-    private static final CharsetProviderICU _builtInProvider;
-    // END android-changed
-
-    // cached built in charsets
-    private static TreeMap<String, Charset> _builtInCharsets = null;
+    private static SortedMap<String, Charset> cachedBuiltInCharsets;
 
     private final String canonicalName;
 
@@ -112,19 +103,6 @@
 
     private static boolean inForNameInternal = false;
 
-    static {
-        /*
-         * Create built-in charset provider even if no privilege to access
-         * charset provider.
-         */
-        _builtInProvider = AccessController
-                .doPrivileged(new PrivilegedAction<CharsetProviderICU>() {
-                    public CharsetProviderICU run() {
-                         return new CharsetProviderICU();
-                   }
-                });
-    }
-
     /**
      * Constructs a <code>Charset</code> object. Duplicated aliases are
      * ignored.
@@ -147,7 +125,7 @@
         this.canonicalName = canonicalName;
         // check each alias and put into a set
         this.aliasesSet = new HashSet<String>();
-        if (null != aliases) {
+        if (aliases != null) {
             for (int i = 0; i < aliases.length; i++) {
                 checkCharsetName(aliases[i]);
                 this.aliasesSet.add(aliases[i]);
@@ -234,8 +212,7 @@
     /*
      * Add the charsets supported by the given provider to the map.
      */
-    private static void addCharsets(CharsetProvider cp,
-            TreeMap<String, Charset> charsets) {
+    private static void addCharsets(CharsetProvider cp, Map<String, Charset> charsets) {
         Iterator<Charset> it = cp.charsets();
         while (it.hasNext()) {
             Charset cs = it.next();
@@ -264,15 +241,13 @@
      * specified by this configuration file to the map.
      */
     private static void loadConfiguredCharsets(URL configFile,
-            ClassLoader contextClassLoader, TreeMap<String, Charset> charsets) {
+            ClassLoader contextClassLoader, Map<String, Charset> charsets) {
         BufferedReader reader = null;
         try {
             InputStream is = configFile.openStream();
             // Read each line for charset provider class names
-            // BEGIN android-modified
             reader = new BufferedReader(new InputStreamReader(is,
-                            PROVIDER_CONFIGURATION_FILE_ENCODING), 8192);
-            // END android-modified
+                    PROVIDER_CONFIGURATION_FILE_ENCODING));
             String providerClassName = reader.readLine();
             while (null != providerClassName) {
                 providerClassName = trimClassName(providerClassName);
@@ -315,57 +290,43 @@
         }
     }
 
+    private static synchronized SortedMap<String, Charset> getCachedBuiltInCharsets() {
+        if (cachedBuiltInCharsets == null) {
+            cachedBuiltInCharsets = new TreeMap<String, Charset>(String.CASE_INSENSITIVE_ORDER);
+            for (String charsetName : NativeConverter.getAvailableCharsetNames()) {
+                Charset charset = NativeConverter.charsetForName(charsetName);
+                cachedBuiltInCharsets.put(charset.name(), charset);
+            }
+        }
+        return cachedBuiltInCharsets;
+    }
+
     /**
-     * Gets a map of all available charsets supported by the runtime.
-     * <p>
-     * The returned map contains mappings from canonical names to corresponding
-     * instances of <code>Charset</code>. The canonical names can be considered
-     * as case-insensitive.
-     *
-     * @return an unmodifiable map of all available charsets supported by the
-     *         runtime
+     * Returns an immutable case-insensitive map from canonical names to {@code Charset} instances.
+     * If multiple charsets have the same canonical name, it is unspecified which is returned in
+     * the map. This method may be slow. If you know which charset you're looking for, use
+     * {@link #forName}.
+     * @return an immutable case-insensitive map from canonical names to {@code Charset} instances
      */
     @SuppressWarnings("unchecked")
     public static SortedMap<String, Charset> availableCharsets() {
-        // BEGIN android-removed
-        // // workaround: conflicted Charsets with icu4j 4.0
-        // Charset.forName("TIS-620");
-        // Charset.forName("windows-1258");
-        // Charset.forName("cp856");
-        // Charset.forName("cp922");
-        // END android-removed
+        // Start with a copy of the built-in charsets...
+        TreeMap<String, Charset> charsets = new TreeMap<String, Charset>(String.CASE_INSENSITIVE_ORDER);
+        charsets.putAll(getCachedBuiltInCharsets());
 
-        // Initialize the built-in charsets map cache if necessary
-        if (null == _builtInCharsets) {
-            synchronized (Charset.class) {
-                if (null == _builtInCharsets) {
-                    _builtInCharsets = new TreeMap<String, Charset>(
-                            IgnoreCaseComparator.getInstance());
-                    _builtInProvider.putCharsets(_builtInCharsets);
-                }
-            }
-        }
-
-        // Add built-in charsets
-        TreeMap<String, Charset> charsets = (TreeMap<String, Charset>) _builtInCharsets
-                .clone();
-
-        // Collect all charsets provided by charset providers
+        // Add all charsets provided by charset providers...
         ClassLoader contextClassLoader = getContextClassLoader();
         Enumeration<URL> e = null;
         try {
-            if (null != contextClassLoader) {
-                e = contextClassLoader
-                        .getResources(PROVIDER_CONFIGURATION_FILE_NAME);
+            if (contextClassLoader != null) {
+                e = contextClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME);
             } else {
                 getSystemClassLoader();
-                e = systemClassLoader
-                        .getResources(PROVIDER_CONFIGURATION_FILE_NAME);
+                e = systemClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME);
             }
             // Examine each configuration file
             while (e.hasMoreElements()) {
-                loadConfiguredCharsets(e.nextElement(), contextClassLoader,
-                        charsets);
+                loadConfiguredCharsets(e.nextElement(), contextClassLoader, charsets);
             }
         } catch (IOException ex) {
             // Unexpected ClassLoader exception, ignore
@@ -384,10 +345,8 @@
         try {
             InputStream is = configFile.openStream();
             // Read each line for charset provider class names
-            // BEGIN android-modified
             reader = new BufferedReader(new InputStreamReader(is,
-                            PROVIDER_CONFIGURATION_FILE_ENCODING), 8192);
-            // END android-modified
+                    PROVIDER_CONFIGURATION_FILE_ENCODING));
             String providerClassName = reader.readLine();
             while (null != providerClassName) {
                 providerClassName = trimClassName(providerClassName);
@@ -450,52 +409,34 @@
      */
     private synchronized static Charset forNameInternal(String charsetName)
             throws IllegalCharsetNameException {
-        Charset cs = cachedCharsetTable.get(charsetName);
-        if (null != cs) {
-            return cs;
-        }
 
-        if (null == charsetName) {
-            throw new IllegalArgumentException();
-        }
-        checkCharsetName(charsetName);
-        // try built-in charsets
-        // BEGIN android-removed
-        // if (_builtInProvider == null) {
-        //     _builtInProvider = new CharsetProviderICU();
-        // }
-        // END android-removed
-        cs = _builtInProvider.charsetForName(charsetName);
-        if (null != cs) {
-            cacheCharset(cs);
+        Charset cs = lookupCachedOrBuiltInCharset(charsetName);
+        if (cs != null || inForNameInternal) {
             return cs;
         }
 
         // collect all charsets provided by charset providers
-        ClassLoader contextClassLoader = getContextClassLoader();
-        Enumeration<URL> e = null;
         try {
-            if (null != contextClassLoader) {
-                e = contextClassLoader
-                        .getResources(PROVIDER_CONFIGURATION_FILE_NAME);
+            Enumeration<URL> e = null;
+            ClassLoader contextClassLoader = getContextClassLoader();
+            if (contextClassLoader != null) {
+                e = contextClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME);
             } else {
                 getSystemClassLoader();
                 if (systemClassLoader == null) {
                     // Non available during class library start-up phase
-                    e = new Vector<URL>().elements();
+                    return null;
                 } else {
-                    e = systemClassLoader
-                            .getResources(PROVIDER_CONFIGURATION_FILE_NAME);
+                    e = systemClassLoader.getResources(PROVIDER_CONFIGURATION_FILE_NAME);
                 }
             }
 
             // examine each configuration file
             while (e.hasMoreElements()) {
-			     inForNameInternal = true;
-			     cs = searchConfiguredCharsets(charsetName, contextClassLoader,
-                        e.nextElement());
-				 inForNameInternal = false;
-                if (null != cs) {
+                inForNameInternal = true;
+                cs = searchConfiguredCharsets(charsetName, contextClassLoader, e.nextElement());
+                inForNameInternal = false;
+                if (cs != null) {
                     cacheCharset(cs);
                     return cs;
                 }
@@ -503,26 +444,40 @@
         } catch (IOException ex) {
             // Unexpected ClassLoader exception, ignore
         } finally {
-		    inForNameInternal = false;
+            inForNameInternal = false;
         }
         return null;
     }
 
+    private synchronized static Charset lookupCachedOrBuiltInCharset(String charsetName) {
+        Charset cs = cachedCharsetTable.get(charsetName);
+        if (cs != null) {
+            return cs;
+        }
+        if (charsetName == null) {
+            throw new IllegalArgumentException();
+        }
+        checkCharsetName(charsetName);
+        cs = NativeConverter.charsetForName(charsetName);
+        if (cs != null) {
+            cacheCharset(cs);
+        }
+        return cs;
+    }
+
     /*
      * save charset into cachedCharsetTable
      */
-    private static void cacheCharset(Charset cs) {
-        if (!cachedCharsetTable.containsKey(cs.name())){
-            cachedCharsetTable.put(cs.name(), cs);  
+    private synchronized static void cacheCharset(Charset cs) {
+        // Cache the Charset by its canonical name...
+        String canonicalName = cs.name();
+        if (!cachedCharsetTable.containsKey(canonicalName)) {
+            cachedCharsetTable.put(canonicalName, cs);
         }
-        Set<String> aliasesSet = cs.aliases();
-        if (null != aliasesSet) {
-            Iterator<String> iter = aliasesSet.iterator();
-            while (iter.hasNext()) {
-                String alias = iter.next();
-                if (!cachedCharsetTable.containsKey(alias)) {
-                    cachedCharsetTable.put(alias, cs); 
-                }
+        // And all its aliases...
+        for (String alias : cs.aliasesSet) {
+            if (!cachedCharsetTable.containsKey(alias)) {
+                cachedCharsetTable.put(alias, cs);
             }
         }
     }
@@ -540,7 +495,7 @@
      */
     public static Charset forName(String charsetName) {
         Charset c = forNameInternal(charsetName);
-        if (null == c) {
+        if (c == null) {
             throw new UnsupportedCharsetException(charsetName);
         }
         return c;
@@ -556,34 +511,7 @@
      *             if the specified charset name is illegal.
      */
     public static synchronized boolean isSupported(String charsetName) {
-        if (inForNameInternal) {
-            Charset cs = cachedCharsetTable.get(charsetName);
-            if (null != cs) {
-                return true;
-            }
-
-            if (null == charsetName) {
-                throw new IllegalArgumentException();
-            }
-            checkCharsetName(charsetName);
-
-            // Try built-in charsets
-            // BEGIN android-removed
-            // if (_builtInProvider == null) {
-            //     _builtInProvider = new CharsetProviderICU();
-            // }
-            // END android-removed
-            cs = _builtInProvider.charsetForName(charsetName);
-            if (null != cs) {
-                cacheCharset(cs);
-                return true;
-            }
-            return false;
-        } else {
-            Charset cs = forNameInternal(charsetName);
-            return (null != cs);
-        }
-
+        return forNameInternal(charsetName) != null;
     }
 
     /**
@@ -820,34 +748,4 @@
         }
         return defaultCharset;
     }
-
-    /**
-     * A comparator that ignores case.
-     */
-    static class IgnoreCaseComparator implements Comparator<String> {
-
-        // the singleton
-        private static Comparator<String> c = new IgnoreCaseComparator();
-
-        /*
-         * Default constructor.
-         */
-        private IgnoreCaseComparator() {
-            // no action
-        }
-
-        /*
-         * Gets a single instance.
-         */
-        public static Comparator<String> getInstance() {
-            return c;
-        }
-
-        /*
-         * Compares two strings ignoring case.
-         */
-        public int compare(String s1, String s2) {
-            return s1.compareToIgnoreCase(s2);
-        }
-    }
 }
diff --git a/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java b/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
index dc243cc..393cad5 100644
--- a/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
+++ b/nio_char/src/main/java/java/nio/charset/CharsetDecoder.java
@@ -21,8 +21,6 @@
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 
-import org.apache.harmony.niochar.internal.nls.Messages;
-
 /**
  * A converter that can convert a byte sequence from a charset into a 16-bit
  * Unicode character sequence.
@@ -138,12 +136,10 @@
     protected CharsetDecoder(Charset charset, float averageCharsPerByte,
             float maxCharsPerByte) {
         if (averageCharsPerByte <= 0 || maxCharsPerByte <= 0) {
-            // niochar.00=Characters number for one byte must be positive.
-            throw new IllegalArgumentException(Messages.getString("niochar.00")); //$NON-NLS-1$
+            throw new IllegalArgumentException("averageCharsPerByte and maxCharsPerByte must be positive");
         }
         if (averageCharsPerByte > maxCharsPerByte) {
-            // niochar.01=averageCharsPerByte is greater than maxCharsPerByte
-            throw new IllegalArgumentException(Messages.getString("niochar.01")); //$NON-NLS-1$
+            throw new IllegalArgumentException("averageCharsPerByte is greater than maxCharsPerByte");
         }
         averChars = averageCharsPerByte;
         maxChars = maxCharsPerByte;
@@ -151,7 +147,7 @@
         status = INIT;
         malformAction = CodingErrorAction.REPORT;
         unmapAction = CodingErrorAction.REPORT;
-        replace = "\ufffd"; //$NON-NLS-1$
+        replace = "\ufffd";
     }
 
     /**
@@ -692,14 +688,11 @@
      *             mentioned above.
      */
     public final CharsetDecoder replaceWith(String newReplacement) {
-        if (null == newReplacement || newReplacement.length() == 0) {
-            // niochar.06=Replacement string cannot be null or empty.
-            throw new IllegalArgumentException(Messages.getString("niochar.06")); //$NON-NLS-1$
+        if (newReplacement == null || newReplacement.isEmpty()) {
+            throw new IllegalArgumentException("Replacement string cannot be null or empty");
         }
         if (newReplacement.length() > maxChars) {
-            // niochar.07=Replacement string's length cannot be larger than max
-            // characters per byte.
-            throw new IllegalArgumentException(Messages.getString("niochar.07")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Replacement string cannot be longer than max characters per byte");
         }
         replace = newReplacement;
         implReplaceWith(newReplacement);
diff --git a/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java b/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
index f24be92..daf2c08 100644
--- a/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
+++ b/nio_char/src/main/java/java/nio/charset/CharsetEncoder.java
@@ -20,8 +20,7 @@
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
-
-import org.apache.harmony.niochar.internal.nls.Messages;
+import java.util.Arrays;
 
 /**
  * A converter that can converts a 16-bit Unicode character sequence to a byte
@@ -168,12 +167,10 @@
     protected CharsetEncoder(Charset cs, float averageBytesPerChar,
             float maxBytesPerChar, byte[] replacement) {
         if (averageBytesPerChar <= 0 || maxBytesPerChar <= 0) {
-            // niochar.02=Bytes number for one character must be positive.
-            throw new IllegalArgumentException(Messages.getString("niochar.02")); //$NON-NLS-1$
+            throw new IllegalArgumentException("averageBytesPerChar and maxBytesPerChar must both be positive");
         }
         if (averageBytesPerChar > maxBytesPerChar) {
-            // niochar.03=averageBytesPerChar is greater than maxBytesPerChar.
-            throw new IllegalArgumentException(Messages.getString("niochar.03")); //$NON-NLS-1$
+            throw new IllegalArgumentException("averageBytesPerChar is greater than maxBytesPerChar");
         }
         this.cs = cs;
         averBytes = averageBytesPerChar;
@@ -221,8 +218,7 @@
             status = INIT;
         }
         if (status != INIT) {
-            // niochar.0B=Another encoding process is ongoing\!
-            throw new IllegalStateException(Messages.getString("niochar.0B")); //$NON-NLS-1$
+            throw new IllegalStateException("encoding already in progress");
         }
         CodingErrorAction malformBak = malformAction;
         CodingErrorAction unmapBak = unmapAction;
@@ -688,9 +684,8 @@
      *             if the given newAction is null.
      */
     public final CharsetEncoder onMalformedInput(CodingErrorAction newAction) {
-        if (null == newAction) {
-            // niochar.0C=Action on malformed input error cannot be null\!
-            throw new IllegalArgumentException(Messages.getString("niochar.0C")); //$NON-NLS-1$
+        if (newAction == null) {
+            throw new IllegalArgumentException("newAction == null");
         }
         malformAction = newAction;
         implOnMalformedInput(newAction);
@@ -710,11 +705,9 @@
      * @throws IllegalArgumentException
      *             if the given newAction is null.
      */
-    public final CharsetEncoder onUnmappableCharacter(
-            CodingErrorAction newAction) {
-        if (null == newAction) {
-            // niochar.0D=Action on unmappable character error cannot be null\!
-            throw new IllegalArgumentException(Messages.getString("niochar.0D")); //$NON-NLS-1$
+    public final CharsetEncoder onUnmappableCharacter(CodingErrorAction newAction) {
+        if (newAction == null) {
+            throw new IllegalArgumentException("newAction == null");
         }
         unmapAction = newAction;
         implOnUnmappableCharacter(newAction);
@@ -742,18 +735,16 @@
      *            the replacement byte array, cannot be null or empty, its
      *            length cannot be larger than <code>maxBytesPerChar</code>,
      *            and it must be legal replacement, which can be justified by
-     *            calling <code>isLegalReplacement(byte[] repl)</code>.
+     *            calling <code>isLegalReplacement(byte[] replacement)</code>.
      * @return this encoder.
      * @throws IllegalArgumentException
      *             if the given replacement cannot satisfy the requirement
      *             mentioned above.
      */
     public final CharsetEncoder replaceWith(byte[] replacement) {
-        if (null == replacement || 0 == replacement.length
-                || maxBytes < replacement.length
+        if (replacement == null || replacement.length == 0 || maxBytes < replacement.length
                 || !isLegalReplacement(replacement)) {
-            // niochar.0E=Replacement is illegal
-            throw new IllegalArgumentException(Messages.getString("niochar.0E")); //$NON-NLS-1$
+            throw new IllegalArgumentException("bad replacement: " + Arrays.toString(replacement));
         }
         replace = replacement;
         implReplaceWith(replacement);
diff --git a/nio_char/src/main/java/java/nio/charset/CoderResult.java b/nio_char/src/main/java/java/nio/charset/CoderResult.java
index 47df0dd..880d9fb 100644
--- a/nio_char/src/main/java/java/nio/charset/CoderResult.java
+++ b/nio_char/src/main/java/java/nio/charset/CoderResult.java
@@ -20,8 +20,6 @@
 import java.nio.BufferUnderflowException;
 import java.util.WeakHashMap;
 
-import org.apache.harmony.niochar.internal.nls.Messages;
-
 /**
  * Used to indicate the result of encoding/decoding. There are four types of
  * results:
@@ -124,9 +122,7 @@
                 return r;
             }
         }
-        // niochar.08=The length must be positive: {0}.
-        throw new IllegalArgumentException(Messages.getString(
-                "niochar.08", length)); //$NON-NLS-1$
+        throw new IllegalArgumentException("Length must be greater than 0; was " + length);
     }
 
     /**
@@ -154,9 +150,7 @@
                 return r;
             }
         }
-        // niochar.08=The length must be positive: {0}.
-        throw new IllegalArgumentException(Messages.getString(
-                "niochar.08", length)); //$NON-NLS-1$
+        throw new IllegalArgumentException("Length must be greater than 0; was " + length);
     }
 
     /**
@@ -216,14 +210,10 @@
      *             if this result is an overflow or underflow.
      */
     public int length() throws UnsupportedOperationException {
-        if (this.type == TYPE_MALFORMED_INPUT
-                || this.type == TYPE_UNMAPPABLE_CHAR) {
+        if (this.type == TYPE_MALFORMED_INPUT || this.type == TYPE_UNMAPPABLE_CHAR) {
             return this.length;
         }
-        // niochar.09=The length of the erroneous input is only meaningful to
-        // a malformed-input error or an unmappble character error
-        throw new UnsupportedOperationException(Messages
-                .getString("niochar.09")); //$NON-NLS-1$
+        throw new UnsupportedOperationException("length meaningless for " + toString());
     }
 
     /**
diff --git a/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java b/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java
index fad9fa6..d1c71ea 100644
--- a/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java
+++ b/nio_char/src/main/java/java/nio/charset/IllegalCharsetNameException.java
@@ -17,8 +17,6 @@
 
 package java.nio.charset;
 
-import org.apache.harmony.niochar.internal.nls.Messages;
-
 /**
  * An {@code IllegalCharsetNameException} is thrown when an illegal charset name
  * is encountered.
@@ -42,15 +40,12 @@
      *            the encountered illegal charset name.
      */
     public IllegalCharsetNameException(String charset) {
-        // niochar.0F=The illegal charset name is "{0}".
-        super(Messages.getString("niochar.0F", charset)); //$NON-NLS-1$
+        super(charset);
         this.charsetName = charset;
     }
 
     /**
-     * Gets the encountered illegal charset name.
-     * 
-     * @return the encountered illegal charset name.
+     * Returns the encountered illegal charset name.
      */
     public String getCharsetName() {
         return this.charsetName;
diff --git a/nio_char/src/main/java/java/nio/charset/MalformedInputException.java b/nio_char/src/main/java/java/nio/charset/MalformedInputException.java
index 0a93728..aa853bf 100644
--- a/nio_char/src/main/java/java/nio/charset/MalformedInputException.java
+++ b/nio_char/src/main/java/java/nio/charset/MalformedInputException.java
@@ -17,8 +17,6 @@
 
 package java.nio.charset;
 
-import org.apache.harmony.niochar.internal.nls.Messages;
-
 /**
  * A {@code MalformedInputException} is thrown when a malformed input is
  * encountered, for example if a byte sequence is illegal for the given charset.
@@ -53,14 +51,8 @@
         return this.inputLength;
     }
 
-    /**
-     * Gets a message describing this exception.
-     * 
-     * @return a message describing this exception.
-     */
     @Override
     public String getMessage() {
-        // niochar.05=Malformed input length is {0}.
-        return Messages.getString("niochar.05", this.inputLength); //$NON-NLS-1$
+        return "Length: " + inputLength;
     }
 }
diff --git a/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java b/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java
index db23a6f..b929023 100644
--- a/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java
+++ b/nio_char/src/main/java/java/nio/charset/UnmappableCharacterException.java
@@ -17,8 +17,6 @@
 
 package java.nio.charset;
 
-import org.apache.harmony.niochar.internal.nls.Messages;
-
 /**
  * An {@code UnmappableCharacterException} is thrown when an unmappable
  * character for the given charset is encountered.
@@ -45,22 +43,14 @@
     }
 
     /**
-     * Gets the length of the unmappable character.
-     * 
-     * @return the length of the unmappable character.
+     * Returns the length of the unmappable character.
      */
     public int getInputLength() {
         return this.inputLength;
     }
 
-    /**
-     * Gets a message describing this exception.
-     * 
-     * @return a message describing this exception.
-     */
     @Override
     public String getMessage() {
-        // niochar.0A=The unmappable character length is {0}.
-        return Messages.getString("niochar.0A", this.inputLength); //$NON-NLS-1$
+        return "Length: " + inputLength;
     }
 }
diff --git a/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java b/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java
index b5985b4..9bfdcfe 100644
--- a/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java
+++ b/nio_char/src/main/java/java/nio/charset/UnsupportedCharsetException.java
@@ -17,8 +17,6 @@
 
 package java.nio.charset;
 
-import org.apache.harmony.niochar.internal.nls.Messages;
-
 /**
  * An {@code UnsupportedCharsetException} is thrown when an unsupported charset
  * name is encountered.
@@ -42,8 +40,7 @@
      *            the encountered unsupported charset name.
      */
     public UnsupportedCharsetException(String charset) {
-        // niochar.04=The unsupported charset name is "{0}".
-        super(Messages.getString("niochar.04", charset)); //$NON-NLS-1$
+        super(charset);
         this.charsetName = charset;
     }
 
diff --git a/nio_char/src/main/java/java/nio/charset/package.html b/nio_char/src/main/java/java/nio/charset/package.html
index 175fb71..6554010 100644
--- a/nio_char/src/main/java/java/nio/charset/package.html
+++ b/nio_char/src/main/java/java/nio/charset/package.html
@@ -10,6 +10,5 @@
       de-/encoder pair that can be used to translate a byte stream. With the
       service provider package it is possible to use your own charsets.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/nio_char/src/main/java/java/nio/charset/spi/CharsetProvider.java b/nio_char/src/main/java/java/nio/charset/spi/CharsetProvider.java
index 6d5c66f..246da6a 100644
--- a/nio_char/src/main/java/java/nio/charset/spi/CharsetProvider.java
+++ b/nio_char/src/main/java/java/nio/charset/spi/CharsetProvider.java
@@ -21,8 +21,6 @@
 
 /**
  * The service provider class for character sets.
- * 
- * @since Android 1.0
  */
 public abstract class CharsetProvider {
 
@@ -36,7 +34,6 @@
      * @throws SecurityException
      *             if there is a security manager installed that does not permit
      *             the runtime permission labeled "charsetProvider".
-     * @since Android 1.0
      */
     protected CharsetProvider() {
         SecurityManager securityManager = System.getSecurityManager();
@@ -48,7 +45,6 @@
      * Returns an iterator over all the available charsets.
      * 
      * @return the iterator.
-     * @since Android 1.0
      */
     public abstract Iterator<Charset> charsets();
 
@@ -61,7 +57,6 @@
      * @param charsetName
      *            the canonical or alias name of a character set.
      * @return the charset, or <code>null</code> if unavailable.
-     * @since Android 1.0
      */
     public abstract Charset charsetForName(String charsetName);
 }
diff --git a/nio_char/src/main/java/java/nio/charset/spi/package.html b/nio_char/src/main/java/java/nio/charset/spi/package.html
index f7d9d2b..4e58391 100644
--- a/nio_char/src/main/java/java/nio/charset/spi/package.html
+++ b/nio_char/src/main/java/java/nio/charset/spi/package.html
@@ -3,6 +3,5 @@
     <p>
       Service-provider class for nio charset.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/nio_char/src/main/java/org/apache/harmony/niochar/internal/nls/Messages.java b/nio_char/src/main/java/org/apache/harmony/niochar/internal/nls/Messages.java
deleted file mode 100644
index f2fb652..0000000
--- a/nio_char/src/main/java/org/apache/harmony/niochar/internal/nls/Messages.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.niochar.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.niochar.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.niochar.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
-
diff --git a/nio_char/src/main/java/org/apache/harmony/niochar/internal/nls/messages.properties b/nio_char/src/main/java/org/apache/harmony/niochar/internal/nls/messages.properties
deleted file mode 100644
index 6737e2b..0000000
--- a/nio_char/src/main/java/org/apache/harmony/niochar/internal/nls/messages.properties
+++ /dev/null
@@ -1,32 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# messages for EN locale
-niochar.00=Characters number for one byte must be positive.
-niochar.01=averageCharsPerByte is greater than maxCharsPerByte
-niochar.02=Bytes number for one character must be positive.
-niochar.03=averageBytesPerChar is greater than maxBytesPerChar.
-niochar.04=The unsupported charset name is "{0}".
-niochar.05=Malformed input length is {0}.
-niochar.06=Replacement string cannot be null or empty.
-niochar.07=Replacement string's length cannot be larger than max characters per byte.
-niochar.08=The length must be positive: {0}.
-niochar.09=The length of the erroneous input is only meaningful to a malformed-input error or an unmappble character error
-niochar.0A=The unmappable character length is {0}.
-niochar.0B=Another encoding process is ongoing\!
-niochar.0C=Action on malformed input error cannot be null\!
-niochar.0D=Action on unmappable character error cannot be null\!
-niochar.0E=Replacement is illegal
-niochar.0F=The illegal charset name is "{0}".
diff --git a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/AllTests.java b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/AllTests.java
index 2bc537b..9c56d76 100644
--- a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/AllTests.java
+++ b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/AllTests.java
@@ -20,14 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "Test for org.apache.harmony.nio_char.tests.java.nio.charset");
+        TestSuite suite = new TestSuite("Test for org.apache.harmony.nio_char.tests.java.nio.charset");
         //$JUnit-BEGIN$
         suite.addTestSuite(ASCIICharsetEncoderTest.class);
         suite.addTestSuite(CharacterCodingExceptionTest.class);
diff --git a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/spi/AllTests.java b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/spi/AllTests.java
index 3e5f3a9..00ed64b 100644
--- a/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/spi/AllTests.java
+++ b/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/spi/AllTests.java
@@ -20,14 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "Suite of tests for the java.nio.charset.spi package.");
+        TestSuite suite = new TestSuite("Suite of tests for the java.nio.charset.spi package.");
         // $JUnit-BEGIN$
         suite.addTestSuite(CharsetProviderTest.class);
         // $JUnit-END$
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java b/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java
index f318960..933f341 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.java.nio.charset;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.java.nio.charset;");
 
         suite.addTestSuite(CharsetProviderTest.class);
         suite.addTestSuite(CharsetTest.class);
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
index 903c689..a2ae12e 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
@@ -140,6 +140,7 @@
     )
     @AndroidOnly("Looks like RI doesn't use current thread's context class "+
     "loader to lookup charset providers")
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void testIsSupported_And_ForName_NormalProvider() throws Exception {
         try {
             assertFalse(Charset.isSupported("mockCharset10"));
@@ -299,6 +300,7 @@
         method = "charsetForName",
         args = {String.class}
     )
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void testForName_InsufficientPrivilege() throws Exception {
         SecurityManager oldMan = System.getSecurityManager();
         System.setSecurityManager(new MockSecurityManager());
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java
index b9f9bc6..7f83414 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_GB2312.java
@@ -192,7 +192,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is not properly supported in Android!")
     @Override
     public void test_Decode() throws CharacterCodingException {
         super.test_Decode();
@@ -203,7 +202,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is not properly supported in Android!")
     @Override
     public void test_Encode() throws CharacterCodingException {
         super.test_Encode();
@@ -214,7 +212,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is mapped to GBK Android!")
     @Override
     public void test_nameMatch() {
         super.test_nameMatch();
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java
index 3f1afb5..bf070c0 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_ISO_2022_JP.java
@@ -385,7 +385,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is not properly supported in Android!")
     @Override
     public void test_Decode() throws CharacterCodingException {
         super.test_Decode();
@@ -396,7 +395,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is not properly supported in Android!")
     @Override
     public void test_Encode() throws CharacterCodingException {
         super.test_Encode();
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java
index 61685f1..39e7f31 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/Charset_MultiByte_x_windows_950.java
@@ -251,7 +251,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is not properly supported in Android!")
     @Override
     public void test_Encode() throws CharacterCodingException {
         super.test_Encode();
@@ -262,7 +261,6 @@
         method = "functionalCoDec_REPR",
         args = {}
     )
-    @KnownFailure("This Characterset is mapped to Big5 Android!")
     @Override
     public void test_nameMatch() {
         super.test_nameMatch();
diff --git a/nio_char/src/test/java/tests/nio_char/AllTests.java b/nio_char/src/test/java/tests/nio_char/AllTests.java
index 19a003c..4ab9247 100644
--- a/nio_char/src/test/java/tests/nio_char/AllTests.java
+++ b/nio_char/src/test/java/tests/nio_char/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the NIO_Char project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All NIO_Char test suites");
+        TestSuite suite = new TestSuite("All NIO_Char test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.nio_char.tests.java.nio.charset.AllTests.suite());
         suite.addTest(org.apache.harmony.nio_char.tests.java.nio.charset.spi.AllTests.suite());
diff --git a/openssl/src/main/java/org/openssl/NativeBN.java b/openssl/src/main/java/org/openssl/NativeBN.java
index fd796f8..9691204 100644
--- a/openssl/src/main/java/org/openssl/NativeBN.java
+++ b/openssl/src/main/java/org/openssl/NativeBN.java
@@ -96,11 +96,8 @@
     // op: 0 = reset; 1 = set; -1 = flip
     // uses BN_set_bit(), BN_clear_bit() and BN_is_bit_set()
 
-    public static native boolean BN_lshift(int r, int a, int n);
-    // int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
-//    public static native int BN_rshift(BigInteger r, BigInteger a, int n);
-    // int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
-
+    public static native boolean BN_shift(int r, int a, int n);
+    // int BN_shift(BIGNUM *r, const BIGNUM *a, int n);
 
     public static native boolean BN_add_word(int a, int w);
     // ATTENTION: w is treated as unsigned.
diff --git a/openssl/src/main/native/BNInterface.c b/openssl/src/main/native/BNInterface.c
index ff2a2ae..07f0288 100644
--- a/openssl/src/main/native/BNInterface.c
+++ b/openssl/src/main/native/BNInterface.c
@@ -509,72 +509,13 @@
 }
 
 /**
- * public static native int BN_lshift(int, int, int)
+ * public static native int BN_shift(int, int, int)
  */
-static jboolean NativeBN_BN_lshift(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, int n) {
-// LOGD("NativeBN_BN_lshift %p %p %d", r, a, n);
+static jboolean NativeBN_BN_shift(JNIEnv* env, jclass cls, BIGNUM* r, BIGNUM* a, int n) {
     if (!twoValidHandles(env, r, a)) return FALSE;
-    if (n >= 0) return BN_lshift(r, a, n);
-
-    n = -n;
-//    return BN_rshift(r, a, n);
-// Following code insourced from bn_shift.c in order to have bug fixed:
-// FIXME: Should report to openssl team!!!
-
-	int i,j,nw,lb,rb;
-	BN_ULONG *t,*f;
-	BN_ULONG l,tmp;
-
-	bn_check_top(r);
-	bn_check_top(a);
-
-	nw=n/BN_BITS2;
-	rb=n%BN_BITS2;
-	lb=BN_BITS2-rb;
-// Changed "nw > a->top || a->top == 0" to nw >= a->top" as considering this a bug:
-	if (nw >= a->top)
-		{
-		BN_zero(r);
-		return(1);
-		}
-	if (r != a)
-		{
-		r->neg=a->neg;
-		if (bn_wexpand(r,a->top-nw+1) == NULL) return(0);
-		}
-	else
-		{
-		if (n == 0)
-			return 1; /* or the copying loop will go berserk */
-		}
-
-	f= &(a->d[nw]);
-	t=r->d;
-	j=a->top-nw;
-	r->top=j;
-
-	if (rb == 0)
-		{
-		for (i=j; i != 0; i--)
-			*(t++)= *(f++);
-		}
-	else
-		{
-		l= *(f++);
-		for (i=j-1; i != 0; i--)
-			{
-			tmp =(l>>rb)&BN_MASK2;
-			l= *(f++);
-			*(t++) =(tmp|(l<<lb))&BN_MASK2;
-			}
-		*(t++) =(l>>rb)&BN_MASK2;
-		}
-	bn_correct_top(r);
-	bn_check_top(r);
-	return(1);
+    return (n >= 0) ? BN_lshift(r, a, n) : BN_rshift(r, a, -n);
 }
 
-
 /**
  * public static native boolean BN_add_word(int, int)
  */
@@ -698,7 +639,7 @@
 static jboolean NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass cls, BIGNUM* ret, int bits, jboolean safe,
         BIGNUM* add, BIGNUM* rem, jint cb) {
     if (!oneValidHandle(env, ret)) return FALSE;
-    return BN_generate_prime_ex(ret, bits, safe, add, rem, cb);
+    return BN_generate_prime_ex(ret, bits, safe, add, rem, (BN_GENCB*) cb);
 }
 
 /**
@@ -706,15 +647,9 @@
  */
 static jboolean NativeBN_BN_is_prime_ex(JNIEnv* env, jclass cls, BIGNUM* p, int nchecks, BN_CTX* ctx, jint cb) {
     if (!oneValidHandle(env, p)) return FALSE;
-    return BN_is_prime_ex(p, nchecks, ctx, cb);
+    return BN_is_prime_ex(p, nchecks, ctx, (BN_GENCB*) cb);
 }
 
-
-/**
- * Defines the mapping from Java methods and their signatures
- * to native functions. Order is Java name, Java signature,
- * then pointer to C function.
- */
 static JNINativeMethod METHODS[] = {
    { "ERR_get_error", "()I", (void*)NativeBN_ERR_get_error },
    { "ERR_error_string", "(I)Ljava/lang/String;", (void*)NativeBN_ERR_error_string },
@@ -740,7 +675,7 @@
    { "bitLength", "(I)I", (void*)NativeBN_bitLength },
    { "BN_is_bit_set", "(II)Z", (void*)NativeBN_BN_is_bit_set },
    { "modifyBit", "(III)Z", (void*)NativeBN_modifyBit },
-   { "BN_lshift", "(III)Z", (void*)NativeBN_BN_lshift },
+   { "BN_shift", "(III)Z", (void*)NativeBN_BN_shift },
    { "BN_add_word", "(II)Z", (void*)NativeBN_BN_add_word },
    { "BN_sub_word", "(II)Z", (void*)NativeBN_BN_sub_word },
    { "BN_mul_word", "(II)Z", (void*)NativeBN_BN_mul_word },
@@ -758,7 +693,6 @@
    { "BN_generate_prime_ex", "(IIZIII)Z", (void*)NativeBN_BN_generate_prime_ex },
    { "BN_is_prime_ex", "(IIII)Z", (void*)NativeBN_BN_is_prime_ex }
 };
-
 int register_org_openssl_NativeBN(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "org/openssl/NativeBN", METHODS, NELEM(METHODS));
 }
diff --git a/prefs/src/main/java/java/util/prefs/AbstractPreferences.java b/prefs/src/main/java/java/util/prefs/AbstractPreferences.java
index 3264569..17ffbbb 100644
--- a/prefs/src/main/java/java/util/prefs/AbstractPreferences.java
+++ b/prefs/src/main/java/java/util/prefs/AbstractPreferences.java
@@ -31,7 +31,6 @@
 import java.util.TreeSet;
 
 import org.apache.harmony.luni.util.Base64;
-import org.apache.harmony.prefs.internal.nls.Messages;
 
 /**
  * This abstract class is a partial implementation of the abstract class
@@ -51,7 +50,7 @@
     /** the unhandled events collection */
     private static final List<EventObject> events = new LinkedList<EventObject>();
     /** the event dispatcher thread */
-    private static final EventDispatcher dispatcher = new EventDispatcher("Preference Event Dispatcher"); //$NON-NLS-1$
+    private static final EventDispatcher dispatcher = new EventDispatcher("Preference Event Dispatcher");
 
     /*
      * -----------------------------------------------------------
@@ -148,7 +147,7 @@
      *             parent} is not {@code null}.
      */
     protected AbstractPreferences(AbstractPreferences parent, String name) {
-        if ((null == parent ^ name.length() == 0) || name.indexOf("/") >= 0) { //$NON-NLS-1$
+        if ((null == parent ^ name.length() == 0) || name.indexOf("/") >= 0) {
             throw new IllegalArgumentException();
         }
         root = null == parent ? this : parent.root;
@@ -345,11 +344,11 @@
     @Override
     public String absolutePath() {
         if (parentPref == null) {
-            return "/"; //$NON-NLS-1$
+            return "/";
         } else if (parentPref == root) {
-            return "/" + nodeName; //$NON-NLS-1$
+            return "/" + nodeName;
         }
-        return parentPref.absolutePath() + "/" + nodeName; //$NON-NLS-1$
+        return parentPref.absolutePath() + "/" + nodeName;
     }
 
     @Override
@@ -376,23 +375,18 @@
     }
 
     @Override
-    public void exportNode(OutputStream ostream) throws IOException,
-            BackingStoreException {
-        if(ostream == null) {
-            // prefs.5=Stream is null
-            throw new NullPointerException(Messages.getString("prefs.5"));  //$NON-NLS-1$
+    public void exportNode(OutputStream ostream) throws IOException, BackingStoreException {
+        if (ostream == null) {
+            throw new NullPointerException("Stream is null");
         }
         checkState();
         XMLParser.exportPrefs(this, ostream, false);
-
     }
 
     @Override
-    public void exportSubtree(OutputStream ostream) throws IOException,
-            BackingStoreException {
-        if(ostream == null) {
-            // prefs.5=Stream is null
-            throw new NullPointerException(Messages.getString("prefs.5"));  //$NON-NLS-1$
+    public void exportSubtree(OutputStream ostream) throws IOException, BackingStoreException {
+        if (ostream == null) {
+            throw new NullPointerException("Stream is null");
         }
         checkState();
         XMLParser.exportPrefs(this, ostream, true);
@@ -433,9 +427,9 @@
         if (result == null) {
             return deflt;
         }
-        if ("true".equalsIgnoreCase(result)) { //$NON-NLS-1$
+        if ("true".equalsIgnoreCase(result)) {
             return true;
-        } else if ("false".equalsIgnoreCase(result)) { //$NON-NLS-1$
+        } else if ("false".equalsIgnoreCase(result)) {
             return false;
         } else {
             return deflt;
@@ -452,7 +446,7 @@
             return new byte[0];
         }
         try {
-            byte[] bavalue = svalue.getBytes("US-ASCII"); //$NON-NLS-1$
+            byte[] bavalue = svalue.getBytes("US-ASCII");
             if (bavalue.length % 4 != 0) {
                 return deflt;
             }
@@ -538,12 +532,12 @@
         synchronized (lock) {
             checkState();
             validateName(name);
-            if ("".equals(name)) { //$NON-NLS-1$
+            if ("".equals(name)) {
                 return this;
-            } else if ("/".equals(name)) { //$NON-NLS-1$
+            } else if ("/".equals(name)) {
                 return root;
             }
-            if (name.startsWith("/")) { //$NON-NLS-1$
+            if (name.startsWith("/")) {
                 startNode = root;
                 name = name.substring(1);
             } else {
@@ -559,13 +553,11 @@
     }
 
     private void validateName(String name) {
-        if (name.endsWith("/") && name.length() > 1) { //$NON-NLS-1$
-            // prefs.6=Name cannot end with '/'\!
-            throw new IllegalArgumentException(Messages.getString("prefs.6")); //$NON-NLS-1$
+        if (name.endsWith("/") && name.length() > 1) {
+            throw new IllegalArgumentException("Name cannot end with '/'");
         }
-        if (name.indexOf("//") >= 0) { //$NON-NLS-1$
-            // prefs.7=Name cannot contains consecutive '/'\!
-            throw new IllegalArgumentException(Messages.getString("prefs.7")); //$NON-NLS-1$
+        if (name.indexOf("//") >= 0) {
+            throw new IllegalArgumentException("Name cannot contain consecutive '/' characters");
         }
     }
 
@@ -593,12 +585,9 @@
     }
 
     private AbstractPreferences getNodeFromBackend(boolean createNew,
-            AbstractPreferences currentNode, String name)
-            throws BackingStoreException {
+            AbstractPreferences currentNode, String name) throws BackingStoreException {
         if (name.length() > MAX_NAME_LENGTH) {
-            // prefs.8=Name length is too long: {0}
-            throw new IllegalArgumentException(Messages.getString("prefs.8", //$NON-NLS-1$
-                    name));
+            throw new IllegalArgumentException("Name '" + name + "' too long");
         }
         AbstractPreferences temp;
         if (createNew) {
@@ -621,17 +610,16 @@
         AbstractPreferences startNode = null;
         synchronized (lock) {
             if (isRemoved()) {
-                if ("".equals(name)) { //$NON-NLS-1$
+                if (name.isEmpty()) {
                     return false;
                 }
-                // prefs.9=This node has been removed\!
-                throw new IllegalStateException(Messages.getString("prefs.9"));  //$NON-NLS-1$
+                throw new IllegalStateException("This node has been removed");
             }
             validateName(name);
-            if ("".equals(name) || "/".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$
+            if (name.isEmpty() || "/".equals(name)) {
                 return true;
             }
-            if (name.startsWith("/")) { //$NON-NLS-1$
+            if (name.startsWith("/")) {
                 startNode = root;
                 name = name.substring(1);
             } else {
@@ -654,8 +642,7 @@
 
     private void checkState() {
         if (isRemoved()) {
-            // prefs.9=This node has been removed\!
-            throw new IllegalStateException(Messages.getString("prefs.9"));  //$NON-NLS-1$
+            throw new IllegalStateException("This node has been removed");
         }
     }
 
@@ -683,7 +670,7 @@
     @Override
     public void putByteArray(String key, byte[] value) {
         try {
-            put(key, Base64.encode(value, "US-ASCII")); //$NON-NLS-1$
+            put(key, Base64.encode(value, "US-ASCII"));
         } catch (UnsupportedEncodingException e) {
             throw new AssertionError(e);
         }
@@ -725,8 +712,7 @@
     @Override
     public void removeNode() throws BackingStoreException {
         if (root == this) {
-            // prefs.A=Cannot remove root node\!
-            throw new UnsupportedOperationException(Messages.getString("prefs.A"));  //$NON-NLS-1$
+            throw new UnsupportedOperationException("Cannot remove root node");
         }
         synchronized (parentPref.lock) {
             removeNodeImpl();
@@ -810,18 +796,16 @@
             checkState();
             syncSpi();
         }
-        AbstractPreferences[] cc = cachedChildren();
-        int i;
-        for (i = 0; i < cc.length; i++) {
-            cc[i].sync();
+        for (AbstractPreferences child : cachedChildren()) {
+            child.sync();
         }
     }
 
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
-        sb.append(isUserNode() ? "User" : "System"); //$NON-NLS-1$ //$NON-NLS-2$
-        sb.append(" Preference Node: "); //$NON-NLS-1$
+        sb.append(isUserNode() ? "User" : "System");
+        sb.append(" Preference Node: ");
         sb.append(absolutePath());
         return sb.toString();
     }
@@ -843,8 +827,7 @@
     }
 
     private void notifyPreferenceChange(String key, String newValue) {
-        PreferenceChangeEvent pce = new PreferenceChangeEvent(this, key,
-                newValue);
+        PreferenceChangeEvent pce = new PreferenceChangeEvent(this, key, newValue);
         synchronized (events) {
             events.add(pce);
             events.notifyAll();
diff --git a/prefs/src/main/java/java/util/prefs/FilePreferencesImpl.java b/prefs/src/main/java/java/util/prefs/FilePreferencesImpl.java
index f6e5e8f..1eb11e3 100644
--- a/prefs/src/main/java/java/util/prefs/FilePreferencesImpl.java
+++ b/prefs/src/main/java/java/util/prefs/FilePreferencesImpl.java
@@ -25,8 +25,6 @@
 import java.util.Properties;
 import java.util.Set;
 
-import org.apache.harmony.prefs.internal.nls.Messages;
-
 /**
  * The default implementation of <code>AbstractPreferences</code> for the Linux
  * platform, using the file system as its back end.
@@ -44,7 +42,7 @@
      */
 
     //prefs file name
-    private static final String PREFS_FILE_NAME = "prefs.xml"; //$NON-NLS-1$
+    private static final String PREFS_FILE_NAME = "prefs.xml";
 
     //home directory for user prefs
     private static String USER_HOME;
@@ -102,7 +100,7 @@
      * user root if userNode is true, system root otherwise
      */
     FilePreferencesImpl(boolean userNode) {
-        super(null, ""); //$NON-NLS-1$
+        super(null, "");
         this.userNode = userNode;
         path = userNode ? USER_HOME : SYSTEM_HOME;
         initPrefs();
@@ -142,9 +140,7 @@
             }
         });
         if (null == names) {// file is not a directory, exception case
-            // prefs.3=Cannot get children names for {0}!
-            throw new BackingStoreException(
-                    Messages.getString("prefs.3", toString()));  //$NON-NLS-1$
+            throw new BackingStoreException("Cannot get child names for " + toString());
         }
         return names;
     }
@@ -218,8 +214,7 @@
             }
         })).booleanValue();
         if (!removeSucceed) {
-            // prefs.4=Cannot remove {0}!
-            throw new BackingStoreException(Messages.getString("prefs.4", toString()));  //$NON-NLS-1$
+            throw new BackingStoreException("Cannot remove " + toString());
         }
     }
 
diff --git a/prefs/src/main/java/java/util/prefs/NodeSet.java b/prefs/src/main/java/java/util/prefs/NodeSet.java
index 7edd030..202b90b 100644
--- a/prefs/src/main/java/java/util/prefs/NodeSet.java
+++ b/prefs/src/main/java/java/util/prefs/NodeSet.java
@@ -6,10 +6,6 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 
-/**
- * 
- * @since Android 1.0
- */ 
 class NodeSet implements NodeList {
 
     ArrayList<Node> list = new ArrayList<Node>();
diff --git a/prefs/src/main/java/java/util/prefs/Preferences.java b/prefs/src/main/java/java/util/prefs/Preferences.java
index 8b961e4..9a1d9e6 100644
--- a/prefs/src/main/java/java/util/prefs/Preferences.java
+++ b/prefs/src/main/java/java/util/prefs/Preferences.java
@@ -16,14 +16,6 @@
 
 package java.util.prefs;
 
-// BEGIN android-added
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.Enumeration;
-// END android-added
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -31,8 +23,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Locale;
-
-import org.apache.harmony.prefs.internal.nls.Messages;
+import java.util.ServiceLoader;
 
 /**
  * An instance of the class {@code Preferences} represents one node in a
@@ -83,7 +74,7 @@
  * {@code Preferences} type developed. Every J2SE implementation must provide a
  * default implementation for every supported platform, and must also provide a
  * means of replacing the default implementation. This implementation uses the
- * system property {@code java.util.prefs.PreferencesFactory} to detemine which
+ * system property {@code java.util.prefs.PreferencesFactory} to determine which
  * preferences implementation to use.
  * <p>
  * The methods of this class are thread-safe. If multiple JVMs are using the
@@ -110,123 +101,24 @@
      */
     public static final int MAX_VALUE_LENGTH = 8192;
 
-    // BEGIN android-added
-    /**
-     * The name of the configuration file where preferences factory class names
-     * can be specified.
-     */
-    private static final String FACTORY_CONFIGURATION_FILE_NAME = "META-INF/services/java.util.prefs.PreferencesFactory"; //$NON-NLS-1$
-
-    /**
-     * The encoding of configuration files
-     */
-    private static final String CONFIGURATION_FILE_ENCODING = "UTF-8"; //$NON-NLS-1$
-
-    /**
-     * The comment string used in configuration files
-     */
-    private static final String CONFIGURATION_FILE_COMMENT = "#"; //$NON-NLS-1$
-
-    // END android-added
-
     //permission
-    private static final RuntimePermission PREFS_PERM = new RuntimePermission("preferences"); //$NON-NLS-1$
+    private static final RuntimePermission PREFS_PERM = new RuntimePermission("preferences");
 
     //factory used to get user/system prefs root
-    private static final PreferencesFactory factory;
+    private static final PreferencesFactory factory = findPreferencesFactory();
 
-    // BEGIN android-removed
-    // // default provider factory name for Windows
-    // private static final String DEFAULT_FACTORY_NAME_WIN = "java.util.prefs.RegistryPreferencesFactoryImpl"; //$NON-NLS-1$
-    //
-    // // default provider factory name for Unix
-    // private static final String DEFAULT_FACTORY_NAME_UNIX = "java.util.prefs.FilePreferencesFactoryImpl"; //$NON-NLS-1$
-    // END android-removed
-
-    static {
-        String factoryClassName = AccessController.doPrivileged(new PrivilegedAction<String>() {
-            public String run() {
-                return System.getProperty("java.util.prefs.PreferencesFactory"); //$NON-NLS-1$
-            }
-        });
-        // BEGIN android-removed
-        // // set default provider
-        // if (factoryClassName == null) {
-        //     String osName = AccessController.doPrivileged(new PrivilegedAction<String>() {
-        //         public String run() {
-        //             return System.getProperty("os.name"); //$NON-NLS-1$
-        //         }
-        //     });
-        //
-        //     // only comparing ASCII, so assume english locale
-        //     osName = (osName == null ? null : osName.toLowerCase(Locale.ENGLISH));
-        //
-        //     if (osName != null && osName.startsWith("windows")) {
-        //         factoryClassName = DEFAULT_FACTORY_NAME_WIN;
-        //     } else {
-        //         factoryClassName = DEFAULT_FACTORY_NAME_UNIX;
-        //     }
-        // }
-        // try {
-        //     ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        //     if(loader == null){
-        //         loader = ClassLoader.getSystemClassLoader();
-        //     }
-        //     Class<?> factoryClass = loader.loadClass(factoryClassName);
-        //     factory = (PreferencesFactory) factoryClass.newInstance();
-        // } catch (Exception e) {
-        //     // prefs.10=Cannot initiate PreferencesFactory: {0}. Caused by {1}
-        //     throw new InternalError(Messages.getString("prefs.10", factoryClassName, e));   //$NON-NLS-1$
-        // }
-        // BEGIN android-added
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        if (loader == null) {
-            loader = ClassLoader.getSystemClassLoader();
+    private static PreferencesFactory findPreferencesFactory() {
+        // Try the system property first...
+        PreferencesFactory result = ServiceLoader.loadFromSystemProperty(PreferencesFactory.class);
+        if (result != null) {
+            return result;
         }
-        if (factoryClassName == null) {
-            Enumeration<URL> en = null;
-            try {
-                en = loader.getResources(FACTORY_CONFIGURATION_FILE_NAME);
-                BufferedReader reader = null;
-                int commentIndex = 0;
-                while (en.hasMoreElements()) {
-                    try {
-                        InputStream is = en.nextElement().openStream();
-                        // Read each line for charset provider class names
-                        reader = new BufferedReader(new InputStreamReader(is,
-                                CONFIGURATION_FILE_ENCODING), 8192);
-                        factoryClassName = reader.readLine();
-                        commentIndex = factoryClassName.indexOf(CONFIGURATION_FILE_COMMENT);
-                        if (commentIndex > 0) {
-                            factoryClassName = factoryClassName.substring(0, commentIndex).trim();
-                        }
-                        if (factoryClassName.length() > 0) {
-                            break;
-                        }
-                    } catch (IOException ex) {
-                        // ignore if a resource couldn't be read
-                    }
-                }
-            } catch (Exception e) {
-                // prefs.10=Cannot initiate PreferencesFactory: {0}. Caused by
-                // {1}
-                throw new InternalError(Messages.getString("prefs.10",
-                        FACTORY_CONFIGURATION_FILE_NAME, e)); //$NON-NLS-1$
-            }
+        // Then use ServiceLoader for META-INF/services/...
+        for (PreferencesFactory impl : ServiceLoader.load(PreferencesFactory.class, null)) {
+            return impl;
         }
-
-        if (factoryClassName == null) {
-            factoryClassName = "java.util.prefs.FilePreferencesFactoryImpl";
-        }
-
-        try {
-            Class<?> c = loader.loadClass(factoryClassName);
-            factory = (PreferencesFactory)c.newInstance();
-        } catch (Exception e) {
-            // prefs.10=Cannot initiate PreferencesFactory: {0}. Caused by {1}
-            throw new InternalError(Messages.getString("prefs.10", factoryClassName, e)); //$NON-NLS-1$
-        }
-        // END android-added
+        // Finally return a default...
+        return new FilePreferencesFactoryImpl();
     }
 
     /**
@@ -557,9 +449,8 @@
      */
     public static void importPreferences (InputStream istream) throws InvalidPreferencesFormatException, IOException {
         checkSecurity();
-        if(null == istream){
-            // prefs.0=Inputstream cannot be null\!
-            throw new MalformedURLException(Messages.getString("prefs.0")); //$NON-NLS-1$
+        if (istream == null){
+            throw new MalformedURLException("Inputstream cannot be null");
         }
         XMLParser.importPrefs(istream);
     }
@@ -975,9 +866,9 @@
     private static String getNodeName(Class<?> c){
         Package p = c.getPackage();
         if(null == p){
-            return "/<unnamed>"; //$NON-NLS-1$
+            return "/<unnamed>";
         }
-        return "/"+p.getName().replace('.', '/'); //$NON-NLS-1$
+        return "/"+p.getName().replace('.', '/');
     }
 
     /**
diff --git a/prefs/src/main/java/java/util/prefs/XMLParser.java b/prefs/src/main/java/java/util/prefs/XMLParser.java
index c5a234c..986429d 100644
--- a/prefs/src/main/java/java/util/prefs/XMLParser.java
+++ b/prefs/src/main/java/java/util/prefs/XMLParser.java
@@ -33,23 +33,17 @@
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
 import java.util.Properties;
 import java.util.StringTokenizer;
-
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
-// BEGIN android-removed
-// import javax.xml.transform.TransformerException;
-// END android-removed
-
-import org.apache.harmony.prefs.internal.nls.Messages;
-// BEGIN android-removed
-// import org.apache.xpath.XPathAPI;
-// END android-removed
 import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.ErrorHandler;
@@ -57,12 +51,6 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
-// BEGIN android-added
-import java.util.ArrayList;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Node;
-// END android-added
-
 /**
  * Utility class for the Preferences import/export from XML file.
  */
@@ -71,31 +59,31 @@
     /*
      * Constant - the specified DTD URL
      */
-    static final String PREFS_DTD_NAME = "http://java.sun.com/dtd/preferences.dtd"; //$NON-NLS-1$
+    static final String PREFS_DTD_NAME = "http://java.sun.com/dtd/preferences.dtd";
 
     /*
      * Constant - the DTD string
      */
-    static final String PREFS_DTD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" //$NON-NLS-1$
-        + "    <!ELEMENT preferences (root)>" //$NON-NLS-1$
-        + "    <!ATTLIST preferences EXTERNAL_XML_VERSION CDATA \"0.0\" >" //$NON-NLS-1$
-        + "    <!ELEMENT root (map, node*) >" //$NON-NLS-1$
-        + "    <!ATTLIST root type (system|user) #REQUIRED >" //$NON-NLS-1$
-        + "    <!ELEMENT node (map, node*) >" //$NON-NLS-1$
-        + "    <!ATTLIST node name CDATA #REQUIRED >" //$NON-NLS-1$
-        + "    <!ELEMENT map (entry*) >" //$NON-NLS-1$
-        + "    <!ELEMENT entry EMPTY >" //$NON-NLS-1$
-        + "    <!ATTLIST entry key   CDATA #REQUIRED value CDATA #REQUIRED >"; //$NON-NLS-1$
+    static final String PREFS_DTD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+        + "    <!ELEMENT preferences (root)>"
+        + "    <!ATTLIST preferences EXTERNAL_XML_VERSION CDATA \"0.0\" >"
+        + "    <!ELEMENT root (map, node*) >"
+        + "    <!ATTLIST root type (system|user) #REQUIRED >"
+        + "    <!ELEMENT node (map, node*) >"
+        + "    <!ATTLIST node name CDATA #REQUIRED >"
+        + "    <!ELEMENT map (entry*) >"
+        + "    <!ELEMENT entry EMPTY >"
+        + "    <!ATTLIST entry key   CDATA #REQUIRED value CDATA #REQUIRED >";
 
     /*
      * Constant - the specified header
      */
-    static final String HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$
+    static final String HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
 
     /*
      * Constant - the specified DOCTYPE
      */
-    static final String DOCTYPE = "<!DOCTYPE preferences SYSTEM"; //$NON-NLS-1$
+    static final String DOCTYPE = "<!DOCTYPE preferences SYSTEM";
 
     /*
      * empty string array constant
@@ -105,7 +93,7 @@
     /*
      * Constant - used by FilePreferencesImpl, which is default implementation of Linux platform
      */
-    private static final String FILE_PREFS = "<!DOCTYPE map SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>"; //$NON-NLS-1$
+    private static final String FILE_PREFS = "<!DOCTYPE map SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>";
 
     /*
      * Constant - specify the DTD version
@@ -144,9 +132,7 @@
                     result.setSystemId(PREFS_DTD_NAME);
                     return result;
                 }
-                // prefs.1=Invalid DOCTYPE declaration: {0}
-                throw new SAXException(
-                        Messages.getString("prefs.1", systemId));  //$NON-NLS-1$
+                throw new SAXException("Invalid DOCTYPE declaration " + systemId);
             }
         });
         builder.setErrorHandler(new ErrorHandler() {
@@ -173,45 +159,41 @@
     static void exportPrefs(Preferences prefs, OutputStream stream,
             boolean withSubTree) throws IOException, BackingStoreException {
         indent = -1;
-        // BEGIN android-modified
-        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(stream, "UTF-8"), 8192); //$NON-NLS-1$
-        // END android-modified
+        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(stream, "UTF-8"));
         out.write(HEADER);
         out.newLine();
         out.newLine();
 
         out.write(DOCTYPE);
-        out.write(" '"); //$NON-NLS-1$
+        out.write(" '");
         out.write(PREFS_DTD_NAME);
-        out.write("'>"); //$NON-NLS-1$
+        out.write("'>");
         out.newLine();
         out.newLine();
 
-        flushStartTag(
-                "preferences", new String[] { "EXTERNAL_XML_VERSION" }, new String[] { String.valueOf(XML_VERSION) }, out); //$NON-NLS-1$ //$NON-NLS-2$
-        flushStartTag(
-                "root", new String[] { "type" }, new String[] { prefs.isUserNode() ? "user" : "system" }, out); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-        flushEmptyElement("map", out); //$NON-NLS-1$
+        flushStartTag("preferences", new String[] { "EXTERNAL_XML_VERSION" },
+                new String[] { String.valueOf(XML_VERSION) }, out);
+        flushStartTag("root", new String[] { "type" },
+                new String[] { prefs.isUserNode() ? "user" : "system" }, out);
+        flushEmptyElement("map", out);
 
-        StringTokenizer ancestors = new StringTokenizer(prefs.absolutePath(),
-        "/"); //$NON-NLS-1$
+        StringTokenizer ancestors = new StringTokenizer(prefs.absolutePath(), "/");
         exportNode(ancestors, prefs, withSubTree, out);
 
-        flushEndTag("root", out); //$NON-NLS-1$
-        flushEndTag("preferences", out); //$NON-NLS-1$
+        flushEndTag("root", out);
+        flushEndTag("preferences", out);
         out.flush();
         out = null;
     }
 
     private static void exportNode(StringTokenizer ancestors,
             Preferences prefs, boolean withSubTree, BufferedWriter out)
-    throws IOException, BackingStoreException {
+            throws IOException, BackingStoreException {
         if (ancestors.hasMoreTokens()) {
             String name = ancestors.nextToken();
-            flushStartTag(
-                    "node", new String[] { "name" }, new String[] { name }, out); //$NON-NLS-1$ //$NON-NLS-2$
+            flushStartTag("node", new String[] { "name" }, new String[] { name }, out);
             if (ancestors.hasMoreTokens()) {
-                flushEmptyElement("map", out); //$NON-NLS-1$
+                flushEmptyElement("map", out);
                 exportNode(ancestors, prefs, withSubTree, out);
             } else {
                 exportEntries(prefs, out);
@@ -219,7 +201,7 @@
                     exportSubTree(prefs, out);
                 }
             }
-            flushEndTag("node", out); //$NON-NLS-1$
+            flushEndTag("node", out);
         }
     }
 
@@ -229,11 +211,10 @@
         if (names.length > 0) {
             for (int i = 0; i < names.length; i++) {
                 Preferences child = prefs.node(names[i]);
-                flushStartTag(
-                        "node", new String[] { "name" }, new String[] { names[i] }, out); //$NON-NLS-1$ //$NON-NLS-2$
+                flushStartTag("node", new String[] { "name" }, new String[] { names[i] }, out);
                 exportEntries(child, out);
                 exportSubTree(child, out);
-                flushEndTag("node", out); //$NON-NLS-1$
+                flushEndTag("node", out);
             }
         }
     }
@@ -251,34 +232,34 @@
     private static void exportEntries(String[] keys, String[] values,
             BufferedWriter out) throws IOException {
         if (keys.length == 0) {
-            flushEmptyElement("map", out); //$NON-NLS-1$
+            flushEmptyElement("map", out);
             return;
         }
-        flushStartTag("map", out); //$NON-NLS-1$
+        flushStartTag("map", out);
         for (int i = 0; i < keys.length; i++) {
             if (values[i] != null) {
-                flushEmptyElement(
-                        "entry", new String[] { "key", "value" }, new String[] { keys[i], values[i] }, out); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                flushEmptyElement("entry", new String[] { "key", "value" },
+                        new String[] { keys[i], values[i] }, out);
             }
         }
-        flushEndTag("map", out); //$NON-NLS-1$
+        flushEndTag("map", out);
     }
 
     private static void flushEndTag(String tagName, BufferedWriter out)
     throws IOException {
         flushIndent(indent--, out);
-        out.write("</"); //$NON-NLS-1$
+        out.write("</");
         out.write(tagName);
-        out.write(">"); //$NON-NLS-1$
+        out.write(">");
         out.newLine();
     }
 
     private static void flushEmptyElement(String tagName, BufferedWriter out)
     throws IOException {
         flushIndent(++indent, out);
-        out.write("<"); //$NON-NLS-1$
+        out.write("<");
         out.write(tagName);
-        out.write(" />"); //$NON-NLS-1$
+        out.write(" />");
         out.newLine();
         indent--;
     }
@@ -286,10 +267,10 @@
     private static void flushEmptyElement(String tagName, String[] attrKeys,
             String[] attrValues, BufferedWriter out) throws IOException {
         flushIndent(++indent, out);
-        out.write("<"); //$NON-NLS-1$
+        out.write("<");
         out.write(tagName);
         flushPairs(attrKeys, attrValues, out);
-        out.write(" />"); //$NON-NLS-1$
+        out.write(" />");
         out.newLine();
         indent--;
     }
@@ -297,37 +278,37 @@
     private static void flushPairs(String[] attrKeys, String[] attrValues,
             BufferedWriter out) throws IOException {
         for (int i = 0; i < attrKeys.length; i++) {
-            out.write(" "); //$NON-NLS-1$
+            out.write(" ");
             out.write(attrKeys[i]);
-            out.write("=\""); //$NON-NLS-1$
+            out.write("=\"");
             out.write(htmlEncode(attrValues[i]));
-            out.write("\""); //$NON-NLS-1$
+            out.write("\"");
         }
     }
 
     private static void flushIndent(int ind, BufferedWriter out)
     throws IOException {
         for (int i = 0; i < ind; i++) {
-            out.write("  "); //$NON-NLS-1$
+            out.write("  ");
         }
     }
 
     private static void flushStartTag(String tagName, String[] attrKeys,
             String[] attrValues, BufferedWriter out) throws IOException {
         flushIndent(++indent, out);
-        out.write("<"); //$NON-NLS-1$
+        out.write("<");
         out.write(tagName);
         flushPairs(attrKeys, attrValues, out);
-        out.write(">"); //$NON-NLS-1$
+        out.write(">");
         out.newLine();
     }
 
     private static void flushStartTag(String tagName, BufferedWriter out)
     throws IOException {
         flushIndent(++indent, out);
-        out.write("<"); //$NON-NLS-1$
+        out.write("<");
         out.write(tagName);
-        out.write(">"); //$NON-NLS-1$
+        out.write(">");
         out.newLine();
     }
 
@@ -338,19 +319,19 @@
             c = s.charAt(i);
             switch (c) {
             case '<':
-                sb.append("&lt;"); //$NON-NLS-1$
+                sb.append("&lt;");
                 break;
             case '>':
-                sb.append("&gt;"); //$NON-NLS-1$
+                sb.append("&gt;");
                 break;
             case '&':
-                sb.append("&amp;"); //$NON-NLS-1$
+                sb.append("&amp;");
                 break;
             case '\\':
-                sb.append("&apos;"); //$NON-NLS-1$
+                sb.append("&apos;");
                 break;
             case '"':
-                sb.append("&quot;"); //$NON-NLS-1$
+                sb.append("&quot;");
                 break;
             default:
                 sb.append(c);
@@ -362,8 +343,7 @@
     /***************************************************************************
      * utilities for Preferences import
      **************************************************************************/
-    static void importPrefs(InputStream in) throws IOException,
-    InvalidPreferencesFormatException {
+    static void importPrefs(InputStream in) throws IOException, InvalidPreferencesFormatException {
         try {
             // load XML document
             Document doc = builder.parse(new InputSource(in));
@@ -371,19 +351,18 @@
             // check preferences' export version
             Element preferences;
             preferences = doc.getDocumentElement();
-            String version = preferences.getAttribute("EXTERNAL_XML_VERSION"); //$NON-NLS-1$
+            String version = preferences.getAttribute("EXTERNAL_XML_VERSION");
             if (version != null && Float.parseFloat(version) > XML_VERSION) {
-                // prefs.2=This preferences exported version is not supported:{0}
-                throw new InvalidPreferencesFormatException(
-                        Messages.getString("prefs.2", version));  //$NON-NLS-1$
+                throw new InvalidPreferencesFormatException("Preferences version " + version +
+                        " is not supported");
             }
 
             // check preferences root's type
             Element root = (Element) preferences
-            .getElementsByTagName("root").item(0); //$NON-NLS-1$
+            .getElementsByTagName("root").item(0);
             Preferences prefsRoot = null;
-            String type = root.getAttribute("type"); //$NON-NLS-1$
-            if (type.equals("user")) { //$NON-NLS-1$
+            String type = root.getAttribute("type");
+            if (type.equals("user")) {
                 prefsRoot = Preferences.userRoot();
             } else {
                 prefsRoot = Preferences.systemRoot();
@@ -409,8 +388,8 @@
         // END android-note
         // load preferences
         // BEGIN android-changed
-        NodeList children = selectNodeList(node, "node"); //$NON-NLS-1$
-        NodeList entries = selectNodeList(node, "map/entry"); //$NON-NLS-1$
+        NodeList children = selectNodeList(node, "node");
+        NodeList entries = selectNodeList(node, "map/entry");
         // END android-changed
         int childNumber = children.getLength();
         Preferences[] prefChildren = new Preferences[childNumber];
@@ -421,14 +400,14 @@
             }
             for (int i = 0; i < entryNumber; i++) {
                 Element entry = (Element) entries.item(i);
-                String key = entry.getAttribute("key"); //$NON-NLS-1$
-                String value = entry.getAttribute("value"); //$NON-NLS-1$
+                String key = entry.getAttribute("key");
+                String value = entry.getAttribute("value");
                 prefs.put(key, value);
             }
             // get children preferences node
             for (int i = 0; i < childNumber; i++) {
                 Element child = (Element) children.item(i);
-                String name = child.getAttribute("name"); //$NON-NLS-1$
+                String name = child.getAttribute("name");
                 prefChildren[i] = prefs.node(name);
             }
         }
@@ -515,31 +494,21 @@
             FileLock lock = null;
             try {
                 FileInputStream istream = new FileInputStream(file);
-                // BEGIN android-modified
-                in = new BufferedInputStream(istream, 8192);
-                // END android-modified
+                in = new BufferedInputStream(istream);
                 FileChannel channel = istream.getChannel();
                 lock = channel.lock(0L, Long.MAX_VALUE, true);
                 Document doc = builder.parse(in);
-                // BEGIN android-modified
-                NodeList entries = selectNodeList(doc
-                        .getDocumentElement(), "entry"); //$NON-NLS-1$
-                // END android-modified
+                NodeList entries = selectNodeList(doc.getDocumentElement(), "entry");
                 int length = entries.getLength();
                 for (int i = 0; i < length; i++) {
                     Element node = (Element) entries.item(i);
-                    String key = node.getAttribute("key"); //$NON-NLS-1$
-                    String value = node.getAttribute("value"); //$NON-NLS-1$
+                    String key = node.getAttribute("key");
+                    String value = node.getAttribute("value");
                     result.setProperty(key, value);
                 }
                 return result;
             } catch (IOException e) {
             } catch (SAXException e) {
-            // BEGIN android-removed
-            // } catch (TransformerException e) {
-            //     // transform shouldn't fail for xpath call
-            //     throw new AssertionError(e);
-            // END android-removed
             } finally {
                 releaseQuietly(lock);
                 closeQuietly(in);
@@ -570,9 +539,7 @@
         FileLock lock = null;
         try {
             FileOutputStream ostream = new FileOutputStream(file);
-            // BEGIN android-modified
-            out = new BufferedWriter(new OutputStreamWriter(ostream, "UTF-8"), 8192); //$NON-NLS-1$
-            // END android-modified
+            out = new BufferedWriter(new OutputStreamWriter(ostream, "UTF-8"));
             FileChannel channel = ostream.getChannel();
             lock = channel.lock();
             out.write(HEADER);
diff --git a/prefs/src/main/java/java/util/prefs/package.html b/prefs/src/main/java/java/util/prefs/package.html
index 8a3dd33..41cd12c 100644
--- a/prefs/src/main/java/java/util/prefs/package.html
+++ b/prefs/src/main/java/java/util/prefs/package.html
@@ -9,6 +9,5 @@
       on the operating system, this package is designed to allow the installation
       of a custom service provider implementation.
     </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/prefs/src/main/java/org/apache/harmony/prefs/internal/nls/Messages.java b/prefs/src/main/java/org/apache/harmony/prefs/internal/nls/Messages.java
deleted file mode 100644
index aaf5d8d..0000000
--- a/prefs/src/main/java/org/apache/harmony/prefs/internal/nls/Messages.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.prefs.internal.nls;
-
-// BEGIN android-added
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-added
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.prefs.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- *
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.prefs.internal.nls.messages";
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     *
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     *
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     *
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     *
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     *
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     *
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/prefs/src/main/java/org/apache/harmony/prefs/internal/nls/messages.properties b/prefs/src/main/java/org/apache/harmony/prefs/internal/nls/messages.properties
deleted file mode 100644
index 8940685..0000000
--- a/prefs/src/main/java/org/apache/harmony/prefs/internal/nls/messages.properties
+++ /dev/null
@@ -1,33 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-# messages for EN locale
-prefs.0=Inputstream cannot be null\!
-prefs.1=Invalid DOCTYPE declaration: {0}
-prefs.10=Cannot initiate PreferencesFactory: {0}. Caused by {1}
-prefs.2=This preferences exported version is not supported:{0}
-prefs.3=Cannot get children names for {0}!
-prefs.4=Cannot remove {0}!
-prefs.5=Stream is null
-prefs.6=Name cannot end with '/'\!
-prefs.7=Name cannot contains consecutive '/'\!
-prefs.8=Name length is too long: {0}
-prefs.9=This node has been removed\!
-prefs.A=Cannot remove root node\!
-prefs.B=Enumerate child nodes error\!
-prefs.C=Flush error\!
-prefs.D=Enumerate keys error\!
-prefs.E=Access denied\!
-prefs.F=Remove node error\!
diff --git a/prefs/src/main/resources/META-INF/services/java.util.prefs.PreferencesFactory b/prefs/src/main/resources/META-INF/services/java.util.prefs.PreferencesFactory
deleted file mode 100644
index ebb514c..0000000
--- a/prefs/src/main/resources/META-INF/services/java.util.prefs.PreferencesFactory
+++ /dev/null
@@ -1 +0,0 @@
-java.util.prefs.FilePreferencesFactoryImpl
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AllTests.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AllTests.java
index 29ff362..d2dd841 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AllTests.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/AllTests.java
@@ -24,13 +24,8 @@
  * 
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Suite for org.apache.harmony.prefs.tests.java.util.prefs");
+        TestSuite suite = new TestSuite("Suite for org.apache.harmony.prefs.tests.java.util.prefs");
         // $JUnit-BEGIN$
         suite.addTestSuite(NodeChangeListenerTest.class);
         suite.addTestSuite(PreferenceChangeListenerTest.class);
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
index 122dacd..c6e0861 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
@@ -213,7 +213,6 @@
             method = "importPreferences",
             args = {java.io.InputStream.class}
         )
-    @KnownFailure("xml validation does not work")
     public void testImportPreferences2() throws Exception {
         InputStream in = PreferencesTest.class
                 .getResourceAsStream("/prefs/java/util/prefs/userprefs-badtype.xml");
diff --git a/prefs/src/test/java/tests/prefs/AllTests.java b/prefs/src/test/java/tests/prefs/AllTests.java
index b3f2ed6..4d99023 100644
--- a/prefs/src/test/java/tests/prefs/AllTests.java
+++ b/prefs/src/test/java/tests/prefs/AllTests.java
@@ -24,13 +24,8 @@
  *
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Prefs test suites");
+        TestSuite suite = new TestSuite("All Prefs test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.prefs.tests.java.util.prefs.AllTests.suite());
         // $JUnit-END$
diff --git a/regex/src/main/java/java/util/regex/Matcher.java b/regex/src/main/java/java/util/regex/Matcher.java
index be5c782..5abbbd5 100644
--- a/regex/src/main/java/java/util/regex/Matcher.java
+++ b/regex/src/main/java/java/util/regex/Matcher.java
@@ -206,8 +206,7 @@
             throw new IllegalArgumentException();
         }
 
-        if (start < 0 || end < 0 || start > input.length() ||
-                end > input.length() || start > end) {
+        if (start < 0 || end < 0 || start > input.length() || end > input.length() || start > end) {
             throw new IllegalArgumentException();
         }
 
diff --git a/regex/src/main/java/java/util/regex/Pattern.java b/regex/src/main/java/java/util/regex/Pattern.java
index 26c74f8..325e3e0 100644
--- a/regex/src/main/java/java/util/regex/Pattern.java
+++ b/regex/src/main/java/java/util/regex/Pattern.java
@@ -52,7 +52,6 @@
  * Android-specific implementation details.
  * 
  * @see Matcher
- * @since Android 1.0
  */
 public final class Pattern implements Serializable {
     
@@ -170,8 +169,6 @@
      * <p>Otherwise, the {@code limit} parameter controls the contents of the
      * returned array as described below.
      *
-     * @param inputSeq
-     *            the input sequence.
      * @param limit
      *            Determines the maximum number of entries in the resulting
      *            array, and the treatment of trailing empty strings.
@@ -189,61 +186,15 @@
      *            special, as described above, and the limit parameter does
      *            not apply there.)
      *            </ul>
-     *
-     * @return the resulting array.
      */
-    public String[] split(CharSequence inputSeq, int limit) {
-        if (inputSeq.length() == 0) {
-            // Unlike Perl, which considers the result of splitting the empty
-            // string to be the empty array, Java returns an array containing
-            // the empty string.
-            return new String[] { "" };
-        }
-
-        int maxLength = limit <= 0 ? Integer.MAX_VALUE : limit;
-
-        String input = inputSeq.toString();
-        ArrayList<String> list = new ArrayList<String>();
-
-        Matcher matcher = new Matcher(this, inputSeq);
-        int savedPos = 0;
-
-        // Add text preceding each occurrence, if enough space.
-        while(matcher.find() && list.size() + 1 < maxLength) {
-            list.add(input.substring(savedPos, matcher.start()));
-            savedPos = matcher.end();
-        }
-
-        // Add trailing text if enough space.
-        if (list.size() < maxLength) {
-            if (savedPos < input.length()) {
-                list.add(input.substring(savedPos));
-            } else {
-                list.add("");
-            }
-        }
-
-        // Remove trailing empty matches in the limit == 0 case.
-        if (limit == 0) {
-            int i = list.size() - 1;
-            while (i >= 0 && "".equals(list.get(i))) {
-                list.remove(i);
-                i--;
-            }
-        }
-
-        return list.toArray(new String[list.size()]);
+    public String[] split(CharSequence input, int limit) {
+        return Splitter.split(this, pattern, input.toString(), limit);
     }
 
     /**
      * Splits a given input around occurrences of a regular expression. This is
      * a convenience method that is equivalent to calling the method
      * {@link #split(java.lang.CharSequence, int)} with a limit of 0.
-     *
-     * @param input
-     *            the input sequence.
-     *
-     * @return the resulting array.
      */
     public String[] split(CharSequence input) {
         return split(input, 0);
diff --git a/regex/src/main/java/java/util/regex/Splitter.java b/regex/src/main/java/java/util/regex/Splitter.java
new file mode 100644
index 0000000..d30bada
--- /dev/null
+++ b/regex/src/main/java/java/util/regex/Splitter.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.regex;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Used to make {@code String.split} fast (and to help {@code Pattern.split} too).
+ * @hide
+ */
+public class Splitter {
+    // The RI allows regular expressions beginning with ] or }, but that's probably a bug.
+    private static final String METACHARACTERS = "\\?*+[](){}^$.|";
+
+    private Splitter() {
+    }
+
+    /**
+     * Returns a result equivalent to {@code s.split(separator, limit)} if it's able
+     * to compute it more cheaply than ICU, or null if the caller should fall back to
+     * using ICU.
+     */
+    public static String[] fastSplit(String re, String input, int limit) {
+        // Can we do it cheaply?
+        int len = re.length();
+        if (len == 0) {
+            return null;
+        }
+        char ch = re.charAt(0);
+        if (len == 1 && METACHARACTERS.indexOf(ch) == -1) {
+            // We're looking for a single non-metacharacter. Easy.
+        } else if (len == 2 && ch == '\\') {
+            // We're looking for a quoted character.
+            // Quoted metacharacters are effectively single non-metacharacters.
+            ch = re.charAt(1);
+            if (METACHARACTERS.indexOf(ch) == -1) {
+                return null;
+            }
+        } else {
+            return null;
+        }
+
+        // We can do this cheaply...
+
+        // Unlike Perl, which considers the result of splitting the empty string to be the empty
+        // array, Java returns an array containing the empty string.
+        if (input.isEmpty()) {
+            return new String[] { "" };
+        }
+
+        // Collect text preceding each occurrence of the separator, while there's enough space.
+        ArrayList<String> list = new ArrayList<String>();
+        int maxSize = limit <= 0 ? Integer.MAX_VALUE : limit;
+        int begin = 0;
+        int end;
+        while ((end = input.indexOf(ch, begin)) != -1 && list.size() + 1 < maxSize) {
+            list.add(input.substring(begin, end));
+            begin = end + 1;
+        }
+        return finishSplit(list, input, begin, maxSize, limit);
+    }
+
+    public static String[] split(Pattern pattern, String re, String input, int limit) {
+        String[] fastResult = fastSplit(re, input, limit);
+        if (fastResult != null) {
+            return fastResult;
+        }
+
+        // Unlike Perl, which considers the result of splitting the empty string to be the empty
+        // array, Java returns an array containing the empty string.
+        if (input.isEmpty()) {
+            return new String[] { "" };
+        }
+
+        // Collect text preceding each occurrence of the separator, while there's enough space.
+        ArrayList<String> list = new ArrayList<String>();
+        int maxSize = limit <= 0 ? Integer.MAX_VALUE : limit;
+        Matcher matcher = new Matcher(pattern, input);
+        int begin = 0;
+        while (matcher.find() && list.size() + 1 < maxSize) {
+            list.add(input.substring(begin, matcher.start()));
+            begin = matcher.end();
+        }
+        return finishSplit(list, input, begin, maxSize, limit);
+    }
+
+    private static String[] finishSplit(List<String> list, String input, int begin, int maxSize, int limit) {
+        // Add trailing text.
+        if (begin < input.length()) {
+            list.add(input.substring(begin));
+        } else if (limit != 0) { // No point adding the empty string if limit == 0, just to remove it below.
+            list.add("");
+        }
+        // Remove all trailing empty matches in the limit == 0 case.
+        if (limit == 0) {
+            int i = list.size() - 1;
+            while (i >= 0 && list.get(i).isEmpty()) {
+                list.remove(i);
+                i--;
+            }
+        }
+        // Convert to an array.
+        return list.toArray(new String[list.size()]);
+    }
+}
diff --git a/regex/src/main/java/java/util/regex/package.html b/regex/src/main/java/java/util/regex/package.html
index 0508f3e..3ce73eb 100644
--- a/regex/src/main/java/java/util/regex/package.html
+++ b/regex/src/main/java/java/util/regex/package.html
@@ -622,7 +622,7 @@
           {n}
         </td>
         <td>
-          Match exactly n times
+          Match exactly n times.
         </td>
       </tr>
       <tr>
@@ -680,7 +680,7 @@
         </td>
         <td>
           Match at least n times, but no more than required for an
-        overall pattern match
+        overall pattern match.
         </td>
       </tr>
       <tr>
@@ -877,8 +877,5 @@
         all (throws an exception).
       </li>
     </ul>
-    
-    @since Android 1.0
-    
   </body>
 </html>
diff --git a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/AllTests.java b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/AllTests.java
index b69c401..55d3bf0 100644
--- a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/AllTests.java
+++ b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/AllTests.java
@@ -24,13 +24,8 @@
  * Provides a test suite for java.util.regex package.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.util.regex");
+        TestSuite suite = new TestSuite("Tests for java.util.regex");
         //$JUnit-BEGIN$
 
         suite.addTestSuite(Matcher2Test.class);
diff --git a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/MatcherTest.java b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/MatcherTest.java
index 5e9137b..adb3bc7 100644
--- a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/MatcherTest.java
+++ b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/MatcherTest.java
@@ -1464,8 +1464,4 @@
         assertTrue(pattern.matcher("14pt").matches());
     }
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(MatcherTest.class);
-    }
-
 }
diff --git a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
index c21a81d..5b979cf 100644
--- a/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
+++ b/regex/src/test/java/org/apache/harmony/regex/tests/java/util/regex/PatternTest.java
@@ -2377,10 +2377,6 @@
         assertTrue(matcher.find());
     }
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(PatternTest.class);
-    }
-    
     @TestTargetNew(
         level = TestLevel.PARTIAL_COMPLETE,
         notes = "The test doesn't verify Matcher and should be moved to PatterTest.",
diff --git a/regex/src/test/java/tests/regex/AllTests.java b/regex/src/test/java/tests/regex/AllTests.java
index d590d08..07feebc 100644
--- a/regex/src/test/java/tests/regex/AllTests.java
+++ b/regex/src/test/java/tests/regex/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the regex project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All regex test suites");
+        TestSuite suite = new TestSuite("All regex test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.regex.tests.java.util.regex.AllTests.suite());
         // $JUnit-END$
diff --git a/run-core-tests b/run-core-tests
index 3359dde..345f23b 100755
--- a/run-core-tests
+++ b/run-core-tests
@@ -1,3 +1,4 @@
+# -*- mode: bash -*-
 #
 # Copyright (C) 2007 The Android Open Source Project
 #
@@ -13,24 +14,33 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Run all the tests contained in the core-tests library.
-#
-# To install this script and the tests on a device:
-# $ make (only necessary once)
-# $ make CtsCoreTests snod (to create a system.img containing these files)
-#  OR
-# $ make CtsCoreTests && adb sync (to push these files to a running system)
+# To run these tests:
+# mmm -j14 dalvik snod
+# adb reboot bootloader && fastboot flashall
+# adb shell run-core-tests
 
 tmp=/data/core-tests.tmp
 mkdir $tmp
 chmod 777 $tmp
 
+# Build the classpath by putting together the jar file for each module.
+classpath="/system/framework/sqlite-jdbc.jar" # Bonus item for jdbc testing.
+modules="annotation archive concurrent crypto dom json \
+        logging luni-kernel luni math nio nio_char prefs regex security sql \
+        suncompat support text x-net xml"
+for module in $modules; do
+  classpath="$classpath:/system/framework/core-tests-$module.jar"
+done
+
 exec dalvikvm \
      -Duser.name=root \
      -Duser.language=en \
      -Duser.region=US \
+     -Duser.dir=$tmp \
+     -Duser.home=$tmp \
      -Djava.io.tmpdir=$tmp \
      -Djavax.net.ssl.trustStore=/system/etc/security/cacerts.bks \
-     -classpath /system/framework/core-tests.jar \
+     -classpath $classpath \
      -Xcheck:jni \
-     -Xmx64M com.google.coretests.Main "$@"
+     -Xmx64M \
+     com.google.coretests.Main "$@"
diff --git a/security-kernel/src/main/java/java/security/AccessControlContext.java b/security-kernel/src/main/java/java/security/AccessControlContext.java
index 597cc44..8efdb27 100644
--- a/security-kernel/src/main/java/java/security/AccessControlContext.java
+++ b/security-kernel/src/main/java/java/security/AccessControlContext.java
@@ -73,7 +73,6 @@
      *             not have permission to invoke this constructor
      * @throws NullPointerException
      *             if {@code acc} is {@code null}
-     * @since Android 1.0
      */
     public AccessControlContext(AccessControlContext acc,
             DomainCombiner combiner) {
@@ -96,7 +95,6 @@
      *            checks in the context of this {@code AccessControlContext}
      * @throws NullPointerException
      *             if {@code context} is {@code null}
-     * @since Android 1.0
      */
     public AccessControlContext(ProtectionDomain[] context) {
         if (context == null) {
@@ -185,7 +183,6 @@
      * @throws NullPointerException
      *             if the specified permission is {@code null}
      * @see AccessController#checkPermission(Permission)
-     * @since Android 1.0
      */
     public void checkPermission(Permission perm) throws AccessControlException {
         if (perm == null) {
@@ -215,7 +212,6 @@
      *            AccessControlContext}
      * @return {@code true} if the specified object is equal to this {@code
      *         AccessControlContext}, otherwise {@code false}
-     * @since Android 1.0
      */
     @Override
     public boolean equals(Object obj) {
@@ -251,7 +247,6 @@
      * @throws SecurityException
      *             if a {@code SecurityManager} is installed and the caller does
      *             not have permission to invoke this method
-     * @since Android 1.0
      */
     public DomainCombiner getDomainCombiner() {
         SecurityManager sm = System.getSecurityManager();
@@ -271,7 +266,6 @@
      * @return the hash code value for this {@code AccessControlContext}
      * @see Object#equals(Object)
      * @see AccessControlContext#equals(Object)
-     * @since Android 1.0
      */
     public int hashCode() {
         int hash = 0;
diff --git a/security-kernel/src/main/java/java/security/AccessController.java b/security-kernel/src/main/java/java/security/AccessController.java
index 5c5bc26..b27ab53 100644
--- a/security-kernel/src/main/java/java/security/AccessController.java
+++ b/security-kernel/src/main/java/java/security/AccessController.java
@@ -75,7 +75,6 @@
      * @return the result of executing the privileged action
      * @throws NullPointerException
      *             if the specified action is {@code null}
-     * @since Android 1.0
      */
     public static <T> T doPrivileged(PrivilegedAction<T> action) {
         if (action == null) {
@@ -103,7 +102,6 @@
      * @return the result of executing the privileged action
      * @throws NullPointerException
      *             if the specified action is {@code null}
-     * @since Android 1.0
      */
     public static <T> T doPrivileged(PrivilegedAction<T> action,
             AccessControlContext context) {
@@ -134,7 +132,6 @@
      *             if the action's run method throws any checked exception
      * @throws NullPointerException
      *             if the specified action is {@code null}
-     * @since Android 1.0
      */
     public static <T> T doPrivileged(PrivilegedExceptionAction<T> action)
             throws PrivilegedActionException {
@@ -168,7 +165,6 @@
      *             if the action's run method throws any checked exception
      * @throws NullPointerException
      *             if the specified action is {@code null}
-     * @since Android 1.0
      */
     public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
             AccessControlContext context) throws PrivilegedActionException {
@@ -297,7 +293,6 @@
      *             if the specified permission is {@code null}
      * @see AccessControlContext#checkPermission(Permission)
      * 
-     * @since Android 1.0
      */
     public static void checkPermission(Permission perm)
             throws AccessControlException {
@@ -327,7 +322,6 @@
      * 
      * @return the {@code AccessControlContext} for the current {@code Thread}
      * @see Thread#currentThread
-     * @since Android 1.0
      */
     public static AccessControlContext getContext() {
 
diff --git a/security/src/main/files/certimport.sh b/security/src/main/files/certimport.sh
index f7bd8c8a..f65aff9 100755
--- a/security/src/main/files/certimport.sh
+++ b/security/src/main/files/certimport.sh
@@ -1,6 +1,39 @@
 #!/bin/bash
+#
+# 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.
+
+#
+# certimport.sh recreates the cacerts.bks file from the x509 CA
+# certificates in the cacerts directory.
+# 
+# By convention, the filenames in the cacerts directory are in the
+# format of <hash>.<n> where "hash" is the subject hash produced by:
+# 
+#     openssl x509 -subject_hash -in filename
+#
+# and the "n" is the the depth of the certificate along a chain, i.e.
+# .0 for roots, .1 for an intermediate one level deep, etc.
+#
+# The filename itself is not important, and is around just for convention sake.
+#
+# usage is simply running ./certimport.sh from the scripts directory
+# 
 # java version >= 1.6 is required for this script.
+# 
 # This script was tested to work with bouncycastle 1.32.
+#
 
 set -x
 set -e
diff --git a/security/src/main/java/java/security/MessageDigest.java b/security/src/main/java/java/security/MessageDigest.java
index cb8fc08..6996054 100644
--- a/security/src/main/java/java/security/MessageDigest.java
+++ b/security/src/main/java/java/security/MessageDigest.java
@@ -170,7 +170,6 @@
      * @param arg0
      *            the {@code byte} to update this {@code MessageDigest} with
      * @see #reset()
-     * @since Android 1.0
      */
     public void update(byte arg0) {
         engineUpdate(arg0);
@@ -222,7 +221,6 @@
      * 
      * @return the computed one way hash value
      * @see #reset
-     * @since Android 1.0
      */
     public byte[] digest() {
         return engineDigest();
diff --git a/security/src/main/java/java/security/Security.java b/security/src/main/java/java/security/Security.java
index 6ff38ad..1fea1bd 100644
--- a/security/src/main/java/java/security/Security.java
+++ b/security/src/main/java/java/security/Security.java
@@ -70,8 +70,7 @@
                 try {
                     InputStream configStream =
                         getClass().getResourceAsStream("security.properties"); //$NON-NLS-1$
-                    InputStream input =
-                        new BufferedInputStream(configStream, 8192);
+                    InputStream input = new BufferedInputStream(configStream);
                     secprops.load(input);
                     loaded = true;
                     configStream.close();
diff --git a/security/src/main/java/java/security/acl/package.html b/security/src/main/java/java/security/acl/package.html
index 3102fc2..b8ec061 100644
--- a/security/src/main/java/java/security/acl/package.html
+++ b/security/src/main/java/java/security/acl/package.html
@@ -10,6 +10,5 @@
 for the creation of new owners {@link java.security.acl.Owner}, and for the registration of
 new permissions {@link java.security.acl.Permission} are provided.
 </p>
-@since Android 1.0
 </body>
 </html>
diff --git a/security/src/main/java/java/security/cert/X509CertSelector.java b/security/src/main/java/java/security/cert/X509CertSelector.java
index e2de95b..0460fd6 100644
--- a/security/src/main/java/java/security/cert/X509CertSelector.java
+++ b/security/src/main/java/java/security/cert/X509CertSelector.java
@@ -751,7 +751,6 @@
         ArrayList result = new ArrayList();
         for (int tag=0; tag<9; tag++) {
             if (subjectAltNames[tag] != null) {
-                Integer teg = new Integer(tag);
                 for (int name=0; name<subjectAltNames[tag].size(); name++) {
                     Object neim = subjectAltNames[tag].get(name);
                     if (neim instanceof byte[]) {
@@ -760,7 +759,7 @@
                         System.arraycopy(arr_neim, 0, neim, 0, arr_neim.length);
                     }
                     List list = new ArrayList(2);
-                    list.add(teg);
+                    list.add(Integer.valueOf(tag)); // android-changed
                     list.add(neim);
                     result.add(list);
                 }
@@ -1431,4 +1430,3 @@
         return result;
     }
 }
-
diff --git a/security/src/main/java/java/security/cert/package.html b/security/src/main/java/java/security/cert/package.html
index e3cc92b..e39b38f 100644
--- a/security/src/main/java/java/security/cert/package.html
+++ b/security/src/main/java/java/security/cert/package.html
@@ -18,6 +18,5 @@
 </p><p>
 The functionality to check the different entries and extension fields of X.509 certificates are also provided.
 </p>
-@since Android 1.0
 </body>
 </html>
diff --git a/security/src/main/java/java/security/interfaces/package.html b/security/src/main/java/java/security/interfaces/package.html
index 6f14de1..dd24196 100644
--- a/security/src/main/java/java/security/interfaces/package.html
+++ b/security/src/main/java/java/security/interfaces/package.html
@@ -10,6 +10,5 @@
 (2) Keys for the Digital Signature Algorithm (DSA) specified by FIPS-186;
 (3) Keys for a generic Elliptic Curve asymmetric encryption algorithm.
 </p>
-@since Android 1.0
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/security/src/main/java/java/security/package.html b/security/src/main/java/java/security/package.html
index b4f450e..4c5e2b4 100644
--- a/security/src/main/java/java/security/package.html
+++ b/security/src/main/java/java/security/package.html
@@ -31,6 +31,5 @@
 	implemented.
 </ul>
 </p>
-@since Android 1.0
 </body>
 </html>
diff --git a/security/src/main/java/java/security/spec/package.html b/security/src/main/java/java/security/spec/package.html
index 1a1a8e0..d75aee6 100644
--- a/security/src/main/java/java/security/spec/package.html
+++ b/security/src/main/java/java/security/spec/package.html
@@ -14,6 +14,5 @@
 The parameters for the Elliptic Curve (EC) encryption algorithm are only specified as
 input parameters to the relevant EC-generator.
 </p>
-@since Android 1.0
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/security/src/main/java/javax/security/cert/package.html b/security/src/main/java/javax/security/cert/package.html
index a58f1de..792b446 100644
--- a/security/src/main/java/javax/security/cert/package.html
+++ b/security/src/main/java/javax/security/cert/package.html
@@ -10,6 +10,5 @@
 All applications that do not have to be compatible with older versions of JSSE (that is
 before Java SDK 1.5) should only use java.security.cert.
 </p>
-@since Android 1.0
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java b/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java
index c809fe4..8edb0c5 100644
--- a/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java
+++ b/security/src/main/java/org/apache/harmony/security/fortress/DefaultPolicyParser.java
@@ -115,14 +115,11 @@
             throws Exception {
 
         boolean resolve = PolicyUtils.canExpandProperties();
-        // BEGIN android-modified
         Reader r =
             new BufferedReader(
                     new InputStreamReader(
                             AccessController.doPrivileged(
-                                    new PolicyUtils.URLLoader(location))),
-                    8192);
-        // END android-modified
+                                    new PolicyUtils.URLLoader(location))));
 
         Collection<GrantEntry> grantEntries = new HashSet<GrantEntry>();
         List<KeystoreEntry> keystores = new ArrayList<KeystoreEntry>();
diff --git a/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java b/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java
index 3b291a1..dcf4b94 100644
--- a/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java
+++ b/security/src/main/java/org/apache/harmony/security/x509/GeneralName.java
@@ -463,7 +463,7 @@
      */
     public List getAsList() {
         ArrayList result = new ArrayList();
-        result.add(new Integer(tag));
+        result.add(Integer.valueOf(tag)); // android-changed
         switch (tag) {
             case OTHER_NAME:
                 result.add(((OtherName) name).getEncoded());
diff --git a/security/src/main/java/org/bouncycastle/crypto/macs/HMac.java b/security/src/main/java/org/bouncycastle/crypto/macs/HMac.java
index 0bd4d39..7272f32 100644
--- a/security/src/main/java/org/bouncycastle/crypto/macs/HMac.java
+++ b/security/src/main/java/org/bouncycastle/crypto/macs/HMac.java
@@ -32,23 +32,23 @@
     {
         blockLengths = new Hashtable();
         
-        blockLengths.put("GOST3411", new Integer(32));
+        blockLengths.put("GOST3411", Integer.valueOf(32));
         
-        blockLengths.put("MD2", new Integer(16));
-        blockLengths.put("MD4", new Integer(64));
-        blockLengths.put("MD5", new Integer(64));
+        blockLengths.put("MD2", Integer.valueOf(16));
+        blockLengths.put("MD4", Integer.valueOf(64));
+        blockLengths.put("MD5", Integer.valueOf(64));
         
-        blockLengths.put("RIPEMD128", new Integer(64));
-        blockLengths.put("RIPEMD160", new Integer(64));
+        blockLengths.put("RIPEMD128", Integer.valueOf(64));
+        blockLengths.put("RIPEMD160", Integer.valueOf(64));
         
-        blockLengths.put("SHA-1", new Integer(64));
-        blockLengths.put("SHA-224", new Integer(64));
-        blockLengths.put("SHA-256", new Integer(64));
-        blockLengths.put("SHA-384", new Integer(128));
-        blockLengths.put("SHA-512", new Integer(128));
+        blockLengths.put("SHA-1", Integer.valueOf(64));
+        blockLengths.put("SHA-224", Integer.valueOf(64));
+        blockLengths.put("SHA-256", Integer.valueOf(64));
+        blockLengths.put("SHA-384", Integer.valueOf(128));
+        blockLengths.put("SHA-512", Integer.valueOf(128));
         
-        blockLengths.put("Tiger", new Integer(64));
-        blockLengths.put("Whirlpool", new Integer(64));
+        blockLengths.put("Tiger", Integer.valueOf(64));
+        blockLengths.put("Whirlpool", Integer.valueOf(64));
     }
     
     private static int getByteLength(
diff --git a/security/src/main/java/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java b/security/src/main/java/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java
index cb3b172..24233d6 100644
--- a/security/src/main/java/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java
+++ b/security/src/main/java/org/bouncycastle/jce/provider/JDKKeyPairGenerator.java
@@ -397,9 +397,9 @@
 //        static {
 //            ecParameters = new Hashtable();
 //
-//            ecParameters.put(new Integer(192), new ECGenParameterSpec("prime192v1"));
-//            ecParameters.put(new Integer(239), new ECGenParameterSpec("prime239v1"));
-//            ecParameters.put(new Integer(256), new ECGenParameterSpec("prime256v1"));
+//            ecParameters.put(Integer.valueOf(192), new ECGenParameterSpec("prime192v1"));
+//            ecParameters.put(Integer.valueOf(239), new ECGenParameterSpec("prime239v1"));
+//            ecParameters.put(Integer.valueOf(256), new ECGenParameterSpec("prime256v1"));
 //        }
 //
 //        public EC()
@@ -421,7 +421,7 @@
 //        {
 //            this.strength = strength;
 //            this.random = random;
-//            this.ecParams = (ECGenParameterSpec)ecParameters.get(new Integer(strength));
+//            this.ecParams = (ECGenParameterSpec)ecParameters.get(Integer.valueOf(strength));
 //
 //            if (ecParams != null)
 //            {
diff --git a/security/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java b/security/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java
index 7846530..3cf05b1 100644
--- a/security/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java
+++ b/security/src/main/java/org/bouncycastle/jce/provider/JDKPKCS12KeyStore.java
@@ -704,9 +704,7 @@
             throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
         }
 
-        // BEGIN android-modified
-        BufferedInputStream             bufIn = new BufferedInputStream(stream, 8192);
-        // END android-modified
+        BufferedInputStream             bufIn = new BufferedInputStream(stream);
 
         bufIn.mark(10);
 
diff --git a/security/src/main/java/org/bouncycastle/jce/provider/JDKX509CertificateFactory.java b/security/src/main/java/org/bouncycastle/jce/provider/JDKX509CertificateFactory.java
index 899cdd0..31507c6 100644
--- a/security/src/main/java/org/bouncycastle/jce/provider/JDKX509CertificateFactory.java
+++ b/security/src/main/java/org/bouncycastle/jce/provider/JDKX509CertificateFactory.java
@@ -282,9 +282,7 @@
             
             if (!in.markSupported())
             {
-                // BEGIN android-modified
-                in = new BufferedInputStream(in, 8192);
-                // END android-modified
+                in = new BufferedInputStream(in);
             }
             
             in.mark(10);
@@ -377,9 +375,7 @@
             
             if (!inStream.markSupported())
             {
-                // BEGIN android-modified
-                inStream = new BufferedInputStream(inStream, 8192);
-                // END android-modified
+                inStream = new BufferedInputStream(inStream);
             }
             
             inStream.mark(10);
diff --git a/security/src/main/java/org/bouncycastle/jce/provider/PKIXCertPath.java b/security/src/main/java/org/bouncycastle/jce/provider/PKIXCertPath.java
index 25053c3..69585b8 100644
--- a/security/src/main/java/org/bouncycastle/jce/provider/PKIXCertPath.java
+++ b/security/src/main/java/org/bouncycastle/jce/provider/PKIXCertPath.java
@@ -202,9 +202,7 @@
             }
             else if (encoding.equalsIgnoreCase("PKCS7") || encoding.equalsIgnoreCase("PEM"))
             {
-                // BEGIN android-modified
-                inStream = new BufferedInputStream(inStream, 8192);
-                // END android-modified
+                inStream = new BufferedInputStream(inStream);
                 certificates = new ArrayList();
                 CertificateFactory certFactory= CertificateFactory.getInstance("X.509", "BC");
                 Certificate cert;
diff --git a/security/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages_de.properties b/security/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages_de.properties
deleted file mode 100644
index 52b5e5b..0000000
--- a/security/src/main/java/org/bouncycastle/x509/CertPathReviewerMessages_de.properties
+++ /dev/null
@@ -1,563 +0,0 @@
-
-## constructor exceptions 
-
-# cert path is empty
-CertPathReviewer.emptyCertPath.title = CertPath is empty
-CertPathReviewer.emptyCertPath.text = PKIXCertPathReviewer: the CertPath is empty.
-CertPathReviewer.emptyCertPath.summary = PKIXCertPathReviewer: the CertPath is empty.
-CertPathReviewer.emptyCertPath.details = PKIXCertPathReviewer: the CertPath is empty.
-
-## name constraints processing errors
-
-# cert DN is not in the permitted tree
-# {0} DN as String 
-CertPathReviewer.notPermittedDN.title = Name constraint error: certificate DN is not permitted
-CertPathReviewer.notPermittedDN.text = Name constraint error: the certificate DN {0} is not permitted.
-CertPathReviewer.notPermittedDN.summary = Name constraint error: certificate DN is not permitted.
-CertPathReviewer.notPermittedDN.details = Name constraint checking error. The certificate DN {0} is not in the permitted set of DNs.
-
-# cert DN is in the excluded tree
-# {0} DN as String
-CertPathReviewer.excludedDN.title = Name constraint error: certificate DN is excluded
-CertPathReviewer.excludedDN.text = Name constraint error: The certificate DN {0} is excluded.
-CertPathReviewer.excludedDN.summary = Name constraint error: certificate DN is excluded.
-CertPathReviewer.excludedDN.details = Name constraint checking error. The certificate DN {0} is inside of the excluded set of DNs.
-
-# cert email is not in the permitted tree
-# {0} email address as String
-CertPathReviewer.notPermittedEmail.title = Name constraint error: not permitted email address
-CertPathReviewer.notPermittedEmail.text = Name constraint error: certificate contains the not permitted email address {0}.
-CertPathReviewer.notPermittedEmail.summary = Name constraint error: not permitted email address.
-CertPathReviewer.notPermittedEmail.details = Name constraint checking error. The certificate contains the email address {0} which is not in the permitted set of email addresses.
-
-# cert email is in the excluded tree
-# {0} email as String
-CertPathReviewer.excludedEmail.title = Name constraint error: excluded email address
-CertPathReviewer.excludedEmail.text = Name constraint error: certificate contains the excluded email address {0}. 
-CertPathReviewer.excludedEmail.summary = Name constraint error: excluded email address.
-CertPathReviewer.excludedEmail.details = Name constraint checking error. The certificate contains the email address {0} which is in the excluded set of email addresses.
-
-# cert IP is not in the permitted tree
-# {0} ip address as String
-CertPathReviewer.notPermittedIP.title = Name constraint error: not permitted IP address
-CertPathReviewer.notPermittedIP.text = Name constraint error: certificate contains the not permitted IP address {0}.
-CertPathReviewer.notPermittedIP.summary = Name constraint error: not permitted IP address.
-CertPathReviewer.notPermittedIP.details = Name constraint checking error. The certificate contains the IP address {0} which is not in the permitted set of IP addresses.
-
-# cert ip is in the excluded tree
-# {0} ip address as String
-CertPathReviewer.excludedIP.title = Name constraint error: excluded IP address
-CertPathReviewer.excludedIP.text = Name constraint error: certificate contains the excluded IP address {0}.
-CertPathReviewer.excludedIP.summary = Name constraint error: excluded IP address.
-CertPathReviewer.excludedIP.details = Name constraint checking error. The certificate contains the IP address {0} which is in the excluded set of IP addresses.
-
-# error processing the name constraints extension
-CertPathReviewer.ncExtError.title = Name constraint checking failed
-CertPathReviewer.ncExtError.text = Name constraint checking failed: there was an error processing the name constraints extension of the certificate.
-CertPathReviewer.ncExtError.summary = Error processing the name constraints extension.
-CertPathReviewer.ncExtError.details = Name constraint checking failed: there was an error processing the name constraints extension of the certificate.
-
-# error processing the subject alternative name extension
-CertPathReviewer.subjAltNameExtError.title = Name constraint checking failed
-CertPathReviewer.subjAltNameExtError.text = Name constraint checking failed: there was an error processing the subject alernative name extension of the certificate.
-CertPathReviewer.subjAltNameExtError.summary = Error processing the subject alternative name extension.
-CertPathReviewer.subjAltNameExtError.details = Name constraint checking failed: there was an error processing the subject alternative name extension of the certificate.
-
-# exception extracting subject name when checking subtrees
-# {0} subject Principal
-CertPathReviewer.ncSubjectNameError.title = Name constraint checking failed
-CertPathReviewer.ncSubjectNameError.text = Name constraint checking failed: there was an exception extracting the DN from the certificate.
-CertPathReviewer.ncSubjectNameError.summary = Name constraint checking failed: exception extracting the DN.
-CertPathReviewer.ncSubjectNameError.details = Name constraint checking failed: there was an exception extracting the DN from the certificate.
-
-
-## path length errors
-
-# max path length extended
-CertPathReviewer.pathLenghtExtended.title = Maximum path length extended 
-CertPathReviewer.pathLenghtExtended.text = Certificate path invalid: Maximum path length extended.
-CertPathReviewer.pathLenghtExtended.summary = Certificate path invalid: Maximum path length extended.
-CertPathReviewer.pathLenghtExtended.details = Certificate path invalid: Maximum path length extended.
-
-# error reading length constraint from basic constraint extension
-CertPathReviewer.processLengthConstError.title = Path length checking failed
-CertPathReviewer.processLengthConstError.text = Path length checking failed: there was an error processing the basic constraint extension of the certificate. 
-CertPathReviewer.processLengthConstError.summary = Error processing the subject alternative name extension.
-CertPathReviewer.processLengthConstError.details = Path length checking failed: there was an error processing the basic constraint extension of the certificate.
-
-
-## path length notifications
-
-# total path length as defined in rfc 3280
-# {0} the path length as Integer
-CertPathReviewer.totalPathLength.title = Total path length
-CertPathReviewer.totalPathLength.text = The total path length without self-signed certificates is {0}.
-CertPathReviewer.totalPathLength.summary = The total path length without self-signed certificates is {0}.
-CertPathReviewer.totalPathLength.details = The total path length without self-signed certificates, as defined in RFC 3280, is {0}.
-
-
-## critical extensions errors
-
-# one unknown critical extension
-# {0} extension as String
-CertPathReviewer.unknownCriticalExt.title = Unknown critical extension
-CertPathReviewer.unknownCriticalExt.text = The certificate contains the unknown critical extension {0}.
-CertPathReviewer.unknownCriticalExt.summary = Unknown critical extension: {0}.
-CertPathReviewer.unknownCriticalExt.details = The certificate contains the unknown critical extension with the OID {0}.
-
-# more unknown critical extensions
-# {0} extensions as Set of Strings
-CertPathReviewer.unknownCriticalExts.title = Unknown critical extensions
-CertPathReviewer.unknownCriticalExts.text = The certificate contains two or more unknown critical extensions: {0}.
-CertPathReviewer.unknownCriticalExts.summary = Unknown critical extensions: {0}.
-CertPathReviewer.unknownCriticalExts.details = The certificate contains two or more unknown critical extensions with the OIDs: {0}.
-
-# error processing critical extension
-# {0} the message of the underlying exception
-# {1} the underlying exception
-CertPathReviewer.criticalExtensionError.title = Error processing a critical extension
-CertPathReviewer.criticalExtensionError.text = Error processing a critical extension. Cause: {0}.
-CertPathReviewer.criticalExtensionError.summary = Error processing a critical extension. Cause: {0}.
-CertPathReviewer.criticalExtensionError.details = Error processing a critical extension. Cause: {0}.
-
-# error initializing the certpath checkers
-# {0} the message of the underlying exception
-# {1} the underlying exception
-CertPathReviewer.certPathCheckerError.title = Checking critical extensions failed
-CertPathReviewer.certPathCheckerError.text = Checking critical extensions failed: there was an error initializing a CertPathChecker.
-CertPathReviewer.certPathCheckerError.summary = Checking critical extensions failed: error initializing a CertPathChecker
-CertPathReviewer.certPathCheckerError.details = Checking critical extensions failed: there was an error initializing a CertPathChecker. Cause: {0}
-
-
-## check signature errors
-
-# trustanchor found, but certificate validation failed
-CertPathReviewer.trustButInvalidCert.title = TrustAnchor found, but certificate invalid
-CertPathReviewer.trustButInvalidCert.text = A TrustAnchor was found but the certificate validation failed.
-CertPathReviewer.trustButInvalidCert.summary = TrustAnchor found but certificate validation failed.
-CertPathReviewer.trustButInvalidCert.details = A TrustAnchor was found but the certificate validation failed.
-
-# trustanchor - cannot extract issuer
-CertPathReviewer.trustAnchorIssuerError.title = Finding TrustAnchor failed 
-CertPathReviewer.trustAnchorIssuerError.text = Finding TrustAnchor failed: cannot extract issuer from certificate.
-CertPathReviewer.trustAnchorIssuerError.summary = Finding TrustAnchor failed: cannot extract issuer from certificate.
-CertPathReviewer.trustAnchorIssuerError.details = Finding TrustAnchor failed: cannot extract issuer from certificate.
-
-# no trustanchor was found for the certificate path
-# {0} issuer of the root certificate of the path
-# {1} number of trusted root certificates (trustanchors) provided
-CertPathReviewer.noTrustAnchorFound.title = No trusted root certificate found
-CertPathReviewer.noTrustAnchorFound.text = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. The name of the CA is "{0}".
-CertPathReviewer.noTrustAnchorFound.summary = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation.
-CertPathReviewer.noTrustAnchorFound.details = The root certificate of the certificate path was issued by a CA that is not in the the trusted-root-certificate-store used for the path validation. The name of the CA is "{0}". The trusted-root-certificate store contains {1} CA(s).
-
-# conflicting trust anchors
-# {0} number of trustanchors found (Integer)
-# {1} the ca name
-CertPathReviewer.conflictingTrustAnchors.title = Corrupt trust root store
-CertPathReviewer.conflictingTrustAnchors.text = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key.
-CertPathReviewer.conflictingTrustAnchors.summary = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key.
-CertPathReviewer.conflictingTrustAnchors.details = Warning: corrupt trust root store: There are {0} trusted public keys for the CA "{1}" - please ensure with CA which is the correct key.
-
-# trustanchor DN is invalid
-# {0} DN of the Trustanchor
-CertPathReviewer.trustDNInvalid.title = DN of TrustAnchor is improperly specified
-CertPathReviewer.trustDNInvalid.text = The DN of the TrustAnchor is improperly specified: {0}.
-CertPathReviewer.trustDNInvalid.summary = The DN of the TrustAnchor is improperly specified.
-CertPathReviewer.trustDNInvalid.details = The DN of the TrustAnchor is improperly specified: {0}. It's not a valid X.500 name. See RFC 1779 or RFC 2253. 
-
-# trustanchor public key algorithm error
-CertPathReviewer.trustPubKeyError.title = Error processing public key of the trust anchor
-CertPathReviewer.trustPubKeyError.text = Error processing public key of the trust anchor.
-CertPathReviewer.trustPubKeyError.summary = Error processing public key of the trust anchor.
-CertPathReviewer.trustPubKeyError.details = Error processing public key of the trust anchor. Could not extract the AlorithmIdentifier for the key.
-
-# can not verifiy signature: issuer public key unknown
-CertPathReviewer.NoIssuerPublicKey.title = Can not verify the certificate signature 
-CertPathReviewer.NoIssuerPublicKey.text = Can not verify the certificate signature: Issuer public key is unknown.
-CertPathReviewer.NoIssuerPublicKey.summary = Can not verify the certificate signature: Issuer public key is unknown.
-CertPathReviewer.NoIssuerPublicKey.details = Can not verify the certificate signature: Issuer public key is unknown.
-
-# signature can not be verified
-# {0} message of the underlying exception (english)
-# {1} the underlying exception
-CertPathReviewer.signatureNotVerified.title = Certificate signature invalid
-CertPathReviewer.signatureNotVerified.text = The certificate signature is invalid.
-CertPathReviewer.signatureNotVerified.summary = The certificate signature is invalid.
-CertPathReviewer.signatureNotVerified.details = The certificate signature is invalid. Cause: {0}
-
-# certificate expired
-# {0} the date the certificate expired 
-CertPathReviewer.certificateExpired.title = Certificate is expired
-CertPathReviewer.certificateExpired.text = Could not validate the certificate. Certificate expired on {0,date} {0,time,full}.
-CertPathReviewer.certificateExpired.summary = Certificate expired on {0,date} {0,time,full}.
-CertPathReviewer.certificateExpired.details = Could not validate the certificate. Certificate expired on {0,date} {0,time,full}. 
-
-# certificate not yet valid
-# {0} the date from which on the certificate is valid
-CertPathReviewer.certificateNotYetValid.title = Certificate is not yet valid
-CertPathReviewer.certificateNotYetValid.text = Could not validate the certificate. Certificate is not valid untill {0,date} {0,time,full}.
-CertPathReviewer.certificateNotYetValid.summary = Certificate is not valid untill {0,date} {0,time,full}.
-CertPathReviewer.certificateNotYetValid.details = Could not validate the certificate. Certificate is not valid untill {0,date} {0,time,full}. 
-
-# certificate invalid issuer DN
-# {0} expected issuer DN as String
-# {1} found issuer DN as String
-CertPathReviewer.certWrongIssuer.title = Issuer of certificate not valid
-CertPathReviewer.certWrongIssuer.text = Issuer of certificate is not valid. Expected {0}, but found {1}. 
-CertPathReviewer.certWrongIssuer.summary = Issuer of certificate is not valid. 
-CertPathReviewer.certWrongIssuer.details = Issuer of certificate is not valid. Expected {0}, but found {1}.
-
-# intermediate certificate is no ca cert
-CertPathReviewer.noCACert.title = Certificate is no CA certificate
-CertPathReviewer.noCACert.text = Intermediate certificate is no CA certificate.
-CertPathReviewer.noCACert.summary = The certificate is no CA certificate.
-CertPathReviewer.noCACert.details = The certificate is no CA certificate but used as one.
-
-# cert laks basic constraints
-CertPathReviewer.noBasicConstraints.title = Certificate has no basic constraints
-CertPathReviewer.noBasicConstraints.text = Intermediate certificate has no basic constraints.
-CertPathReviewer.noBasicConstraints.summary = Intermediate certificate has no basic constraints.
-CertPathReviewer.noBasicConstraints.details = Intermediate certificate has no basic constraints.
-
-# error processing basic constraints
-CertPathReviewer.errorProcesingBC.title = Error processing the basic constraints extension
-CertPathReviewer.errorProcesingBC.text = There was an error while processing the basic constraints extension of this certificate.
-CertPathReviewer.errorProcesingBC.summary = Error processing the basic constraints extension. 
-CertPathReviewer.errorProcesingBC.details = There was an error while processing the basic constraints extension of this certificate.
-
-# certificate not usable for signing certs
-CertPathReviewer.noCertSign.title = Key not usable for signing certificates
-CertPathReviewer.noCertSign.text = The key usage constraint does not allow the use of this certificate key for signing certificates.
-CertPathReviewer.noCertSign.summary = The certificate key can not be used for signing certificates.
-CertPathReviewer.noCertSign.details = The key usage constraint does not allow the use of this certificate key for signing certificates.
-
-# error processing public key
-CertPathReviewer.pubKeyError.title = Error processing public key
-CertPathReviewer.pubKeyError.text = Error processing public key of the certificate.
-CertPathReviewer.pubKeyError.summary = Error processing public key of the certificate.
-CertPathReviewer.pubKeyError.details = Error processing public key of the certificate. Could not extract the AlorithmIdentifier for the key.
-
-
-## check signatures notifications
-
-# certificate path validation date
-# {0} date for which the cert path is validated
-# {1} current date
-CertPathReviewer.certPathValidDate.title = Certificate path validation date
-CertPathReviewer.certPathValidDate.text = Der Zertifikatspfad wurde am {0,date} {0,time,full} angewendet. Er wurde am {1,date} {1,time,full} validiert.
-CertPathReviewer.certPathValidDate.summary = The certificate path was validated for {0,date} {0,time,full}. It was validated at {1,date} {1,time,full}.
-CertPathReviewer.certPathValidDate.details = The certificate path was validated for {0,date} {0,time,full}. It was validated at {1,date} {1,time,full}.
-
-
-## check policy errors
-
-# error processing certificate policy extension
-CertPathReviewer.policyExtError.title = Policy checking failed
-CertPathReviewer.policyExtError.text = Policy checking failed: there was an error processing the certificate policy extension. 
-CertPathReviewer.policyExtError.summary = Error processing the certificate policy extension.
-CertPathReviewer.policyExtError.details = Policy checking failed: there was an error processing the certificate policy extension. 
-
-# error processing policy constraints extension
-CertPathReviewer.policyConstExtError.title = Policy checking failed
-CertPathReviewer.policyConstExtError.text = Policy checking failed: there was an error processing the policy constraints extension.
-CertPathReviewer.policyConstExtError.summary = Error processing the policy constraints extension.
-CertPathReviewer.policyConstExtError.details = Policy checking failed: there was an error processing the policy constraints extension.
-
-# error processing policy mapping extension
-CertPathReviewer.policyMapExtError.title = Policy checking failed
-CertPathReviewer.policyMapExtError.text = Policy checking failed: there was an error processing the policy mapping extension.
-CertPathReviewer.policyMapExtError.summary = Error processing the policy mapping extension.
-CertPathReviewer.policyMapExtError.details = Policy checking failed: there was an error processing the policy mapping extension.
-
-# error processing inhibit any policy extension
-CertPathReviewer.policyInhibitExtError.title = Policy checking failed
-CertPathReviewer.policyInhibitExtError.text = Policy checking failed: there was an error processing the policy mapping extension.
-CertPathReviewer.policyInhibitExtError.summary = Error processing the inhibit any policy extension.
-CertPathReviewer.policyInhibitExtError.details = Policy checking failed: there was an error processing the policy mapping extension.
-
-# error building qualifier set
-CertPathReviewer.policyQualifierError.title = Policy checking failed
-CertPathReviewer.policyQualifierError.text = Policy checking failed: error building the policy qualifier set.
-CertPathReviewer.policyQualifierError.summary = Policy checking failed: error building the policy qualifier set.
-CertPathReviewer.policyQualifierError.details = Policy checking failed: error building the policy qualifier set.
-
-# no valid policy tree - explicit policy required
-CertPathReviewer.noValidPolicyTree.title = Policy checking failed
-CertPathReviewer.noValidPolicyTree.text = Policy checking failed: no valid policy tree found when one expected.
-CertPathReviewer.noValidPolicyTree.summary = Policy checking failed: no valid policy tree found when one expected.
-CertPathReviewer.noValidPolicyTree.details = Policy checking failed: no valid policy tree found when one expected.
-
-# expicit policy requested, but no policy available
-CertPathReviewer.explicitPolicy.title = Policy checking failed
-CertPathReviewer.explicitPolicy.text = Policy checking failed: explicit policy requested but no policy available.
-CertPathReviewer.explicitPolicy.summary = Policy checking failed: explicit policy requested but no policy available.
-CertPathReviewer.explicitPolicy.details = Policy checking failed: explicit policy requested but no policy available.
-
-# path processing failed on policy
-CertPathReviewer.invalidPolicy.title = Path processing failed on policy
-CertPathReviewer.invalidPolicy.text = Path processing failed on policy.
-CertPathReviewer.invalidPolicy.summary = Path processing failed on policy.
-CertPathReviewer.invalidPolicy.details = Path processing failed on policy.
-
-# invalid policy mapping
-CertPathReviewer.invalidPolicyMapping.title = Invalid policy mapping 
-CertPathReviewer.invalidPolicyMapping.text = Certificate contains an invalid policy mapping.
-CertPathReviewer.invalidPolicyMapping.summary = Certificate contains an invalid policy mapping. 
-CertPathReviewer.invalidPolicyMapping.details = Certificate contains a policy mapping including the value any policy which is invalid.
-
-## check CRL notifications
-
-# found local valid CRL
-# {0} thisUpdate of the CRL
-# {1} nextUpdate of the CRL
-CertPathReviewer.localValidCRL.title = Found valid local CRL
-CertPathReviewer.localValidCRL.text = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}.
-CertPathReviewer.localValidCRL.summary = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}.
-CertPathReviewer.localValidCRL.details = Found a valid CRL in local certstore. Issued on {0,date}, next update {1,date}.
-
-
-# found matching CRL, but not valid
-# {0} thisUpdate of the CRL
-# {1} nextUpdate of the CRL
-CertPathReviewer.localInvalidCRL.title = Local CRL outdated
-CertPathReviewer.localInvalidCRL.text = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}.
-CertPathReviewer.localInvalidCRL.summary = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}.
-CertPathReviewer.localInvalidCRL.details = Did not use a matching CRL in a local certstore, because it is outdated. Issued on {0,date}, next update {1,date}.
-
-# found a valid crl at crl distribution point
-# {0} thisUpdate of the CRL
-# {1} nextUpdate of the CRL
-# {2} the url of the distribution point
-CertPathReviewer.onlineValidCRL.title = Found valid CRL at CRL distribution point
-CertPathReviewer.onlineValidCRL.text = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}.
-CertPathReviewer.onlineValidCRL.summary = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}.
-CertPathReviewer.onlineValidCRL.details = Found a valid CRL at: {2}. Issued on {0,date}, next update on {1,date}.
-
-# found an invalid CRL at crl distribution point
-# {0} thisUpdate of the CRL
-# {1} nextUpdate of the CRL
-# {2} the url of the distribution point
-CertPathReviewer.onlineInvalidCRL.title = Outdated CRL at CRL distribution point
-CertPathReviewer.onlineInvalidCRL.text = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}.
-CertPathReviewer.onlineInvalidCRL.summary = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}.
-CertPathReviewer.onlineInvalidCRL.details = The CRL loaded from {2} was outdated. Issued on {0,date}, next update on {1,date}.
-
-# Certificate not revoked
-CertPathReviewer.notRevoked.title = Certificate not revoked
-CertPathReviewer.notRevoked.text = The certificate was not revoked.
-CertPathReviewer.notRevoked.summary = The certificate was not revoked.
-CertPathReviewer.notRevoked.details = The certificate was not revoked.
-
-# CRL found: certificate was revoked, but after the validationDate
-# {0} the date the certificate was revoked
-# {1} the reason for revoking the certificate
-CertPathReviewer.revokedAfterValidation.title = Certificate was revoked after the validation date
-CertPathReviewer.revokedAfterValidation.text = The certificate was revoked after the validation date at {0,date} {0,time,full}. Reason: {1}.
-CertPathReviewer.revokedAfterValidation.summary = The certificate was revoked after the validation date at {0,date} {0,time,full}.
-CertPathReviewer.revokedAfterValidation.details = The certificate was revoked after the validation date at {0,date} {0,time,full}. Reason: {1}.
-
-# updated crl available
-# {0} date since when the update is available
-CertPathReviewer.crlUpdateAvailable.title = CRL update available
-CertPathReviewer.crlUpdateAvailable.text = An update for the CRL of this certificate is available since {0,date} {0,time,full}.
-CertPathReviewer.crlUpdateAvailable.summary = An update for the CRL of this certificate is available since {0,date} {0,time,full}.
-CertPathReviewer.crlUpdateAvailable.details = An update for the CRL of this certificate is available since {0,date} {0,time,full}.
-
-# crl distribution point url
-# {0} the crl distribution point url as String
-CertPathReviewer.crlDistPoint.title = CRL distribution point
-CertPathReviewer.crlDistPoint.text = A CRL can be obtained from: {0}.
-CertPathReviewer.crlDistPoint.summary = A CRL can be obtained from: {0}.
-CertPathReviewer.crlDistPoint.details = A CRL can be obtained from: {0}.
-
-# ocsp location
-# {0} the url on which the ocsp service can be found
-CertPathReviewer.ocspLocation.title = OCSP responder location
-CertPathReviewer.ocspLocation.text = OCSP responder location: {0}.
-CertPathReviewer.ocspLocation.summary = OCSP responder location: {0}.
-CertPathReviewer.ocspLocation.details = OCSP responder location: {0}.
-
-# unable to get crl from crl distribution point
-# {0} the url of the distribution point
-# {1} the message of the occured exception
-# {2} the occured exception
-CertPathReviewer.loadCrlDistPointError.title = Cannot load CRL from CRL distribution point
-CertPathReviewer.loadCrlDistPointError.text = Unable to load a CRL from: {0}. An Exception occured.
-CertPathReviewer.loadCrlDistPointError.summary = Unable to load a CRL from: {0}. An Exception occured.
-CertPathReviewer.loadCrlDistPointError.details = Unable to load a CRL from: {0}. An Exception occured: Cause: {1}.
-
-# no crl found in certstores
-# {0} the issuers which we searched for
-# {1} list of crl issuer names that are found in the certstores
-# {2} number of crls in the certstores
-CertPathReviewer.noCrlInCertstore.title = No matching CRL found in local certstores
-CertPathReviewer.noCrlInCertstore.text = No matching CRL was found in the provided local certstore.
-CertPathReviewer.noCrlInCertstore.summary = No matching CRL was found in the provided local certstore.
-CertPathReviewer.noCrlInCertstore.details = No matching CRL was found in the provided local certstore. \
-No CRL was found for the selector "{0}". The {2} CRL(s) in the certstores are from "{1}".
-
-
-## check CRL exceptions
-
-# cannot extract issuer from certificate
-CertPathReviewer.crlIssuerException.title = CRL checking failed
-CertPathReviewer.crlIssuerException.text = CRL checking failed: cannot extract issuer from certificate.
-CertPathReviewer.crlIssuerException.summary = CRL checking failed: cannot extract issuer from certificate.
-CertPathReviewer.crlIssuerException.details = CRL checking failed: cannot extract issuer from certificate.
-
-# cannot extract crls
-# {0} message from the underlying exception
-# {1} the underlying exception
-CertPathReviewer.crlExtractionError.title = CRL checking failed
-CertPathReviewer.crlExtractionError.text = CRL checking failed: Cannot extract CRL from CertStore.
-CertPathReviewer.crlExtractionError.summary = CRL checking failed: Cannot extract CRL from CertStore.
-CertPathReviewer.crlExtractionError.details = CRL checking failed: Cannot extract CRL from CertStore. Cause: {0}.
-
-# Issuer certificate key usage extension does not permit crl signing
-CertPathReviewer.noCrlSigningPermited.title = CRL checking failed
-CertPathReviewer.noCrlSigningPermited.text = CRL checking failed: issuer certificate does not permit CRL signing.
-CertPathReviewer.noCrlSigningPermited.summary = CRL checking failed: issuer certificate does not permit CRL signing.
-CertPathReviewer.noCrlSigningPermited.details = CRL checking failed: issuer certificate does not permit CRL signing.
-
-# can not verify crl: issuer public key unknown
-CertPathReviewer.crlNoIssuerPublicKey.title = CRL checking failed
-CertPathReviewer.crlNoIssuerPublicKey.text = CRL checking failed: Can not verify the CRL: Issuer public key is unknown.
-CertPathReviewer.crlNoIssuerPublicKey.summary = CRL checking failed: Can not verify the CRL: Issuer public key is unknown.
-CertPathReviewer.crlNoIssuerPublicKey.details = CRL checking failed: Can not verify the CRL: Issuer public key is unknown.
-
-# crl verification failed
-CertPathReviewer.crlVerifyFailed.title = CRL checking failed
-CertPathReviewer.crlVerifyFailed.text = CRL checking failed: CRL signature is invalid.
-CertPathReviewer.crlVerifyFailed.summary = CRL checking failed: CRL signature is invalid.
-CertPathReviewer.crlVerifyFailed.details = CRL checking failed: CRL signature is invalid.
-
-# no valid CRL found
-CertPathReviewer.noValidCrlFound.title = CRL checking failed
-CertPathReviewer.noValidCrlFound.text = CRL checking failed: no valid CRL found.
-CertPathReviewer.noValidCrlFound.summary = CRL checking failed: no valid CRL found.
-CertPathReviewer.noValidCrlFound.details = CRL checking failed: no valid CRL found.
-
-# No base CRL for delta CRL
-CertPathReviewer.noBaseCRL.title = CRL checking failed
-CertPathReviewer.noBaseCRL.text = CRL checking failed: no base CRL found for delta CRL.
-CertPathReviewer.noBaseCRL.summary = CRL checking failed: no base CRL found for delta CRL.
-CertPathReviewer.noBaseCRL.details = CRL checking failed: no base CRL found for delta CRL.
-
-# certificate revoked
-# {0} the date the certificate was revoked
-# {1} the reason for revoking the certificate
-CertPathReviewer.certRevoked.title = Certificate was revoked
-CertPathReviewer.certRevoked.text = The certificate is invalid, because it was revoked at {0,date} {0,time,full}. Reason: {1}.
-CertPathReviewer.certRevoked.summary = The certificate is invalid, because it was revoked at {0,date} {0,time,full}.
-CertPathReviewer.certRevoked.details = The certificate is invalid, because it was revoked at {0,date} {0,time,full}. Reason: {1}.
-
-# error processing issuing distribution point extension
-CertPathReviewer.distrPtExtError.title = CRL checking failed
-CertPathReviewer.distrPtExtError.text = CRL checking failed: there was an error processing the issuing distribution point extension. 
-CertPathReviewer.distrPtExtError.summary = Error processing the issuing distribution point extension.
-CertPathReviewer.distrPtExtError.details = CRL checking failed: there was an error processing the issuing distribution point extension.
-
-# error processing crl distribution points extension
-CertPathReviewer.crlDistPtExtError.title = CRL checking failed
-CertPathReviewer.crlDistPtExtError.text = CRL checking failed: there was an error processing the crl distribution points extension.
-CertPathReviewer.crlDistPtExtError.summary = Error processing the crl distribution points extension.
-CertPathReviewer.crlDistPtExtError.details = CRL checking failed: there was an error processing the crl distribution points extension.
-
-# error processing the authority info access extension
-CertPathReviewer.crlAuthInfoAccError.title = CRL checking failed
-CertPathReviewer.crlAuthInfoAccError.text = CRL checking failed: there was an error processing the authority info access extension.
-CertPathReviewer.crlAuthInfoAccError.summary = Error processing the authority info access extension.
-CertPathReviewer.crlAuthInfoAccError.details = CRL checking failed: there was an error processing the authority info access extension.
-
-# error processing delta crl indicator extension
-CertPathReviewer.deltaCrlExtError.title = CRL checking failed
-CertPathReviewer.deltaCrlExtError.text = CRL checking failed: there was an error processing the delta CRL indicator extension. 
-CertPathReviewer.deltaCrlExtError.summary = Error processing the delta CRL indicator extension.
-CertPathReviewer.deltaCrlExtError.details = CRL checking failed: there was an error processing the delta CRL indicator extension.
-
-# error porcessing crl number extension
-CertPathReviewer.crlNbrExtError.title = CRL checking failed
-CertPathReviewer.crlNbrExtError.text = CRL checking failed: there was an error processing the CRL number extension.
-CertPathReviewer.crlNbrExtError.summary = Error processing the CRL number extension.
-CertPathReviewer.crlNbrExtError.details = CRL checking failed: there was an error processing the CRL number extension.
-
-# error processing crl reason code extension
-CertPathReviewer.crlReasonExtError.title = CRL checking failed
-CertPathReviewer.crlReasonExtError.text = CRL checking failed: there was an error processing the CRL reason code extension.
-CertPathReviewer.crlReasonExtError.summary = Error processing the CRL reason code extension.
-CertPathReviewer.crlReasonExtError.details = CRL checking failed: there was an error processing the CRL reason code extension.
-
-# error processing basic constraints extension
-CertPathReviewer.crlBCExtError.title = CRL checking failed
-CertPathReviewer.crlBCExtError.text = CRL checking failed: there was an error processing the basic constraints extension.
-CertPathReviewer.crlBCExtError.summary = Error processing the basic constraints extension.
-CertPathReviewer.crlBCExtError.details = CRL checking failed: there was an error processing the basic constraints extension.
-
-# CA Cert CRL only contains user certificates
-CertPathReviewer.crlOnlyUserCert.title = CRL checking failed
-CertPathReviewer.crlOnlyUserCert.text = CRL checking failed: CRL only contains user certificates.
-CertPathReviewer.crlOnlyUserCert.summary = CRL checking failed: CRL only contains user certificates.
-CertPathReviewer.crlOnlyUserCert.details = CRL checking failed: CRL for CA certificate only contains user certificates.
-
-# End CRL only contains CA certificates
-CertPathReviewer.crlOnlyCaCert.title = CRL checking failed
-CertPathReviewer.crlOnlyCaCert.text = CRL checking failed: CRL only contains CA certificates.
-CertPathReviewer.crlOnlyCaCert.summary = CRL checking failed: CRL only contains CA certificates.
-CertPathReviewer.crlOnlyCaCert.details = CRL checking failed: CRL for end certificate only contains CA certificates.
-
-# onlyContainsAttributeCerts boolean is asserted
-CertPathReviewer.crlOnlyAttrCert.title = CRL checking failed
-CertPathReviewer.crlOnlyAttrCert.text = CRL checking failed: CRL only contains attribute certificates.
-CertPathReviewer.crlOnlyAttrCert.summary = CRL checking failed: CRL only contains attribute certificates.
-CertPathReviewer.crlOnlyAttrCert.details = CRL checking failed: CRL only contains attribute certificates.
-
-
-## QcStatement notifications
-
-# unkown statement
-# {0} statement OID
-# {1} statement as ANS1Sequence
-CertPathReviewer.QcUnknownStatement.title = Unknown statement in QcStatement extension 
-CertPathReviewer.QcUnknownStatement.text = Unknown statement in QcStatement extension: OID = {0}
-CertPathReviewer.QcUnknownStatement.summary = Unknown statement in QcStatement extension: OID = {0}
-CertPathReviewer.QcUnknownStatement.details = Unknown statement in QcStatement extension: OID = {0}, statement = {1}
-
-# QcLimitValue Alpha currency code
-# {0} currency code
-# {1} limit value
-# {2} monetary value as MonetaryValue
-CertPathReviewer.QcLimitValueAlpha.title = Transaction Value Limit
-CertPathReviewer.QcLimitValueAlpha.text = This certificate has a limit for the transaction value: {1,number,currency} {0}.
-CertPathReviewer.QcLimitValueAlpha.summary = Transaction value limit: {1,number,currency} {0}.
-CertPathReviewer.QcLimitValueAlpha.details = This certificate has a limitation on the value of transaction for which this certificate can be used to the specified amount, according to the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. The limit for this certificate is {1,number,currency} {0}.
-
-# QcLimitValue Numeric currency code
-# {0} currency code
-# {1} limit value
-# {2} monetary value as MonetaryValue
-CertPathReviewer.QcLimitValueNum.title = Transaction Value Limit
-CertPathReviewer.QcLimitValueNum.text = This certificate has a limit for the transaction value: {1,number,currency} of currency {0} (See RFC 4217 for currency codes).
-CertPathReviewer.QcLimitValueNum.summary = Transaction value limit: {1,number,currency} of currency {0} (See RFC 4217 for currency codes).
-CertPathReviewer.QcLimitValueNum.details = This certificate has a limitation on the value of transaction for which this certificate can be used to the specified amount, according to the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. The limit for this certificate is {1,number,currency} of currency {0} (See RFC 4217 for currency codes).
-
-# QcSSCD
-CertPathReviewer.QcSSCD.title = QcSSCD Statement
-CertPathReviewer.QcSSCD.text = The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures.
-CertPathReviewer.QcSSCD.summary = The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures.
-CertPathReviewer.QcSSCD.details = The issuer claims that for the certificate where this statement appears that the private key associated with the public key in the certificate is protected according to Annex III of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures.
-
-# QcEuCompliance
-CertPathReviewer.QcEuCompliance.title = Qualified Certificate
-CertPathReviewer.QcEuCompliance.text = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate.
-CertPathReviewer.QcEuCompliance.summary = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate.
-CertPathReviewer.QcEuCompliance.details = This certificate is issued as a Qualified Certificate according Annex I and II of the Directive 1999/93/EC of the European Parliament and of the Council of 13 December 1999 on a Community framework for electronic signatures, as implemented in the law of the country specified in the issuer field of this certificate. 
-
-## QcStatement errors
-
-# error processing the QcStatement extension
-CertPathReviewer.QcStatementExtError.title = Error processing the qc statements extension
-CertPathReviewer.QcStatementExtError.text = Error processing the qc statements extension.
-CertPathReviewer.QcStatementExtError.summary = Error processing the qc statements extension.
-CertPathReviewer.QcStatementExtError.details = Error processing the qc statements extension.
-
diff --git a/security/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java b/security/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java
index 50037db..cc00697 100644
--- a/security/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java
+++ b/security/src/main/java/org/bouncycastle/x509/PKIXCertPathReviewer.java
@@ -662,7 +662,7 @@
         }
 
         ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.totalPathLength",
-                new Object[] {new Integer(totalPathLength)});
+                new Object[] {Integer.valueOf(totalPathLength)});
         
         addNotification(msg);
     }
@@ -697,7 +697,7 @@
                 // conflicting trust anchors                
                 ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,
                         "CertPathReviewer.conflictingTrustAnchors",
-                        new Object[] {new Integer(trustColl.size()),
+                        new Object[] {Integer.valueOf(trustColl.size()),
                                       new UntrustedInput(cert.getIssuerX500Principal())});
                 addError(msg);
             }
@@ -706,7 +706,7 @@
                 ErrorBundle msg = new ErrorBundle(RESOURCE_NAME,
                         "CertPathReviewer.noTrustAnchorFound",
                         new Object[] {new UntrustedInput(cert.getIssuerX500Principal()),
-                                      new Integer(pkixParams.getTrustAnchors().size())});
+                                Integer.valueOf(pkixParams.getTrustAnchors().size())});
                 addError(msg);
             }
             else
@@ -1883,7 +1883,7 @@
                     else
                     {
                         msg = new ErrorBundle(RESOURCE_NAME,"CertPathReviewer.QcLimitValueNum",
-                                new Object[] {new Integer(limit.getCurrency().getNumeric()),
+                                new Object[] {Integer.valueOf(limit.getCurrency().getNumeric()),
                                               new Double(value),
                                               limit});
                     }
@@ -1978,7 +1978,7 @@
                         "CertPathReviewer.noCrlInCertstore",
                         new Object[] {new UntrustedInput(crlselect.getIssuers()),
                                       new UntrustedInput(nonMatchingCrlNames),
-                                      new Integer(numbOfCrls)});
+                                      Integer.valueOf(numbOfCrls)});
                 addNotification(msg,index);
             }
 
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/AccessControlExceptionTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/AccessControlExceptionTest.java
index a2008de..9825291 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/AccessControlExceptionTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/AccessControlExceptionTest.java
@@ -41,14 +41,6 @@
 public class AccessControlExceptionTest extends TestCase {
 
     /**
-     * Entry point for standalone run.
-     * @param args command line arguments
-     */
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AccessControlExceptionTest.class);
-    }
-
-    /**
      * Tests AccessControlException(String)
      */
     @TestTargetNew(
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java
index 1ff236a..69c994d 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParameterGenerator1Test.java
@@ -478,10 +478,6 @@
         } catch (NullPointerException e) {
         }
     }
-
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(AlgorithmParameterGenerator1Test.class);
-    }
 }
 /**
  * Additional class to verify AlgorithmParameterGenerator constructor
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java
index 5ec3d96..f65cc80 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersSpiTest.java
@@ -126,9 +126,5 @@
         }
     }
     
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(AlgorithmParametersSpiTest.class);
-    }
-    
     class MyAlgorithmParameterSpec implements AlgorithmParameterSpec {}
 }
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java
index 089a7db..c0d5640 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.security.tests.java.security;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.security.tests.java.security;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AccessControlException2Test.class);
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
index e29d9ac..f94cb27 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSignerTest.java
@@ -41,15 +41,6 @@
  */
 
 public class CodeSignerTest extends TestCase {
-
-    /**
-     * Entry point for standalone runs.
-     * @param args command line arguments
-     */
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(CodeSignerTest.class);
-    }
-
     private CertPath cpath = TestCertUtils.genCertPath(3, 0);
     private Date now = new Date();
 
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java
index 276dfd7..eeef8ac 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/CodeSourceTest.java
@@ -47,16 +47,6 @@
  */
 
 public class CodeSourceTest extends TestCase {
-    /**
-     * 
-     * Entry point for standalone runs.
-     *
-     * @param args command line arguments
-     */
-    public static void main(String[] args) throws Exception {
-        junit.textui.TestRunner.run(CodeSourceTest.class);
-    }
-
     private java.security.cert.Certificate[] chain = null;
 
     /* Below are various URLs used during the testing */
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/GuardedObjectTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/GuardedObjectTest.java
index a1b0365..e717747 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/GuardedObjectTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/GuardedObjectTest.java
@@ -39,10 +39,6 @@
 
 public class GuardedObjectTest extends TestCase {
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(GuardedObjectTest.class);
-    }
-
     /** Null guard imposes no restriction. */
     @TestTargets({
         @TestTargetNew(
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java
index 5b1ea7f..c11f90a 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/IdentityScopeTest.java
@@ -51,10 +51,6 @@
         }
     }
     
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(IdentityScopeTest.class);
-    }
-    
     IdentityScope is;
 
     /**
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java
index dc7880f..0cb1400 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KSPrivateKeyEntryTest.java
@@ -231,10 +231,6 @@
         return new TestSuite(KSPrivateKeyEntryTest.class);
     }
 
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(suite());
-    }
-
     private static class tmpPrivateKey implements PrivateKey {
         private String alg = "My algorithm";
 
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java
index 742cc13..efa9bf0 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator1Test.java
@@ -650,8 +650,4 @@
             fail("Unexpected InvalidAlgorithmParameterException was thrown");
         }
     }
-
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(KeyPairGenerator1Test.class);
-    }
 }
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java
index 9a8c5c5..5fe110c 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator2Test.java
@@ -505,7 +505,4 @@
         setProv();
         GetInstance03(4);
     }
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(KeyPairGenerator2Test.class);
-    }
 }
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java
index 69ec7a7..24867e7 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGenerator3Test.java
@@ -191,10 +191,6 @@
         }
     }
 
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(KeyPairGenerator3Test.class);
-    }
-    
     /**
      * Additional class to verify KeyPairGenerator constructor
      */
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java
index 8d75921..689e6ce 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyPairGeneratorSpiTest.java
@@ -104,9 +104,6 @@
         KeyPair kp = keyPairGen.generateKeyPair();
         assertNull("Not null KeyPair", kp);
     }
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(KeyPairGeneratorSpiTest.class);
-    }
     
     class MyAlgorithmParameterSpec implements AlgorithmParameterSpec {}
 
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
index 2ccca0e..9f25a7b 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
@@ -424,12 +424,6 @@
         } catch (UnsupportedOperationException e) {
         }
     }
-    
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(KeyStoreSpiTest.class);
-    }
-    
-    
 }
 
 /**
@@ -487,4 +481,4 @@
             }
         };
     }
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java
index 13d4d62..f1a3cf3 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionTest.java
@@ -36,11 +36,6 @@
  */
 
 public class PermissionTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(PermissionTest.class);
-    }
-
     // Bare extension to instantiate abstract Permission class
     static final class RealPermission extends Permission {
 
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionsTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionsTest.java
index 5680e2e..99d39f3 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionsTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/PermissionsTest.java
@@ -49,11 +49,6 @@
  */
 
 public class PermissionsTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(PermissionsTest.class);
-    }
-
     /**
      * Can add any type of permissions. Cannot add if collection is read-only.
      */
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java
index ce57328..1f64d34 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/PolicyTest.java
@@ -57,10 +57,6 @@
 
     public static final String JAVA_SECURITY_POLICY = "java.security.policy";
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(PolicyTest.class);
-    }
-
     @Override protected void tearDown() throws Exception {
         TestEnvironment.reset();
         super.tearDown();
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivilegedActionExceptionTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivilegedActionExceptionTest.java
index 99fce26..f1e1b42 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivilegedActionExceptionTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/PrivilegedActionExceptionTest.java
@@ -38,14 +38,6 @@
 
 public class PrivilegedActionExceptionTest extends TestCase {
     /**
-     * Entry point for standalone runs.
-     * @param args command line arguments
-     */
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(PrivilegedActionExceptionTest.class);
-    }
-
-    /**
      * Tests PrivilegedActionException(Exception)
      */
     @TestTargetNew(
@@ -89,4 +81,4 @@
         assertNotNull(new PrivilegedActionException(new Exception()).toString());
     }
 
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProtectionDomainTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProtectionDomainTest.java
index 451cad4..7397a08 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProtectionDomainTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProtectionDomainTest.java
@@ -48,14 +48,6 @@
 
 public class ProtectionDomainTest extends TestCase {
 
-    /**
-     * Entry point for standalone runs.
-     * @param args command line arguments
-     */
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(ProtectionDomainTest.class);
-    }
-
     private final AllPermission allperm = new AllPermission();
 
     private URL url = null;
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
index 3cc447f..885d0e5 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/ProviderTest.java
@@ -706,7 +706,7 @@
         assertEquals("1.0", myProvider.get("Provider.id version"));
 
         try {
-            myProvider.load(null);
+            myProvider.load((InputStream) null);
             fail("NullPointerException expected");
         } catch (NullPointerException e) {
             // expected
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java
index 2531c81..fcda610 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/SecurityPermissionTest.java
@@ -36,11 +36,6 @@
  * 
  */
 public class SecurityPermissionTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(SecurityPermissionTest.class);
-    }
-
     /**
      * Check all constructors: an object is created with the specified valid name. 
      * If name equal null then NPE should be thrown. 
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java
index 898ab17..267221c 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/SignerTest.java
@@ -57,10 +57,6 @@
             if (denied!=null && denied.implies(permission)) throw new SecurityException();
         }
     }    
-    
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(SignerTest.class);
-    }
 
     /**
      * @tests java.security.Signer#toString()
diff --git a/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java b/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java
index 1015521..f965337 100644
--- a/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java
+++ b/security/src/test/java/org/apache/harmony/security/tests/java/security/TimestampTest.java
@@ -41,11 +41,6 @@
  */
 
 public class TimestampTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(TimestampTest.class);
-    }
-
     private Date now = new Date();
 
     private static final byte[] encoding = { 1, 2, 3 };
diff --git a/security/src/test/java/org/bouncycastle/jce/provider/AllTests.java b/security/src/test/java/org/bouncycastle/jce/provider/AllTests.java
index e9fbdb0..f9bf52f 100644
--- a/security/src/test/java/org/bouncycastle/jce/provider/AllTests.java
+++ b/security/src/test/java/org/bouncycastle/jce/provider/AllTests.java
@@ -20,14 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "All tests for " + AllTests.class.getPackage());
+        TestSuite suite = new TestSuite("All tests for " + AllTests.class.getPackage());
         suite.addTestSuite(PKIXCertPathValidatorSpiTest.class);
         return suite;
     }
diff --git a/security/src/test/java/tests/api/java/security/AllTests.java b/security/src/test/java/tests/api/java/security/AllTests.java
index 679f860..7f83780 100644
--- a/security/src/test/java/tests/api/java/security/AllTests.java
+++ b/security/src/test/java/tests/api/java/security/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.java.security;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.java.security;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AccessControlContextTest.class);
diff --git a/security/src/test/java/tests/api/javax/security/auth/AllTests.java b/security/src/test/java/tests/api/javax/security/auth/AllTests.java
index b5b7f18..bd4ae74 100644
--- a/security/src/test/java/tests/api/javax/security/auth/AllTests.java
+++ b/security/src/test/java/tests/api/javax/security/auth/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.javax.security.auth;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.javax.security.auth;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AuthPermissionTest.class);
diff --git a/security/src/test/java/tests/api/javax/security/cert/AllTests.java b/security/src/test/java/tests/api/javax/security/cert/AllTests.java
index 4516bc1..30921bd 100644
--- a/security/src/test/java/tests/api/javax/security/cert/AllTests.java
+++ b/security/src/test/java/tests/api/javax/security/cert/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.javax.security.cert;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.javax.security.cert;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(CertificateEncodingExceptionTest.class);
diff --git a/security/src/test/java/tests/api/javax/security/cert/CertificateTest.java b/security/src/test/java/tests/api/javax/security/cert/CertificateTest.java
index c4d10f6..38afce6 100644
--- a/security/src/test/java/tests/api/javax/security/cert/CertificateTest.java
+++ b/security/src/test/java/tests/api/javax/security/cert/CertificateTest.java
@@ -191,8 +191,4 @@
     public static Test suite() {
         return new TestSuite(CertificateTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
diff --git a/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java b/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
index 4af8dc8..79b7b00 100644
--- a/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
+++ b/security/src/test/java/tests/api/javax/security/cert/X509CertificateTest.java
@@ -904,8 +904,4 @@
     public static Test suite() {
         return new TestSuite(X509CertificateTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
diff --git a/security/src/test/java/tests/java/security/AllPermissionTest.java b/security/src/test/java/tests/java/security/AllPermissionTest.java
index e9668ad..2db54b0 100644
--- a/security/src/test/java/tests/java/security/AllPermissionTest.java
+++ b/security/src/test/java/tests/java/security/AllPermissionTest.java
@@ -40,10 +40,6 @@
  */
 public class AllPermissionTest extends TestCase {
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllPermissionTest.class);
-    }
-
     /**
      * Test all constructors: an object is created, name and actions are ignored
      */
diff --git a/security/src/test/java/tests/java/security/AllTests.java b/security/src/test/java/tests/java/security/AllTests.java
index 61396df..6dadd07 100644
--- a/security/src/test/java/tests/java/security/AllTests.java
+++ b/security/src/test/java/tests/java/security/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.java.security;");
+        TestSuite suite = new TestSuite("All tests for package tests.java.security;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AlgorithmParameterGeneratorSpiTest.class);
diff --git a/security/src/test/java/tests/java/security/BasicPermissionTest.java b/security/src/test/java/tests/java/security/BasicPermissionTest.java
index 4987ab4..75661ae 100644
--- a/security/src/test/java/tests/java/security/BasicPermissionTest.java
+++ b/security/src/test/java/tests/java/security/BasicPermissionTest.java
@@ -38,11 +38,6 @@
  */
 @TestTargetClass(BasicPermission.class)
 public class BasicPermissionTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(BasicPermissionTest.class);
-    }
-
     /**
      * Check all constructors: an object is created with the specified valid name. 
      * If name equal null then NPE should be thrown. 
diff --git a/security/src/test/java/tests/java/security/IdentityTest.java b/security/src/test/java/tests/java/security/IdentityTest.java
index 3566ecf..470936e 100644
--- a/security/src/test/java/tests/java/security/IdentityTest.java
+++ b/security/src/test/java/tests/java/security/IdentityTest.java
@@ -56,10 +56,6 @@
         }
     }
     
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(IdentityTest.class);
-    }
-
     @TestTargetNew(
         level = TestLevel.PARTIAL,
         notes = "Method's returned variable is not checked",
diff --git a/security/src/test/java/tests/java/security/SecureClassLoaderTest.java b/security/src/test/java/tests/java/security/SecureClassLoaderTest.java
index 1dfaae6..6ce1659 100644
--- a/security/src/test/java/tests/java/security/SecureClassLoaderTest.java
+++ b/security/src/test/java/tests/java/security/SecureClassLoaderTest.java
@@ -64,16 +64,6 @@
 
 public class SecureClassLoaderTest extends TestCase {
     /**
-     * Entry point for stand alone runs.
-     * 
-     * @param args
-     *            command line parameters
-     */
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(SecureClassLoaderTest.class);
-    }
-
-    /**
      * A class name for the class presented as {@link #klassData bytecode below}
      */
     private static final String klassName = "HiWorld";
diff --git a/security/src/test/java/tests/security/AllTests.java b/security/src/test/java/tests/security/AllTests.java
index a88cc0e..7a790c9 100644
--- a/security/src/test/java/tests/security/AllTests.java
+++ b/security/src/test/java/tests/security/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the security project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All security test suites");
+        TestSuite suite = new TestSuite("All security test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.security.tests.java.security.AllTests.suite());
         suite.addTest(org.bouncycastle.jce.provider.AllTests.suite());
diff --git a/security/src/test/java/tests/security/acl/AclNotFoundExceptionTest.java b/security/src/test/java/tests/security/acl/AclNotFoundExceptionTest.java
index cfd0bb0..cbee130 100644
--- a/security/src/test/java/tests/security/acl/AclNotFoundExceptionTest.java
+++ b/security/src/test/java/tests/security/acl/AclNotFoundExceptionTest.java
@@ -37,11 +37,6 @@
  */
 @TestTargetClass(AclNotFoundException.class)
 public class AclNotFoundExceptionTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AclNotFoundExceptionTest.class);
-    }
-
     /**
      * check default constructor 
      */  
diff --git a/security/src/test/java/tests/security/acl/AllTests.java b/security/src/test/java/tests/security/acl/AllTests.java
index 4b93980..9a6f2b4 100644
--- a/security/src/test/java/tests/security/acl/AllTests.java
+++ b/security/src/test/java/tests/security/acl/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.java.security.acl;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.java.security.acl;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AclNotFoundException2Test.class);
diff --git a/security/src/test/java/tests/security/acl/LastOwnerExceptionTest.java b/security/src/test/java/tests/security/acl/LastOwnerExceptionTest.java
index b76f456..3cd14ff 100644
--- a/security/src/test/java/tests/security/acl/LastOwnerExceptionTest.java
+++ b/security/src/test/java/tests/security/acl/LastOwnerExceptionTest.java
@@ -22,11 +22,6 @@
 
 package tests.security.acl;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 import java.security.acl.LastOwnerException;
@@ -35,18 +30,7 @@
  * Unit test for LastOwnerException.
  * 
  */
-@TestTargetClass(LastOwnerException.class)
 public class LastOwnerExceptionTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(LastOwnerExceptionTest.class);
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "LastOwnerException",
-        args = {}
-    )
     public void testLastOwnerException() {
         assertNotNull(new LastOwnerException());
         assertNull(new LastOwnerException().getMessage());
diff --git a/security/src/test/java/tests/security/acl/NotOwnerExceptionTest.java b/security/src/test/java/tests/security/acl/NotOwnerExceptionTest.java
index c3dfe34..67ef38b 100644
--- a/security/src/test/java/tests/security/acl/NotOwnerExceptionTest.java
+++ b/security/src/test/java/tests/security/acl/NotOwnerExceptionTest.java
@@ -22,11 +22,6 @@
 
 package tests.security.acl;
 
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
 import junit.framework.TestCase;
 
 import java.security.acl.NotOwnerException;
@@ -35,18 +30,7 @@
  * Unit test for NotOwnerException.
  * 
  */
-@TestTargetClass(NotOwnerException.class)
 public class NotOwnerExceptionTest extends TestCase {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(NotOwnerExceptionTest.class);
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "NotOwnerException",
-        args = {}
-    )
     public void testNotOwnerException() {
         assertNotNull(new NotOwnerException());
         assertNull(new NotOwnerException().getMessage());
diff --git a/security/src/test/java/tests/security/cert/AllTests.java b/security/src/test/java/tests/security/cert/AllTests.java
index 749a5ab..e5b9d47 100644
--- a/security/src/test/java/tests/security/cert/AllTests.java
+++ b/security/src/test/java/tests/security/cert/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.java.security.cert;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.java.security.cert;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(CRLExceptionTest.class);
diff --git a/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java b/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java
index 1c45e57..d472bc4 100644
--- a/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java
+++ b/security/src/test/java/tests/security/cert/CertPathBuilder1Test.java
@@ -522,11 +522,6 @@
         }
 
     }
-
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(CertPathBuilder1Test.class);
-    }  
-    
 }
 /**
  * Additional class to verify CertPathBuilder constructor
diff --git a/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java b/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java
index fcf235e..af9de90 100644
--- a/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java
+++ b/security/src/test/java/tests/security/cert/CertPathBuilder2Test.java
@@ -265,9 +265,4 @@
             checkResult(cerPB);
         }
     }
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(CertPathBuilder2Test.class);
-    }  
-    
-
 }
diff --git a/security/src/test/java/tests/security/cert/CertPathValidator1Test.java b/security/src/test/java/tests/security/cert/CertPathValidator1Test.java
index a76af78..101644d 100644
--- a/security/src/test/java/tests/security/cert/CertPathValidator1Test.java
+++ b/security/src/test/java/tests/security/cert/CertPathValidator1Test.java
@@ -526,10 +526,6 @@
                     defaultProvider);
         }
     }
-
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(CertPathValidator1Test.class);
-    }  
 }
 /**
  * Additional class to verify CertPathValidator constructor
diff --git a/security/src/test/java/tests/security/cert/CertStoreSpiTest.java b/security/src/test/java/tests/security/cert/CertStoreSpiTest.java
index 3cac01f..4760871 100644
--- a/security/src/test/java/tests/security/cert/CertStoreSpiTest.java
+++ b/security/src/test/java/tests/security/cert/CertStoreSpiTest.java
@@ -97,10 +97,6 @@
         return new TestSuite(CertStoreSpiTest.class);
     }
 
-    public static void main(String args[]) {
-        junit.textui.TestRunner.run(suite());
-    }
-    
     /** 
      * Additional classes for verification CertStoreSpi class
      */
diff --git a/security/src/test/java/tests/security/cert/CertificateFactory1Test.java b/security/src/test/java/tests/security/cert/CertificateFactory1Test.java
index 42677eb..04112a2 100644
--- a/security/src/test/java/tests/security/cert/CertificateFactory1Test.java
+++ b/security/src/test/java/tests/security/cert/CertificateFactory1Test.java
@@ -887,10 +887,6 @@
             fail("Unexpected exception" + e);
         }
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(CertificateFactory1Test.class);
-    }
 }
 /**
  * Additional class to verify CertificateFactory constructor
diff --git a/security/src/test/java/tests/security/cert/X509CRLEntryTest.java b/security/src/test/java/tests/security/cert/X509CRLEntryTest.java
index 1eec127..3f82f67 100644
--- a/security/src/test/java/tests/security/cert/X509CRLEntryTest.java
+++ b/security/src/test/java/tests/security/cert/X509CRLEntryTest.java
@@ -266,9 +266,5 @@
     public static Test suite() {
         return new TestSuite(X509CRLEntryTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/security/src/test/java/tests/security/cert/X509CRLTest.java b/security/src/test/java/tests/security/cert/X509CRLTest.java
index c10494e..4dd98cb 100644
--- a/security/src/test/java/tests/security/cert/X509CRLTest.java
+++ b/security/src/test/java/tests/security/cert/X509CRLTest.java
@@ -457,9 +457,5 @@
     public static Test suite() {
         return new TestSuite(X509CRLTest.class);
     }
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(suite());
-    }
 }
 
diff --git a/security/src/test/java/tests/security/interfaces/AllTests.java b/security/src/test/java/tests/security/interfaces/AllTests.java
index e665119..e180408 100644
--- a/security/src/test/java/tests/security/interfaces/AllTests.java
+++ b/security/src/test/java/tests/security/interfaces/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.security.interfaces;");
+        TestSuite suite = new TestSuite("All tests for package tests.security.interfaces;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(DSAKeyTest.class);
diff --git a/security/src/test/java/tests/security/permissions/JavaIoFileTest.java b/security/src/test/java/tests/security/permissions/JavaIoFileTest.java
index 207bfc0..7bc6933 100644
--- a/security/src/test/java/tests/security/permissions/JavaIoFileTest.java
+++ b/security/src/test/java/tests/security/permissions/JavaIoFileTest.java
@@ -22,7 +22,6 @@
 import java.io.IOException;
 import java.security.Permission;
 
-import dalvik.annotation.KnownFailure;
 import junit.framework.TestCase;
 import dalvik.annotation.TestLevel;
 import dalvik.annotation.TestTargetClass;
@@ -432,7 +431,6 @@
             args = {}
         )
     })
-    @KnownFailure("We need to finish cleaning up java.io.File (bug 2281992)")
     public void test_File4() throws IOException {
         class TestSecurityManager extends SecurityManager {
             boolean checkPropertyAccessCalled;
@@ -489,7 +487,6 @@
             args = {}
         )
     })
-    @KnownFailure("We need to finish cleaning up java.io.File (bug 2281992)")
     public void test_File5() throws IOException {
         class TestSecurityManager extends SecurityManager {
             boolean checkPropertyAccessCalled;
diff --git a/security/src/test/java/tests/security/spec/AllTests.java b/security/src/test/java/tests/security/spec/AllTests.java
index f643618..151e0a7 100644
--- a/security/src/test/java/tests/security/spec/AllTests.java
+++ b/security/src/test/java/tests/security/spec/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.security.spec;");
+        TestSuite suite = new TestSuite("All tests for package tests.security.spec;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(DSAParameterSpecTest.class);
diff --git a/security/src/test/java/tests/targets/security/AllTests.java b/security/src/test/java/tests/targets/security/AllTests.java
index 6bd6d05..7d5802d 100644
--- a/security/src/test/java/tests/targets/security/AllTests.java
+++ b/security/src/test/java/tests/targets/security/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.targets.security;");
+        TestSuite suite = new TestSuite("All tests for package tests.targets.security;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(MessageDigestTestMD2.class);
@@ -75,4 +70,4 @@
         // $JUnit-END$
         return suite;
     }
-}
\ No newline at end of file
+}
diff --git a/security/src/test/java/tests/targets/security/cert/AllTests.java b/security/src/test/java/tests/targets/security/cert/AllTests.java
index 50292e2..c0c411d 100644
--- a/security/src/test/java/tests/targets/security/cert/AllTests.java
+++ b/security/src/test/java/tests/targets/security/cert/AllTests.java
@@ -19,13 +19,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.targets.security.certs;");
+        TestSuite suite = new TestSuite("All tests for package tests.targets.security.certs;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(CertificateTest.class);
@@ -36,4 +31,4 @@
         // $JUnit-END$
         return suite;
     }
-}
\ No newline at end of file
+}
diff --git a/sql/src/main/java/SQLite/Constants.java b/sql/src/main/java/SQLite/Constants.java
deleted file mode 100644
index 4e636b9..0000000
--- a/sql/src/main/java/SQLite/Constants.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/* DO NOT EDIT */
-
-package SQLite;
-
-/**
- * Container for SQLite constants.
- */
-
-public final class Constants {
-    /*
-     * Error code: 0
-     */
-    public static final int SQLITE_OK = 0;
-    /*
-     * Error code: 1
-     */
-    public static final int SQLITE_ERROR = 1;
-    /*
-     * Error code: 2
-     */
-    public static final int SQLITE_INTERNAL = 2;
-    /*
-     * Error code: 3
-     */
-    public static final int SQLITE_PERM = 3;
-    /*
-     * Error code: 4
-     */
-    public static final int SQLITE_ABORT = 4;
-    /*
-     * Error code: 5
-     */
-    public static final int SQLITE_BUSY = 5;
-    /*
-     * Error code: 6
-     */
-    public static final int SQLITE_LOCKED = 6;
-    /*
-     * Error code: 7
-     */
-    public static final int SQLITE_NOMEM = 7;
-    /*
-     * Error code: 8
-     */
-    public static final int SQLITE_READONLY = 8;
-    /*
-     * Error code: 9
-     */
-    public static final int SQLITE_INTERRUPT = 9;
-    /*
-     * Error code: 10
-     */
-    public static final int SQLITE_IOERR = 10;
-    /*
-     * Error code: 11
-     */
-    public static final int SQLITE_CORRUPT = 11;
-    /*
-     * Error code: 12
-     */
-    public static final int SQLITE_NOTFOUND = 12;
-    /*
-     * Error code: 13
-     */
-    public static final int SQLITE_FULL = 13;
-    /*
-     * Error code: 14
-     */
-    public static final int SQLITE_CANTOPEN = 14;
-    /*
-     * Error code: 15
-     */
-    public static final int SQLITE_PROTOCOL = 15;
-    /*
-     * Error code: 16
-     */
-    public static final int SQLITE_EMPTY = 16;
-    /*
-     * Error code: 17
-     */
-    public static final int SQLITE_SCHEMA = 17;
-    /*
-     * Error code: 18
-     */
-    public static final int SQLITE_TOOBIG = 18;
-    /*
-     * Error code: 19
-     */
-    public static final int SQLITE_CONSTRAINT = 19;
-    /*
-     * Error code: 20
-     */
-    public static final int SQLITE_MISMATCH = 20;
-    /*
-     * Error code: 21
-     */
-    public static final int SQLITE_MISUSE = 21;
-    /*
-     * Error code: 22
-     */
-    public static final int SQLITE_NOLFS = 22;
-    /*
-     * Error code: 23
-     */
-    public static final int SQLITE_AUTH = 23;
-    /*
-     * Error code: 24
-     */
-    public static final int SQLITE_FORMAT = 24;
-    /*
-     * Error code: 25
-     */
-    public static final int SQLITE_RANGE = 25;
-    /*
-     * Error code: 26
-     */
-    public static final int SQLITE_NOTADB = 26;
-    public static final int SQLITE_ROW = 100;
-    public static final int SQLITE_DONE = 101;
-    public static final int SQLITE_INTEGER = 1;
-    public static final int SQLITE_FLOAT = 2;
-    public static final int SQLITE_BLOB = 4;
-    public static final int SQLITE_NULL = 5;
-    public static final int SQLITE3_TEXT = 3;
-    public static final int SQLITE_NUMERIC = -1;
-    public static final int SQLITE_TEXT = 3;
-    public static final int SQLITE2_TEXT = -2;
-    public static final int SQLITE_ARGS = -3;
-    public static final int SQLITE_COPY = 0;
-    public static final int SQLITE_CREATE_INDEX = 1;
-    public static final int SQLITE_CREATE_TABLE = 2;
-    public static final int SQLITE_CREATE_TEMP_INDEX = 3;
-    public static final int SQLITE_CREATE_TEMP_TABLE = 4;
-    public static final int SQLITE_CREATE_TEMP_TRIGGER = 5;
-    public static final int SQLITE_CREATE_TEMP_VIEW = 6;
-    public static final int SQLITE_CREATE_TRIGGER = 7;
-    public static final int SQLITE_CREATE_VIEW = 8;
-    public static final int SQLITE_DELETE = 9;
-    public static final int SQLITE_DROP_INDEX = 10;
-    public static final int SQLITE_DROP_TABLE = 11;
-    public static final int SQLITE_DROP_TEMP_INDEX = 12;
-    public static final int SQLITE_DROP_TEMP_TABLE = 13;
-    public static final int SQLITE_DROP_TEMP_TRIGGER = 14;
-    public static final int SQLITE_DROP_TEMP_VIEW = 15;
-    public static final int SQLITE_DROP_TRIGGER = 16;
-    public static final int SQLITE_DROP_VIEW = 17;
-    public static final int SQLITE_INSERT = 18;
-    public static final int SQLITE_PRAGMA = 19;
-    public static final int SQLITE_READ = 20;
-    public static final int SQLITE_SELECT = 21;
-    public static final int SQLITE_TRANSACTION = 22;
-    public static final int SQLITE_UPDATE = 23;
-    public static final int SQLITE_ATTACH = 24;
-    public static final int SQLITE_DETACH = 25;
-    public static final int SQLITE_DENY = 1;
-    public static final int SQLITE_IGNORE = 2;
-}
diff --git a/sql/src/main/java/SQLite/Database.java b/sql/src/main/java/SQLite/Database.java
deleted file mode 100644
index dcaaf9d..0000000
--- a/sql/src/main/java/SQLite/Database.java
+++ /dev/null
@@ -1,615 +0,0 @@
-package SQLite;
-
-/**
- * Main class wrapping an SQLite database.
- */
-
-public class Database {
-
-    /**
-     * Internal handle for the native SQLite API.
-     */
-
-    protected long handle = 0;
-
-    /**
-     * Internal last error code for exec() methods.
-     */
-
-    protected int error_code = 0;
-
-    /**
-     * Open an SQLite database file.
-     *
-     * @param filename the name of the database file
-     * @param mode open mode, currently ignored
-     */
-
-    public void open(String filename, int mode) throws SQLite.Exception {
-    synchronized(this) {
-        _open(filename, mode);
-    }
-    }
-
-    private native void _open(String filename, int mode)
-    throws SQLite.Exception;
-
-    /**
-     * Open SQLite auxiliary database file for temporary
-     * tables.
-     *
-     * @param filename the name of the auxiliary file or null
-     */
-
-    public void open_aux_file(String filename) throws SQLite.Exception {
-    synchronized(this) {
-        _open_aux_file(filename);
-    }
-    }
-
-    private native void _open_aux_file(String filename)
-    throws SQLite.Exception;
-
-    /**
-     * Destructor for object.
-     */
-
-    protected void finalize() {
-    synchronized(this) {
-        _finalize();
-    }
-    }
-
-    private native void _finalize();
-
-    /**
-     * Close the underlying SQLite database file.
-     */
-
-    public void close()    throws SQLite.Exception {
-    synchronized(this) {
-        _close();
-    }
-    }
-
-    private native void _close()
-    throws SQLite.Exception;
-
-    /**
-     * Execute an SQL statement and invoke callback methods
-     * for each row of the result set.<P>
-     *
-     * It the method fails, an SQLite.Exception is thrown and
-     * an error code is set, which later can be retrieved by
-     * the last_error() method.
-     *
-     * @param sql the SQL statement to be executed
-     * @param cb the object implementing the callback methods
-     */
-
-    public void exec(String sql, SQLite.Callback cb) throws SQLite.Exception {
-    synchronized(this) {
-        _exec(sql, cb);
-    }
-    }
-
-    private native void _exec(String sql, SQLite.Callback cb)
-    throws SQLite.Exception;
-
-    /**
-     * Execute an SQL statement and invoke callback methods
-     * for each row of the result set. Each '%q' or %Q in the
-     * statement string is substituted by its corresponding
-     * element in the argument vector.
-     * <BR><BR>
-     * Example:<BR>
-     * <PRE>
-     *   String args[] = new String[1];
-     *   args[0] = "tab%";
-     *   db.exec("select * from sqlite_master where type like '%q'",
-     *           null, args);
-     * </PRE>
-     *
-     * It the method fails, an SQLite.Exception is thrown and
-     * an error code is set, which later can be retrieved by
-     * the last_error() method.
-     *
-     * @param sql the SQL statement to be executed
-     * @param cb the object implementing the callback methods
-     * @param args arguments for the SQL statement, '%q' substitution
-     */
-
-    public void exec(String sql, SQLite.Callback cb,
-             String args[]) throws SQLite.Exception {
-    synchronized(this) {
-        _exec(sql, cb, args);
-    }
-    }
-
-    private native void _exec(String sql, SQLite.Callback cb, String args[])
-    throws SQLite.Exception;
-
-    /**
-     * Return the row identifier of the last inserted
-     * row.
-     */
-
-    public long last_insert_rowid() {
-    synchronized(this) {
-        return _last_insert_rowid();
-    }
-    }
-
-    private native long _last_insert_rowid();
-
-    /**
-     * Abort the current SQLite operation.
-     */
-
-    public void interrupt() {
-    synchronized(this) {
-        _interrupt();
-    }
-    }
-
-    private native void _interrupt();
-
-    /**
-     * Return the number of changed rows for the last statement.
-     */
-
-    public long changes() {
-    synchronized(this) {
-        return _changes();
-    }
-    }
-
-    private native long _changes();
-
-    /**
-     * Establish a busy callback method which gets called when
-     * an SQLite table is locked.
-     *
-     * @param bh the object implementing the busy callback method
-     */
-
-    public void busy_handler(SQLite.BusyHandler bh) {
-    synchronized(this) {
-        _busy_handler(bh);
-    }
-    }
-
-    private native void _busy_handler(SQLite.BusyHandler bh);
-
-    /**
-     * Set the timeout for waiting for an SQLite table to become
-     * unlocked.
-     *
-     * @param ms number of millisecond to wait
-     */
-
-    public void busy_timeout(int ms) {
-    synchronized(this) {
-        _busy_timeout(ms);
-    }
-    }
-
-    private native void _busy_timeout(int ms);
-
-    /**
-     * Convenience method to retrieve an entire result
-     * set into memory.
-     *
-     * @param sql the SQL statement to be executed
-     * @return result set
-     */
-
-    public TableResult get_table(String sql) throws SQLite.Exception {
-    TableResult ret = new TableResult();
-    if (!is3()) {
-        exec(sql, ret);
-    } else {
-        synchronized(this) {
-        /* only one statement !!! */
-        Vm vm = compile(sql);
-        set_last_error(vm.error_code);
-        while (vm.step(ret)) {
-            set_last_error(vm.error_code);
-        }
-        vm.finalize();
-        }
-    }
-    return ret;
-    }
-
-    /**
-     * Convenience method to retrieve an entire result
-     * set into memory.
-     *
-     * @param sql the SQL statement to be executed
-     * @param args arguments for the SQL statement, '%q' substitution
-     * @return result set
-     */
-
-    public TableResult get_table(String sql, String args[])
-    throws SQLite.Exception {
-    TableResult ret = new TableResult();
-    if (!is3()) {
-        exec(sql, ret, args);
-    } else {
-        synchronized(this) {
-        /* only one statement !!! */
-        Vm vm = compile(sql, args);
-        set_last_error(vm.error_code);
-        while (vm.step(ret)) {
-            set_last_error(vm.error_code);
-        }
-        vm.finalize();
-        }
-    }
-    return ret;
-    }
-
-    /**
-     * Convenience method to retrieve an entire result
-     * set into memory.
-     *
-     * @param sql the SQL statement to be executed
-     * @param args arguments for the SQL statement, '%q' substitution
-     * @param tbl TableResult to receive result set
-     * @return result set
-     */
-
-    public void get_table(String sql, String args[], TableResult tbl)
-    throws SQLite.Exception {
-    tbl.clear();
-    if (!is3()) {
-        exec(sql, tbl, args);
-    } else {
-        synchronized(this) {
-        /* only one statement !!! */
-        Vm vm = compile(sql, args);
-        while (vm.step(tbl)) {
-        }
-        vm.finalize();
-        }
-    }
-    }
-
-    /**
-     * See if an SQL statement is complete.
-     * Returns true if the input string comprises
-     * one or more complete SQL statements.
-     *
-     * @param sql the SQL statement to be checked
-     */
-
-    public synchronized static boolean complete(String sql) {
-    return _complete(sql);
-    }
-
-    private native static boolean _complete(String sql);
-
-    /**
-     * Return SQLite version number as string.
-     * Don't rely on this when both SQLite 2 and 3 are compiled
-     * into the native part. Use the class method in this case.
-     */
-
-    public native static String version();
-
-    /**
-     * Return SQLite version number as string.
-     * If the database is not open, <tt>unknown</tt> is returned.
-     */
-
-    public native String dbversion();
-
-    /**
-     * Create regular function.
-     *
-     * @param name the name of the new function
-     * @param nargs number of arguments to function
-     * @param f interface of function
-     */
-
-    public void create_function(String name, int nargs, Function f) {
-    synchronized(this) {
-        _create_function(name, nargs, f);
-    }
-    }
-
-    private native void _create_function(String name, int nargs, Function f);
-
-    /**
-     * Create aggregate function.
-     *
-     * @param name the name of the new function
-     * @param nargs number of arguments to function
-     * @param f interface of function
-     */
-
-    public void create_aggregate(String name, int nargs, Function f) {
-    synchronized(this) {
-        _create_aggregate(name, nargs, f);
-    }
-    }
-
-    private native void _create_aggregate(String name, int nargs, Function f);
-
-    /**
-     * Set function return type. Only available in SQLite 2.6.0 and
-     * above, otherwise a no-op.
-     *
-     * @param name the name of the function whose return type is to be set
-     * @param type return type code, e.g. SQLite.Constants.SQLITE_NUMERIC
-     */
-
-    public void function_type(String name, int type) {
-    synchronized(this) {
-        _function_type(name, type);
-    }
-    }
-
-    private native void _function_type(String name, int type);
-
-    /**
-     * Return the code of the last error occured in
-     * any of the exec() methods. The value is valid
-     * after an Exception has been reported by one of
-     * these methods. See the <A HREF="Constants.html">Constants</A>
-     * class for possible values.
-     *
-     * @return SQLite error code
-     */
-
-    public int last_error() {
-    return error_code;
-    }
-
-    /**
-     * Internal: set error code.
-     * @param error_code new error code
-     */
-
-    protected void set_last_error(int error_code) {
-    this.error_code = error_code;
-    }
-
-    /**
-     * Return last error message of SQLite3 engine.
-     *
-     * @return error string or null
-     */
-
-    public String error_message() {
-    synchronized(this) {
-        return _errmsg();
-    }
-    }
-
-    private native String _errmsg();
-
-    /**
-     * Return error string given SQLite error code (SQLite2).
-     *
-     * @param error_code the error code
-     * @return error string
-     */
-
-    public static native String error_string(int error_code);
-
-    /**
-     * Set character encoding.
-     * @param enc name of encoding
-     */
-
-    public void set_encoding(String enc) throws SQLite.Exception {
-    synchronized(this) {
-        _set_encoding(enc);
-    }
-    }
-
-    private native void _set_encoding(String enc)
-    throws SQLite.Exception;
-
-    /**
-     * Set authorizer function. Only available in SQLite 2.7.6 and
-     * above, otherwise a no-op.
-     *
-     * @param auth the authorizer function
-     */
-
-    public void set_authorizer(Authorizer auth) {
-    synchronized(this) {
-        _set_authorizer(auth);
-    }
-    }
-
-    private native void _set_authorizer(Authorizer auth);
-
-    /**
-     * Set trace function. Only available in SQLite 2.7.6 and above,
-     * otherwise a no-op.
-     *
-     * @param tr the trace function
-     */
-
-    public void trace(Trace tr) {
-    synchronized(this) {
-        _trace(tr);
-    }
-    }
-
-    private native void _trace(Trace tr);
-
-    /**
-     * Compile and return SQLite VM for SQL statement. Only available
-     * in SQLite 2.8.0 and above, otherwise a no-op.
-     *
-     * @param sql SQL statement to be compiled
-     * @return a Vm object
-     */
-
-    public Vm compile(String sql) throws SQLite.Exception {
-    synchronized(this) {
-        Vm vm = new Vm();
-        vm_compile(sql, vm);
-        return vm;
-    }
-    }
-
-    /**
-     * Compile and return SQLite VM for SQL statement. Only available
-     * in SQLite 3.0 and above, otherwise a no-op.
-     *
-     * @param sql SQL statement to be compiled
-     * @param args arguments for the SQL statement, '%q' substitution
-     * @return a Vm object
-     */
-
-    public Vm compile(String sql, String args[]) throws SQLite.Exception {
-    synchronized(this) {
-        Vm vm = new Vm();
-        vm_compile_args(sql, vm, args);
-        return vm;
-    }
-    }
-
-    /**
-     * Prepare and return SQLite3 statement for SQL. Only available
-     * in SQLite 3.0 and above, otherwise a no-op.
-     *
-     * @param sql SQL statement to be prepared
-     * @return a Stmt object
-     */
-
-    public Stmt prepare(String sql) throws SQLite.Exception {
-    synchronized(this) {
-        Stmt stmt = new Stmt();
-        stmt_prepare(sql, stmt);
-        return stmt;
-    }
-    }
-
-    /**
-     * Open an SQLite3 blob. Only available in SQLite 3.4.0 and above.
-     * @param db database name
-     * @param table table name
-     * @param column column name
-     * @param row row identifier
-     * @param rw if true, open for read-write, else read-only
-     * @return a Blob object
-     */
-
-    public Blob open_blob(String db, String table, String column,
-              long row, boolean rw) throws SQLite.Exception {
-    synchronized(this) {
-        Blob blob = new Blob();
-        _open_blob(db, table, column, row, rw, blob);
-        return blob;
-    }
-    }
-
-    /**
-     * Check type of open database.
-     * @return true if SQLite3 database
-     */
-
-    public native boolean is3();
-
-    /**
-     * Internal compile method.
-     * @param sql SQL statement
-     * @param vm Vm object
-     */
-
-    private native void vm_compile(String sql, Vm vm)
-    throws SQLite.Exception;
-
-    /**
-     * Internal compile method, SQLite 3.0 only.
-     * @param sql SQL statement
-     * @param args arguments for the SQL statement, '%q' substitution
-     * @param vm Vm object
-     */
-
-    private native void vm_compile_args(String sql, Vm vm, String args[])
-    throws SQLite.Exception;
-
-    /**
-     * Internal SQLite3 prepare method.
-     * @param sql SQL statement
-     * @param stmt Stmt object
-     */
-
-    private native void stmt_prepare(String sql, Stmt stmt)
-    throws SQLite.Exception;
-
-    /**
-     * Internal SQLite open blob method.
-     * @param db database name
-     * @param table table name
-     * @param column column name
-     * @param row row identifier
-     * @param rw if true, open for read-write, else read-only
-     * @param blob Blob object
-     */
-
-    private native void _open_blob(String db, String table, String column,
-                   long row, boolean rw, Blob blob)
-    throws SQLite.Exception;
-
-    /**
-     * Establish a progress callback method which gets called after
-     * N SQLite VM opcodes.
-     *
-     * @param n number of SQLite VM opcodes until callback is invoked
-     * @param p the object implementing the progress callback method
-     */
-
-    public void progress_handler(int n, SQLite.ProgressHandler p) {
-    synchronized(this) {
-        _progress_handler(n, p);
-    }
-    }
-
-    private native void _progress_handler(int n, SQLite.ProgressHandler p);
-
-    /**
-     * Internal native initializer.
-     */
-
-    private static native void internal_init();
-
-    /**
-     * Static initializer to load the native part.
-     */
-
-    static {
-    try {
-//        String path = System.getProperty("SQLite.library.path");
-//        if (path == null || path.length() == 0){
-//        System.loadLibrary("sqlite_jni");
-//        } else {
-//        try {
-//            java.lang.reflect.Method mapLibraryName;
-//            Class param[] = new Class[1];
-//            param[0] = String.class;
-//            mapLibraryName = System.class.getMethod("mapLibraryName",
-//                                param);
-//            Object args[] = new Object[1];
-//            args[0] = "sqlite_jni";
-//            String mapped = (String) mapLibraryName.invoke(null, args);
-//            System.load(path + java.io.File.separator + mapped);
-//        } catch (Throwable t) {
-//            System.loadLibrary("sqlite_jni");
-//        }
-//        }
-        internal_init();
-    } catch (Throwable t) {
-        System.err.println("Unable to load sqlite: " + t);
-    }
-    }
-}
-
diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCConnection.java b/sql/src/main/java/SQLite/JDBC2y/JDBCConnection.java
deleted file mode 100644
index 20c98e3..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/JDBCConnection.java
+++ /dev/null
@@ -1,452 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.*;
-import java.util.*;
-
-public class JDBCConnection
-    implements java.sql.Connection, SQLite.BusyHandler {
-
-    /**
-     * Open database.
-     */
-    protected DatabaseX db;
-
-    /**
-     * Database URL.
-     */
-    protected String url;
-
-    /**
-     * Character encoding.
-     */
-    protected String enc;
-
-    /**
-     * Autocommit flag, true means autocommit.
-     */
-    protected boolean autocommit = true;
-
-    /**
-     * In-transaction flag.
-     * Can be true only when autocommit false.
-     */
-    protected boolean intrans = false;
-
-    /**
-     * Timeout for Database.exec()
-     */
-    protected int timeout = 1000000;
-
-    /**
-     * File name of database.
-     */
-    private String dbfile = null;
-
-    /**
-     * Reference to meta data or null.
-     */
-    private JDBCDatabaseMetaData meta = null;
-
-    /**
-     * Base time value for timeout handling.
-     */
-    private long t0;
-
-    /**
-     * Database in readonly mode.
-     */
-    private boolean readonly = false;
-
-
-    private boolean busy0(DatabaseX db, int count) {
-    if (count <= 1) {
-        t0 = System.currentTimeMillis();
-    }
-    if (db != null) {
-        long t1 = System.currentTimeMillis();
-        if (t1 - t0 > timeout) {
-        return false;
-        }
-        db.wait(100);
-        return true;
-    }
-    return false;
-    }
-
-    public boolean busy(String table, int count) {
-    return busy0(db, count);
-    }
-
-    protected boolean busy3(DatabaseX db, int count) {
-    if (count <= 1) {
-        t0 = System.currentTimeMillis();
-    }
-    if (db != null) {
-        long t1 = System.currentTimeMillis();
-        if (t1 - t0 > timeout) {
-        return false;
-        }
-        return true;
-    }
-    return false;
-    }
-
-    private DatabaseX open(boolean readonly) throws SQLException {
-    DatabaseX db = null;
-    try {
-        db = new DatabaseX();
-        db.open(dbfile, readonly ? 0444 : 0644);
-        db.set_encoding(enc);
-    } catch (SQLite.Exception e) {
-        throw new SQLException(e.toString());
-    }
-    int loop = 0;
-    while (true) {
-        try {
-        db.exec("PRAGMA short_column_names = off;", null);
-        db.exec("PRAGMA full_column_names = on;", null);
-        db.exec("PRAGMA empty_result_callbacks = on;", null);
-        if (SQLite.Database.version().compareTo("2.6.0") >= 0) {
-            db.exec("PRAGMA show_datatypes = on;", null);
-        }
-        } catch (SQLite.Exception e) {
-        if (db.last_error() != SQLite.Constants.SQLITE_BUSY ||
-            !busy0(db, ++loop)) {
-            try {
-            db.close();
-            } catch (SQLite.Exception ee) {
-            }
-            throw new SQLException(e.toString());
-        }
-        continue;
-        }
-        break;
-    }
-    return db;
-    }
-
-    public JDBCConnection(String url, String enc) throws SQLException {
-    if (url.startsWith("sqlite:/")) {
-        dbfile = url.substring(8);
-    } else if (url.startsWith("jdbc:sqlite:/")) {
-        dbfile = url.substring(13);
-    } else {
-        throw new SQLException("unsupported url");
-    }
-    this.url = url;
-    this.enc = enc;
-    try {
-        db = open(readonly);
-        db.busy_handler(this);
-    } catch (SQLException e) {
-        if (db != null) {
-        try {
-            db.close();
-        } catch (SQLite.Exception ee) {
-        }
-        }
-        throw e;
-    }
-    }
-
-    /* non-standard */
-    public SQLite.Database getSQLiteDatabase() {
-    return (SQLite.Database) db;
-    }
-  
-    public Statement createStatement() {
-    JDBCStatement s = new JDBCStatement(this);
-    return s;
-    }
-  
-    public Statement createStatement(int resultSetType,
-                     int resultSetConcurrency)
-    throws SQLException {
-    JDBCStatement s = new JDBCStatement(this);
-    return s;
-    }
-    
-    public DatabaseMetaData getMetaData() throws SQLException {
-    if (meta == null) {
-        meta = new JDBCDatabaseMetaData(this);
-    }
-    return meta;
-    }
-
-    public void close() throws SQLException {
-    try {
-        rollback();
-    } catch (SQLException e) {
-        /* ignored */
-    }
-    intrans = false;
-    if (db != null) {
-        try {
-        db.close();
-        db = null;
-        } catch (SQLite.Exception e) {
-        throw new SQLException(e.toString());
-        }
-    }
-    }
-
-    public boolean isClosed() throws SQLException {
-    return db == null;
-    }
-
-    public boolean isReadOnly() throws SQLException {
-    return readonly;
-    }
-
-    public void clearWarnings() throws SQLException {
-    }
-
-    public void commit() throws SQLException {
-    if (db == null) {
-        throw new SQLException("stale connection");
-    }
-    if (!intrans) {
-        return;
-    }
-    try {
-        db.exec("COMMIT", null);
-        intrans = false;
-    } catch (SQLite.Exception e) {
-        throw new SQLException(e.toString());
-    }
-    }
-
-    public boolean getAutoCommit() throws SQLException {
-    return autocommit;
-    }
-
-    public String getCatalog() throws SQLException {
-    return null;
-    }
-
-    public int getTransactionIsolation() throws SQLException {
-    return TRANSACTION_SERIALIZABLE;
-    }
-
-    public SQLWarning getWarnings() throws SQLException {
-    return null;
-    }
-
-    public String nativeSQL(String sql) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public CallableStatement prepareCall(String sql) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public CallableStatement prepareCall(String sql, int x, int y)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public PreparedStatement prepareStatement(String sql) throws SQLException {
-    JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
-    return s;
-    }
-
-    public PreparedStatement prepareStatement(String sql, int resultSetType,
-                          int resultSetConcurrency)
-    throws SQLException {
-    JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
-    return s;
-    }
-
-    public void rollback() throws SQLException {
-    if (db == null) {
-        throw new SQLException("stale connection");
-    }
-    if (!intrans) {
-        return;
-    }
-    try {
-        db.exec("ROLLBACK", null);
-        intrans = false;
-    } catch (SQLite.Exception e) {
-        throw new SQLException(e.toString());
-    }
-    }
-
-    public void setAutoCommit(boolean ac) throws SQLException {
-    if (ac && intrans && db != null) {
-        try {
-        db.exec("ROLLBACK", null);
-        } catch (SQLite.Exception e) {
-        throw new SQLException(e.toString());
-        }
-    }
-    intrans = false;
-    autocommit = ac;
-    }
-
-    public void setCatalog(String catalog) throws SQLException {
-    }
-
-    public void setReadOnly(boolean ro) throws SQLException {
-    if (intrans) {
-        throw new SQLException("incomplete transaction");
-    }
-    if (ro != readonly) {
-        DatabaseX db = null;
-        try {
-        db = open(ro);
-        this.db.close();
-        this.db = db;
-        db = null;
-        readonly = ro;
-        } catch (SQLException e) {
-        throw e;
-        } catch (SQLite.Exception ee) {
-        if (db != null) {
-            try {
-            db.close();
-            } catch (SQLite.Exception eee) {
-            }
-        }
-        throw new SQLException(ee.toString());
-        }
-    }
-    }
-
-    public void setTransactionIsolation(int level) throws SQLException {
-    if (level != TRANSACTION_SERIALIZABLE) {
-        throw new SQLException("not supported");
-    }
-    }
-
-    public java.util.Map<String, Class<?>> getTypeMap() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setTypeMap(java.util.Map map) throws SQLException {
-    throw new SQLException("not supported");
-    }
-  
-    public int getHoldability() throws SQLException {
-    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-    }
-
-    public void setHoldability(int holdability) throws SQLException {
-    if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) {
-        return;
-    }
-    throw new SQLException("not supported");
-    }
-
-    public Savepoint setSavepoint() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Savepoint setSavepoint(String name) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void rollback(Savepoint x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void releaseSavepoint(Savepoint x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Statement createStatement(int resultSetType,
-                     int resultSetConcurrency,
-                     int resultSetHoldability)
-    throws SQLException {
-    if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
-        throw new SQLException("not supported");
-    }
-    return createStatement(resultSetType, resultSetConcurrency);
-    }
-
-    public PreparedStatement prepareStatement(String sql, int resultSetType,
-                          int resultSetConcurrency,
-                          int resultSetHoldability)
-    throws SQLException {
-    if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
-        throw new SQLException("not supported");
-    }
-    return prepareStatement(sql, resultSetType, resultSetConcurrency);
-    }
-
-    public CallableStatement prepareCall(String sql, int x, int y, int z)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public PreparedStatement prepareStatement(String sql, int autokeys)
-    throws SQLException {
-    if (autokeys != Statement.NO_GENERATED_KEYS) {
-        throw new SQLException("not supported");
-    }
-    return prepareStatement(sql);
-    }
-
-    public PreparedStatement prepareStatement(String sql, int colIndexes[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public PreparedStatement prepareStatement(String sql, String columns[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-}
-
-class DatabaseX extends SQLite.Database {
-
-    static Object lock = new Object();
-
-    public DatabaseX() {
-    super();
-    }
-
-    void wait(int ms) {
-    try {
-        synchronized (lock) {
-        lock.wait(ms);
-        }
-    } catch (java.lang.Exception e) {
-    }
-    }
-
-    public void exec(String sql, SQLite.Callback cb)
-    throws SQLite.Exception {
-    super.exec(sql, cb);
-    synchronized (lock) {
-        lock.notifyAll();
-    }
-    }
-
-    public void exec(String sql, SQLite.Callback cb, String args[])
-    throws SQLite.Exception {
-    super.exec(sql, cb, args);
-    synchronized (lock) {
-        lock.notifyAll();
-    }
-    }
-
-    public SQLite.TableResult get_table(String sql, String args[])
-    throws SQLite.Exception {
-    SQLite.TableResult ret = super.get_table(sql, args);
-    synchronized (lock) {
-        lock.notifyAll();
-    }
-    return ret;
-    }
-
-    public void get_table(String sql, String args[], SQLite.TableResult tbl)
-    throws SQLite.Exception {
-    super.get_table(sql, args, tbl);
-    synchronized (lock) {
-        lock.notifyAll();
-    }
-    }
-
-}
diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java b/sql/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java
deleted file mode 100644
index 8c14d1d..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java
+++ /dev/null
@@ -1,1578 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.*;
-import java.util.Hashtable;
-
-public class JDBCDatabaseMetaData implements DatabaseMetaData {
-
-    private JDBCConnection conn;
-
-    public JDBCDatabaseMetaData(JDBCConnection conn) {
-    this.conn = conn;
-    }
-
-    public boolean allProceduresAreCallable() throws SQLException {
-    return false;
-    }
-
-    public boolean allTablesAreSelectable() throws SQLException {
-    return true;
-    }
-
-    public String getURL() throws SQLException {
-    return conn.url;
-    }
-
-    public String getUserName() throws SQLException {
-    return "";
-    }
-
-    public boolean isReadOnly() throws SQLException {
-    return false;
-    }
-
-    public boolean nullsAreSortedHigh() throws SQLException {
-    return false;
-    }
-
-    public boolean nullsAreSortedLow() throws SQLException {
-    return false;
-    }
-
-    public boolean nullsAreSortedAtStart() throws SQLException {
-    return false;
-    }
-
-    public boolean nullsAreSortedAtEnd() throws SQLException {
-    return false;
-    }
-
-    public String getDatabaseProductName() throws SQLException {
-    return "SQLite";
-    }
-
-    public String getDatabaseProductVersion() throws SQLException {
-    return SQLite.Database.version();
-    }
-
-    public String getDriverName() throws SQLException {
-    return "SQLite/JDBC";
-    }
-
-    public String getDriverVersion() throws SQLException {
-    return "" + SQLite.JDBCDriver.MAJORVERSION + "." +
-        SQLite.JDBCDriver.MINORVERSION;
-    }
-
-    public int getDriverMajorVersion() {
-    return SQLite.JDBCDriver.MAJORVERSION;
-    }
-
-    public int getDriverMinorVersion() {
-    return SQLite.JDBCDriver.MINORVERSION;
-    }
-
-    public boolean usesLocalFiles() throws SQLException {
-    return true;
-    }
-
-    public boolean usesLocalFilePerTable() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsMixedCaseIdentifiers() throws SQLException {
-    return false;
-    }
-
-    public boolean storesUpperCaseIdentifiers() throws SQLException {
-    return false;
-    }
-
-    public boolean storesLowerCaseIdentifiers() throws SQLException {
-    return false;
-    }
-
-    public boolean storesMixedCaseIdentifiers() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
-    return false;
-    }
-
-    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
-    return false;
-    }
-
-    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
-    return false;
-    }
-
-    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
-    return true;
-    }
-
-    public String getIdentifierQuoteString() throws SQLException {
-    return "\"";
-    }
-
-    public String getSQLKeywords() throws SQLException {
-    return "SELECT,UPDATE,CREATE,TABLE,VIEW,DELETE,FROM,WHERE" +
-        ",COMMIT,ROLLBACK,TRIGGER";
-    }
-
-    public String getNumericFunctions() throws SQLException {
-    return ""; 
-    }
-
-    public String getStringFunctions() throws SQLException {
-    return "";
-    }
-
-    public String getSystemFunctions() throws SQLException {
-    return "";
-    }
-
-    public String getTimeDateFunctions() throws SQLException {
-    return "";
-    }
-
-    public String getSearchStringEscape() throws SQLException {
-    return "\\";
-    }
-
-    public String getExtraNameCharacters() throws SQLException {
-    return "";
-    }
-
-    public boolean supportsAlterTableWithAddColumn() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsAlterTableWithDropColumn() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsColumnAliasing() throws SQLException {
-    return true;
-    }
-
-    public boolean nullPlusNonNullIsNull() throws SQLException {
-    return false;
-    }
-    
-    public boolean supportsConvert() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsConvert(int fromType, int toType)
-    throws SQLException {
-    return false;
-    }
-
-    public boolean supportsTableCorrelationNames() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsDifferentTableCorrelationNames()
-    throws SQLException {
-    return false;
-    }
-
-    public boolean supportsExpressionsInOrderBy() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsOrderByUnrelated() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsGroupBy() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsGroupByUnrelated() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsGroupByBeyondSelect() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsLikeEscapeClause() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsMultipleResultSets() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsMultipleTransactions() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsNonNullableColumns() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsMinimumSQLGrammar() throws SQLException {
-    return true;
-    } 
-
-    public boolean supportsCoreSQLGrammar() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsExtendedSQLGrammar() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsANSI92IntermediateSQL() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsANSI92FullSQL() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsIntegrityEnhancementFacility()
-    throws SQLException {
-    return false;
-    }
-
-    public boolean supportsOuterJoins() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsFullOuterJoins() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsLimitedOuterJoins() throws SQLException {
-    return false;
-    }
-
-    public String getSchemaTerm() throws SQLException {
-    return "";
-    }
-
-    public String getProcedureTerm() throws SQLException {
-    return "";
-    }
-
-    public String getCatalogTerm() throws SQLException {
-    return "";
-    }
-
-    public boolean isCatalogAtStart() throws SQLException {
-    return false;
-    }
-
-    public String getCatalogSeparator() throws SQLException {
-    return "";
-    }
-
-    public boolean supportsSchemasInDataManipulation() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsSchemasInProcedureCalls() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsSchemasInTableDefinitions() throws SQLException {
-    return false;
-    }
-    
-    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsSchemasInPrivilegeDefinitions()
-    throws SQLException {
-    return false;
-    }
-
-    public boolean supportsCatalogsInDataManipulation() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsCatalogsInPrivilegeDefinitions()
-    throws SQLException {
-    return false;
-    }
-
-    public boolean supportsPositionedDelete() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsPositionedUpdate() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsSelectForUpdate() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsStoredProcedures() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsSubqueriesInComparisons() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsSubqueriesInExists() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsSubqueriesInIns() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsCorrelatedSubqueries() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsUnion() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsUnionAll() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
-    return false;
-    }
-
-    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
-    return false;
-    }
-
-    public int getMaxBinaryLiteralLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxCharLiteralLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxColumnNameLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxColumnsInGroupBy() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxColumnsInIndex() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxColumnsInOrderBy() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxColumnsInSelect() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxColumnsInTable() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxConnections() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxCursorNameLength() throws SQLException {
-    return 8;
-    }
-
-    public int getMaxIndexLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxSchemaNameLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxProcedureNameLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxCatalogNameLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxRowSize() throws SQLException {
-    return 0;
-    }
-
-    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
-    return true;
-    }
-
-    public int getMaxStatementLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxStatements() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxTableNameLength() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxTablesInSelect() throws SQLException {
-    return 0;
-    }
-
-    public int getMaxUserNameLength() throws SQLException {
-    return 0;
-    }
-
-    public int getDefaultTransactionIsolation() throws SQLException {
-    return Connection.TRANSACTION_SERIALIZABLE;
-    }
-
-    public boolean supportsTransactions() throws SQLException {
-    return true;
-    }
-
-    public boolean supportsTransactionIsolationLevel(int level)
-    throws SQLException {
-    return level == Connection.TRANSACTION_SERIALIZABLE;
-    }
-
-    public boolean supportsDataDefinitionAndDataManipulationTransactions()
-    throws SQLException {
-    return true;
-    }
-
-    public boolean supportsDataManipulationTransactionsOnly()
-    throws SQLException {
-    return false;
-    }
-
-    public boolean dataDefinitionCausesTransactionCommit()
-    throws SQLException {
-    return false;
-    }
-
-    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
-    return false;
-    }
-
-    public ResultSet getProcedures(String catalog, String schemaPattern,
-                   String procedureNamePattern)
-    throws SQLException {
-    return null;
-    }
-
-    public ResultSet getProcedureColumns(String catalog,
-                     String schemaPattern,
-                     String procedureNamePattern, 
-                     String columnNamePattern)
-    throws SQLException {
-    return null;
-    }
-
-    public ResultSet getTables(String catalog, String schemaPattern,
-                   String tableNamePattern, String types[])
-    throws SQLException {
-    JDBCStatement s = new JDBCStatement(conn);
-    StringBuffer sb = new StringBuffer();
-    sb.append("SELECT '' AS 'TABLE_CAT', " +
-          "'' AS 'TABLE_SCHEM', " +
-          "tbl_name AS 'TABLE_NAME', " +
-          "upper(type) AS 'TABLE_TYPE', " +
-          "'' AS REMARKS FROM sqlite_master " +
-          "WHERE tbl_name like ");
-    if (tableNamePattern != null) {
-        sb.append(SQLite.Shell.sql_quote(tableNamePattern));
-    } else {
-        sb.append("'%'");
-    }
-    sb.append(" AND ");
-    if (types == null || types.length == 0) {
-        sb.append("(type = 'table' or type = 'view')");
-    } else {
-        sb.append("(");
-        String sep = ""; 
-        for (int i = 0; i < types.length; i++) {
-        sb.append(sep);
-        sb.append("type = ");
-        sb.append(SQLite.Shell.sql_quote(types[i].toLowerCase()));
-        sep = " or ";
-        }
-        sb.append(")");
-    }
-    ResultSet rs = null;
-    try {
-        rs = s.executeQuery(sb.toString());
-        s.close();
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s.close();
-    }
-    return rs;
-    }
-
-    public ResultSet getSchemas() throws SQLException {
-    String cols[] = { "TABLE_SCHEM" };
-    SQLite.TableResult tr = new SQLite.TableResult();
-    tr.columns(cols);
-    String row[] = { "" };
-    tr.newrow(row);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    return (ResultSet) rs;
-    }
-
-    public ResultSet getCatalogs() throws SQLException {
-    String cols[] = { "TABLE_CAT" };
-    SQLite.TableResult tr = new SQLite.TableResult();
-    tr.columns(cols);
-    String row[] = { "" };
-    tr.newrow(row);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    return (ResultSet) rs;
-    }
-
-    public ResultSet getTableTypes() throws SQLException {
-    String cols[] = { "TABLE_TYPE" };
-    SQLite.TableResult tr = new SQLite.TableResult();
-    tr.columns(cols);
-    String row[] = new String[1];
-    row[0] = "TABLE";
-    tr.newrow(row);
-    row = new String[1];
-    row[0] = "VIEW";
-    tr.newrow(row);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    return (ResultSet) rs;
-    }
-
-    public ResultSet getColumns(String catalog, String schemaPattern,
-                String tableNamePattern,
-                String columnNamePattern)
-    throws SQLException {
-    JDBCStatement s = new JDBCStatement(conn);
-    JDBCResultSet rs0 = null;
-    try {
-        rs0 = (JDBCResultSet)
-        (s.executeQuery("PRAGMA table_info(" +
-                SQLite.Shell.sql_quote(tableNamePattern) +
-                ")"));
-        s.close();
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s.close();
-    }
-    String cols[] = {
-        "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
-        "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME",
-        "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_POINTS",
-        "NUM_PREC_RADIX", "NULLABLE", "REMARKS",
-        "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB",
-        "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.SMALLINT, Types.VARCHAR,
-        Types.INTEGER, Types.INTEGER, Types.INTEGER,
-        Types.INTEGER, Types.INTEGER, Types.VARCHAR,
-        Types.VARCHAR, Types.INTEGER, Types.INTEGER,
-        Types.INTEGER, Types.INTEGER, Types.VARCHAR
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
-        Hashtable<String, Integer> h = new Hashtable<String, Integer>();
-        for (int i = 0; i < rs0.tr.ncolumns; i++) {
-        h.put(rs0.tr.column[i], new Integer(i));
-        }
-        if (columnNamePattern != null &&
-        columnNamePattern.charAt(0) == '%') {
-        columnNamePattern = null;
-        }
-        for (int i = 0; i < rs0.tr.nrows; i++) {
-        String r0[] = (String [])(rs0.tr.rows.elementAt(i));
-        int col = ((Integer) h.get("name")).intValue();
-        if (columnNamePattern != null) {
-            if (r0[col].compareTo(columnNamePattern) != 0) {
-            continue;
-            }
-        }
-        String row[] = new String[cols.length];
-        row[0]  = "";
-        row[1]  = "";
-        row[2]  = tableNamePattern;
-        row[3]  = r0[col];
-        col = ((Integer) h.get("type")).intValue();
-        String typeStr = r0[col];
-        int type = mapSqlType(typeStr);
-        row[4]  = "" + type;
-        row[5]  = mapTypeName(type);
-        row[6]  = "" + getD(typeStr, type);
-        row[7]  = "" + getM(typeStr, type);
-        row[8]  = "10";
-        row[9]  = "0";
-        row[11] = null;
-        col = ((Integer) h.get("dflt_value")).intValue();
-        row[12] = r0[col];
-        row[13] = "0";
-        row[14] = "0";
-        row[15] = "65536";
-        col = ((Integer) h.get("cid")).intValue();
-        Integer cid = new Integer(r0[col]);
-        row[16] = "" + (cid.intValue() + 1);
-        col = ((Integer) h.get("notnull")).intValue();
-        row[17] = (r0[col].charAt(0) == '0') ? "YES" : "NO";
-        row[10] = (r0[col].charAt(0) == '0') ? "" + columnNullable :
-              "" + columnNoNulls;
-        tr.newrow(row);
-        }
-    }
-    return rs;
-    }
-
-    public ResultSet getColumnPrivileges(String catalog, String schema,
-                     String table,
-                     String columnNamePattern)
-    throws SQLException {
-    String cols[] = {
-        "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
-        "COLUMN_NAME", "GRANTOR", "GRANTEE",
-        "PRIVILEGE", "IS_GRANTABLE"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    return rs;
-    }
-
-    public ResultSet getTablePrivileges(String catalog, String schemaPattern,
-                    String tableNamePattern)
-    throws SQLException {
-    String cols[] = {
-        "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
-        "COLUMN_NAME", "GRANTOR", "GRANTEE",
-        "PRIVILEGE", "IS_GRANTABLE"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    return rs;
-    }
-
-    public ResultSet getBestRowIdentifier(String catalog, String schema,
-                      String table, int scope,
-                      boolean nullable)
-    throws SQLException {
-    JDBCStatement s0 = new JDBCStatement(conn);
-    JDBCResultSet rs0 = null;
-    JDBCStatement s1 = new JDBCStatement(conn);
-    JDBCResultSet rs1 = null;
-    try {
-        rs0 = (JDBCResultSet)
-        (s0.executeQuery("PRAGMA index_list(" +
-                 SQLite.Shell.sql_quote(table) + ")"));
-        rs1 = (JDBCResultSet)
-        (s1.executeQuery("PRAGMA table_info(" +
-                 SQLite.Shell.sql_quote(table) + ")"));
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s0.close();
-        s1.close();
-    }
-    String cols[] = {
-        "SCOPE", "COLUMN_NAME", "DATA_TYPE",
-        "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH",
-        "DECIMAL_DIGITS", "PSEUDO_COLUMN"
-    };
-    int types[] = {
-        Types.SMALLINT, Types.VARCHAR, Types.SMALLINT,
-        Types.VARCHAR, Types.INTEGER, Types.INTEGER,
-        Types.SMALLINT, Types.SMALLINT
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0 &&
-        rs1 != null && rs1.tr != null && rs1.tr.nrows > 0) {
-        Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
-        for (int i = 0; i < rs0.tr.ncolumns; i++) {
-        h0.put(rs0.tr.column[i], new Integer(i));
-        }
-        Hashtable<String, Integer> h1 = new Hashtable<String, Integer>();
-        for (int i = 0; i < rs1.tr.ncolumns; i++) {
-        h1.put(rs1.tr.column[i], new Integer(i));
-        }
-        for (int i = 0; i < rs0.tr.nrows; i++) {
-        String r0[] = (String [])(rs0.tr.rows.elementAt(i));
-        int col = ((Integer) h0.get("unique")).intValue();
-        String uniq = r0[col];
-        col = ((Integer) h0.get("name")).intValue();
-        String iname = r0[col];
-        if (uniq.charAt(0) == '0') {
-            continue;
-        }
-        JDBCStatement s2 = new JDBCStatement(conn);
-        JDBCResultSet rs2 = null;
-        try {
-            rs2 = (JDBCResultSet)
-            (s2.executeQuery("PRAGMA index_info(" +
-                     SQLite.Shell.sql_quote(iname) + ")"));
-        } catch (SQLException e) {
-        } finally {
-            s2.close();
-        }
-        if (rs2 == null || rs2.tr == null || rs2.tr.nrows <= 0) {
-            continue;
-        }
-        Hashtable<String, Integer> h2 =
-            new Hashtable<String, Integer>();
-        for (int k = 0; k < rs2.tr.ncolumns; k++) {
-            h2.put(rs2.tr.column[k], new Integer(k));
-        }
-        for (int k = 0; k < rs2.tr.nrows; k++) {
-            String r2[] = (String [])(rs2.tr.rows.elementAt(k));
-            col = ((Integer) h2.get("name")).intValue();
-            String cname = r2[col];
-            for (int m = 0; m < rs1.tr.nrows; m++) {
-            String r1[] = (String [])(rs1.tr.rows.elementAt(m));
-            col = ((Integer) h1.get("name")).intValue();
-            if (cname.compareTo(r1[col]) == 0) {
-                String row[] = new String[cols.length];
-                row[0] = "" + scope;
-                row[1] = cname;
-                row[2] = "" + Types.VARCHAR;
-                row[3] = "VARCHAR";
-                row[4] = "65536";
-                row[5] = "0";
-                row[6] = "0";
-                row[7] = "" + bestRowNotPseudo;
-                tr.newrow(row);
-            }
-            }
-        }
-        }
-    }
-    if (tr.nrows <= 0) {
-        String row[] = new String[cols.length];
-        row[0] = "" + scope;
-        row[1] = "_ROWID_";
-        row[2] = "" + Types.INTEGER;
-        row[3] = "INTEGER";
-        row[4] = "10";
-        row[5] = "0";
-        row[6] = "0";
-        row[7] = "" + bestRowPseudo;
-        tr.newrow(row);
-    }
-    return rs;
-    }
-
-    public ResultSet getVersionColumns(String catalog, String schema,
-                       String table) throws SQLException {
-    String cols[] = {
-        "SCOPE", "COLUMN_NAME", "DATA_TYPE",
-        "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH",
-        "DECIMAL_DIGITS", "PSEUDO_COLUMN"
-    };
-    int types[] = {
-        Types.SMALLINT, Types.VARCHAR, Types.SMALLINT,
-        Types.VARCHAR, Types.INTEGER, Types.INTEGER,
-        Types.SMALLINT, Types.SMALLINT
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    return rs;
-    }
-
-    public ResultSet getPrimaryKeys(String catalog, String schema,
-                    String table) throws SQLException {
-    JDBCStatement s0 = new JDBCStatement(conn);
-    JDBCResultSet rs0 = null;
-    try {
-        rs0 = (JDBCResultSet)
-        (s0.executeQuery("PRAGMA index_list(" +
-                 SQLite.Shell.sql_quote(table) + ")"));
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s0.close();
-    }
-    String cols[] = {
-        "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
-        "COLUMN_NAME", "KEY_SEQ", "PK_NAME"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.SMALLINT, Types.VARCHAR
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
-        Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
-        for (int i = 0; i < rs0.tr.ncolumns; i++) {
-        h0.put(rs0.tr.column[i], new Integer(i));
-        }
-        for (int i = 0; i < rs0.tr.nrows; i++) {
-        String r0[] = (String [])(rs0.tr.rows.elementAt(i));
-        int col = ((Integer) h0.get("unique")).intValue();
-        String uniq = r0[col];
-        col = ((Integer) h0.get("name")).intValue();
-        String iname = r0[col];
-        if (uniq.charAt(0) == '0') {
-            continue;
-        }
-        JDBCStatement s1 = new JDBCStatement(conn);
-        JDBCResultSet rs1 = null;
-        try {
-            rs1 = (JDBCResultSet)
-            (s1.executeQuery("PRAGMA index_info(" +
-                     SQLite.Shell.sql_quote(iname) + ")"));
-        } catch (SQLException e) {
-        } finally {
-            s1.close();
-        }
-        if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) {
-            continue;
-        }
-        Hashtable<String, Integer> h1 =
-            new Hashtable<String, Integer>();
-        for (int k = 0; k < rs1.tr.ncolumns; k++) {
-            h1.put(rs1.tr.column[k], new Integer(k));
-        }
-        for (int k = 0; k < rs1.tr.nrows; k++) {
-            String r1[] = (String [])(rs1.tr.rows.elementAt(k));
-            String row[] = new String[cols.length];
-            row[0]  = "";
-            row[1]  = "";
-            row[2]  = table;
-            col = ((Integer) h1.get("name")).intValue();
-            row[3] = r1[col];
-            col = ((Integer) h1.get("seqno")).intValue();
-// BEGIN android-changed
-            row[4]  = "" + (Integer.parseInt(r1[col]) + 1);
-// END android-changed
-            row[5]  = iname;
-            tr.newrow(row);
-        }
-        }
-    }
-    JDBCStatement s1 = new JDBCStatement(conn);
-    try {
-        rs0 = (JDBCResultSet)
-        (s1.executeQuery("PRAGMA table_info(" +
-                 SQLite.Shell.sql_quote(table) + ")"));
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s1.close();
-    }
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
-        Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
-        for (int i = 0; i < rs0.tr.ncolumns; i++) {
-        h0.put(rs0.tr.column[i], new Integer(i));
-        }
-        for (int i = 0; i < rs0.tr.nrows; i++) {
-        String r0[] = (String [])(rs0.tr.rows.elementAt(i));
-        int col = ((Integer) h0.get("type")).intValue();
-        String type = r0[col];
-        if (!type.equalsIgnoreCase("integer")) {
-            continue;
-        }
-        col = ((Integer) h0.get("pk")).intValue();
-        String pk = r0[col];
-        if (pk.charAt(0) == '0') {
-            continue;
-        }
-        String row[] = new String[cols.length];
-        row[0]  = "";
-        row[1]  = "";
-        row[2]  = table;
-        col = ((Integer) h0.get("name")).intValue();
-        row[3] = r0[col];
-        col = ((Integer) h0.get("cid")).intValue();
-// BEGIN android-changed
-        row[4] = "" + (Integer.parseInt(r0[col]) + 1);
-// END android-changed
-        row[5] = "";
-        tr.newrow(row);
-        }
-    }
-    return rs;
-    }
-
-    private void internalImportedKeys(String table, String pktable,
-                      JDBCResultSet in, TableResultX out) {
-    Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
-    for (int i = 0; i < in.tr.ncolumns; i++) {
-        h0.put(in.tr.column[i], new Integer(i));
-    }
-    for (int i = 0; i < in.tr.nrows; i++) {
-        String r0[] = (String [])(in.tr.rows.elementAt(i));
-        int col = ((Integer) h0.get("table")).intValue();
-        String pktab = r0[col];
-        if (pktable != null && !pktable.equalsIgnoreCase(pktab)) {
-        continue;
-        }
-        col = ((Integer) h0.get("from")).intValue();
-        String pkcol = r0[col];
-        col = ((Integer) h0.get("to")).intValue();
-        String fkcol = r0[col];
-        col = ((Integer) h0.get("seq")).intValue();
-        String seq = r0[col];
-        String row[] = new String[out.ncolumns];
-        row[0]  = "";
-        row[1]  = "";
-        row[2]  = pktab;
-        row[3]  = pkcol;
-        row[4]  = "";
-        row[5]  = "";
-        row[6]  = table;
-        row[7]  = fkcol == null ? pkcol : fkcol;
-// BEGIN android-changed
-        row[8]  = "" + ((Integer.parseInt(seq)) + 1);
-// END android-changed
-        row[9]  =
-        "" + java.sql.DatabaseMetaData.importedKeyNoAction;
-        row[10] =
-        "" + java.sql.DatabaseMetaData.importedKeyNoAction;
-        row[11] = null;
-        row[12] = null;
-        row[13] =
-        "" + java.sql.DatabaseMetaData.importedKeyNotDeferrable;
-        out.newrow(row);
-    }
-    }
-
-    public ResultSet getImportedKeys(String catalog, String schema,
-                     String table) throws SQLException {
-    JDBCStatement s0 = new JDBCStatement(conn);
-    JDBCResultSet rs0 = null;
-    try {
-        rs0 = (JDBCResultSet)
-        (s0.executeQuery("PRAGMA foreign_key_list(" +
-                 SQLite.Shell.sql_quote(table) + ")"));
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s0.close();
-    }
-    String cols[] = {
-        "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
-        "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
-        "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
-        "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
-        "PK_NAME", "DEFERRABILITY"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.SMALLINT,
-        Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
-        Types.VARCHAR, Types.SMALLINT
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
-        internalImportedKeys(table, null, rs0, tr);
-    }
-    return rs;
-    }
-
-    public ResultSet getExportedKeys(String catalog, String schema,
-                     String table) throws SQLException {
-    String cols[] = {
-        "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
-        "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
-        "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
-        "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
-        "PK_NAME", "DEFERRABILITY"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.SMALLINT,
-        Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
-        Types.VARCHAR, Types.SMALLINT
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    return rs;
-    }
-
-    public ResultSet getCrossReference(String primaryCatalog,
-                       String primarySchema,
-                       String primaryTable,
-                       String foreignCatalog,
-                       String foreignSchema,
-                       String foreignTable)
-    throws SQLException {
-    JDBCResultSet rs0 = null;
-    if (foreignTable != null && foreignTable.charAt(0) != '%') {
-        JDBCStatement s0 = new JDBCStatement(conn);
-        try {
-        rs0 = (JDBCResultSet)
-            (s0.executeQuery("PRAGMA foreign_key_list(" +
-                     SQLite.Shell.sql_quote(foreignTable) + ")"));
-        } catch (SQLException e) {
-        throw e;
-        } finally {
-        s0.close();
-        }
-    }
-    String cols[] = {
-        "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
-        "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
-        "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
-        "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
-        "PK_NAME", "DEFERRABILITY"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.VARCHAR, Types.VARCHAR, Types.SMALLINT,
-        Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
-        Types.VARCHAR, Types.SMALLINT
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
-        String pktable = null;
-        if (primaryTable != null && primaryTable.charAt(0) != '%') {
-        pktable = primaryTable;
-        }
-        internalImportedKeys(foreignTable, pktable, rs0, tr);
-    }
-    return rs;
-    }
-
-    public ResultSet getTypeInfo() throws SQLException {
-    String cols[] = {
-        "TYPE_NAME", "DATA_TYPE", "PRECISION",
-        "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS",
-        "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE",
-        "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT",
-        "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE",
-        "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.SMALLINT, Types.INTEGER,
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.SMALLINT, Types.BIT, Types.SMALLINT,
-        Types.BIT, Types.BIT, Types.BIT,
-        Types.VARCHAR, Types.SMALLINT, Types.SMALLINT,
-        Types.INTEGER, Types.INTEGER, Types.INTEGER
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    String row1[] = {
-        "VARCHAR", "" + Types.VARCHAR, "65536",
-        "'", "'", null,
-        "" + typeNullable, "1", "" + typeSearchable,
-        "0", "0", "0",
-        null, "0", "0",
-        "0", "0", "0"
-    };
-    tr.newrow(row1);
-    String row2[] = {
-        "INTEGER", "" + Types.INTEGER, "32",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "2"
-    };
-    tr.newrow(row2);
-    String row3[] = {
-        "DOUBLE", "" + Types.DOUBLE, "16",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "10"
-    };
-    tr.newrow(row3);
-    String row4[] = {
-        "FLOAT", "" + Types.FLOAT, "7",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "10"
-    };
-    tr.newrow(row4);
-    String row5[] = {
-        "SMALLINT", "" + Types.SMALLINT, "16",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "2"
-    };
-    tr.newrow(row5);
-    String row6[] = {
-        "BIT", "" + Types.BIT, "1",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "2"
-    };
-    tr.newrow(row6);
-    String row7[] = {
-        "TIMESTAMP", "" + Types.TIMESTAMP, "30",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "0"
-    };
-    tr.newrow(row7);
-    String row8[] = {
-        "DATE", "" + Types.DATE, "10",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "0"
-    };
-    tr.newrow(row8);
-    String row9[] = {
-        "TIME", "" + Types.TIME, "8",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "0"
-    };
-    tr.newrow(row9);
-    String row10[] = {
-        "BINARY", "" + Types.BINARY, "65536",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "0"
-    };
-    tr.newrow(row10);
-    String row11[] = {
-        "VARBINARY", "" + Types.VARBINARY, "65536",
-        null, null, null,
-        "" + typeNullable, "0", "" + typeSearchable,
-        "0", "0", "1",
-        null, "0", "0",
-        "0", "0", "0"
-    };
-    tr.newrow(row11);
-    return rs;
-    }
-
-    public ResultSet getIndexInfo(String catalog, String schema, String table,
-                  boolean unique, boolean approximate)
-    throws SQLException {
-    JDBCStatement s0 = new JDBCStatement(conn);
-    JDBCResultSet rs0 = null;
-    try {
-        rs0 = (JDBCResultSet)
-        (s0.executeQuery("PRAGMA index_list(" +
-                 SQLite.Shell.sql_quote(table) + ")"));
-    } catch (SQLException e) {
-        throw e;
-    } finally {
-        s0.close();
-    }
-    String cols[] = {
-        "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
-        "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME",
-        "TYPE", "ORDINAL_POSITION", "COLUMN_NAME",
-        "ASC_OR_DESC", "CARDINALITY", "PAGES",
-        "FILTER_CONDITION"
-    };
-    int types[] = {
-        Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
-        Types.BIT, Types.VARCHAR, Types.VARCHAR,
-        Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
-        Types.VARCHAR, Types.INTEGER, Types.INTEGER,
-        Types.VARCHAR
-    };
-    TableResultX tr = new TableResultX();
-    tr.columns(cols);
-    tr.sql_types(types);
-    JDBCResultSet rs = new JDBCResultSet(tr, null);
-    if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
-        Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
-        for (int i = 0; i < rs0.tr.ncolumns; i++) {
-        h0.put(rs0.tr.column[i], new Integer(i));
-        }
-        for (int i = 0; i < rs0.tr.nrows; i++) {
-        String r0[] = (String [])(rs0.tr.rows.elementAt(i));
-        int col = ((Integer) h0.get("unique")).intValue();
-        String uniq = r0[col];
-        col = ((Integer) h0.get("name")).intValue();
-        String iname = r0[col];
-        if (unique && uniq.charAt(0) == '0') {
-            continue;
-        }
-        JDBCStatement s1 = new JDBCStatement(conn);
-        JDBCResultSet rs1 = null;
-        try {
-            rs1 = (JDBCResultSet)
-            (s1.executeQuery("PRAGMA index_info(" +
-                     SQLite.Shell.sql_quote(iname) + ")"));
-        } catch (SQLException e) {
-        } finally {
-            s1.close();
-        }
-        if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) {
-            continue;
-        }
-        Hashtable<String, Integer> h1 =
-            new Hashtable<String, Integer>();
-        for (int k = 0; k < rs1.tr.ncolumns; k++) {
-            h1.put(rs1.tr.column[k], new Integer(k));
-        }
-        for (int k = 0; k < rs1.tr.nrows; k++) {
-            String r1[] = (String [])(rs1.tr.rows.elementAt(k));
-            String row[] = new String[cols.length];
-            row[0]  = "";
-            row[1]  = "";
-            row[2]  = table;
-            row[3]  = (uniq.charAt(0) != '0' ||
-            (iname.charAt(0) == '(' &&
-             iname.indexOf(" autoindex ") > 0)) ? "0" : "1";
-            row[4]  = "";
-            row[5]  = iname;
-            row[6]  = "" + tableIndexOther;
-            col = ((Integer) h1.get("seqno")).intValue();
-// BEGIN android-changed
-            row[7]  = "" + (Integer.parseInt(r1[col]) + 1);
-// END android-changed
-            col = ((Integer) h1.get("name")).intValue();
-            row[8]  = r1[col];
-            row[9]  = "A";
-            row[10] = "0";
-            row[11] = "0";
-            row[12] = null;
-            tr.newrow(row);
-        }
-        }
-    }
-    return rs;
-    }
-
-    public boolean supportsResultSetType(int type) throws SQLException {
-    return type == ResultSet.CONCUR_READ_ONLY;
-    }
-
-    public boolean supportsResultSetConcurrency(int type, int concurrency)
-    throws SQLException {
-    return false;
-    }
-
-    public boolean ownUpdatesAreVisible(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean ownDeletesAreVisible(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean ownInsertsAreVisible(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean othersUpdatesAreVisible(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean othersDeletesAreVisible(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean othersInsertsAreVisible(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean updatesAreDetected(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean deletesAreDetected(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean insertsAreDetected(int type) throws SQLException {
-    return false;
-    }
-
-    public boolean supportsBatchUpdates() throws SQLException {
-    return false;
-    }
-
-    public ResultSet getUDTs(String catalog, String schemaPattern, 
-              String typeNamePattern, int[] types) 
-    throws SQLException {
-    return null;
-    }
-
-    public Connection getConnection() throws SQLException {
-    return conn;
-    }
-
-    static String mapTypeName(int type) {
-    switch (type) {
-    case Types.INTEGER:    return "integer";
-    case Types.SMALLINT:    return "smallint";
-    case Types.FLOAT:    return "float";
-    case Types.DOUBLE:    return "double";
-    case Types.TIMESTAMP:    return "timestamp";
-    case Types.DATE:    return "date";
-    case Types.TIME:    return "time";
-    case Types.BINARY:    return "binary";
-    case Types.VARBINARY:    return "varbinary";
-    }
-    return "varchar";
-    }
-
-    static int mapSqlType(String type) {
-    if (type == null) {
-        return Types.VARCHAR;
-    }
-    type = type.toLowerCase();
-    if (type.startsWith("inter")) {
-        return Types.VARCHAR;
-    }
-    if (type.startsWith("numeric") ||
-        type.startsWith("int")) {
-        return Types.INTEGER;
-    }
-    if (type.startsWith("tinyint") ||
-        type.startsWith("smallint")) {
-        return Types.SMALLINT;
-    }
-    if (type.startsWith("float")) {
-        return Types.FLOAT;
-    }
-    if (type.startsWith("double")) {
-        return Types.DOUBLE;
-    }
-    if (type.startsWith("datetime") ||
-        type.startsWith("timestamp")) {
-        return Types.TIMESTAMP;
-    }
-    if (type.startsWith("date")) {
-        return Types.DATE;
-    }
-    if (type.startsWith("time")) {
-        return Types.TIME;
-    }
-    if (type.startsWith("blob")) {
-        return Types.BINARY;
-    }
-    if (type.startsWith("binary")) {
-        return Types.BINARY;
-    }
-    if (type.startsWith("varbinary")) {
-        return Types.VARBINARY;
-    }
-    return Types.VARCHAR;
-    }
-
-    static int getM(String typeStr, int type) {
-    int m = 65536;
-    switch (type) {
-    case Types.INTEGER:    m = 11; break;
-    case Types.SMALLINT:    m = 6;  break;
-    case Types.FLOAT:    m = 25; break;
-    case Types.DOUBLE:    m = 54; break;
-    case Types.TIMESTAMP:    return 30;
-    case Types.DATE:    return 10;
-    case Types.TIME:    return 8;
-    }
-    typeStr = typeStr.toLowerCase();
-    int i1 = typeStr.indexOf('(');
-    if (i1 > 0) {
-        ++i1;
-        int i2 = typeStr.indexOf(',', i1);
-        if (i2 < 0) {
-        i2 = typeStr.indexOf(')', i1);
-        }
-        if (i2 - i1 > 0) {
-        String num = typeStr.substring(i1, i2);
-        try {
-            m = java.lang.Integer.parseInt(num, 10);
-        } catch (NumberFormatException e) {
-        }
-        }
-    }
-    return m;
-    }
-
-    static int getD(String typeStr, int type) {
-    int d = 0;
-    switch (type) {
-    case Types.INTEGER:    d = 10; break;
-    case Types.SMALLINT:    d = 5;  break;
-    case Types.FLOAT:    d = 24; break;
-    case Types.DOUBLE:    d = 53; break;
-    default:        return getM(typeStr, type);
-    }
-    typeStr = typeStr.toLowerCase();
-    int i1 = typeStr.indexOf('(');
-    if (i1 > 0) {
-        ++i1;
-        int i2 = typeStr.indexOf(',', i1);
-        if (i2 < 0) {
-        return getM(typeStr, type);
-        }
-        i1 = i2;
-        i2 = typeStr.indexOf(')', i1);
-        if (i2 - i1 > 0) {
-        String num = typeStr.substring(i1, i2);
-        try {
-            d = java.lang.Integer.parseInt(num, 10);
-        } catch (NumberFormatException e) {
-        }
-        }
-    }
-    return d;
-    }
-
-    public boolean supportsSavepoints() {
-    return false;
-    }
-
-    public boolean supportsNamedParameters() {
-    return false;
-    }
-
-    public boolean supportsMultipleOpenResults() {
-    return false;
-    }
-
-    public boolean supportsGetGeneratedKeys() {
-    return false;
-    }
-
-    public boolean supportsResultSetHoldability(int x) {
-    return false;
-    }
-
-    public boolean supportsStatementPooling() {
-    return false;
-    }
-
-    public boolean locatorsUpdateCopy() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public ResultSet getSuperTypes(String catalog, String schemaPattern,
-                String typeNamePattern)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public ResultSet getSuperTables(String catalog, String schemaPattern,
-                    String tableNamePattern)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public ResultSet getAttributes(String catalog, String schemaPattern,
-                   String typeNamePattern,
-                   String attributeNamePattern)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getResultSetHoldability() throws SQLException {
-    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-    }
-
-    public int getDatabaseMajorVersion() {
-    return SQLite.JDBCDriver.MAJORVERSION;
-    }
-
-    public int getDatabaseMinorVersion() {
-    return SQLite.JDBCDriver.MINORVERSION;
-    }
-
-    public int getJDBCMajorVersion() {
-    return 1;
-    }
-    
-    public int getJDBCMinorVersion() {
-    return 0;
-    }
-
-    public int getSQLStateType() throws SQLException {
-    return sqlStateXOpen;
-    }
-
-}
diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java b/sql/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java
deleted file mode 100644
index ab81867..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java
+++ /dev/null
@@ -1,752 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.*;
-import java.math.BigDecimal;
-import java.util.*;
-
-class BatchArg {
-    String arg;
-    boolean blob;
-
-    BatchArg(String arg, boolean blob) {
-    if (arg == null) {
-        this.arg = null;
-    } else {
-        this.arg = new String(arg);
-    }
-    this.blob = blob;
-    }
-}
-
-public class JDBCPreparedStatement extends JDBCStatement
-    implements java.sql.PreparedStatement {
-
-    private String sql;
-    private String args[];
-    private boolean blobs[];
-    private ArrayList<BatchArg> batch;
-    private static final boolean nullrepl =
-    SQLite.Database.version().compareTo("2.5.0") < 0;
-
-    public JDBCPreparedStatement(JDBCConnection conn, String sql) {
-    super(conn);
-    this.args = null;
-    this.blobs = null;
-    this.batch = null;
-    this.sql = fixup(sql);
-    }
-
-    private String fixup(String sql) {
-    StringBuffer sb = new StringBuffer();
-    boolean inq = false;
-    int nparm = 0;
-    for (int i = 0; i < sql.length(); i++) {
-        char c = sql.charAt(i);
-        if (c == '\'') {
-        if (inq) {
-                    char nextChar = 0;
-                    if(i + 1 < sql.length()) {
-                        nextChar = sql.charAt(i + 1);
-                    }
-            if (nextChar == '\'') {
-                        sb.append(c);
-                        sb.append(nextChar);
-                        i++;
-                    } else {
-            inq = false;
-                        sb.append(c);
-                    }
-        } else {
-            inq = true;
-                    sb.append(c);
-        }
-        } else if (c == '?') {
-        if (inq) {
-            sb.append(c);
-        } else {
-            ++nparm;
-            sb.append(nullrepl ? "'%q'" : "%Q");
-        }
-        } else if (c == ';') {
-        if (!inq) {
-            break;
-        }
-        sb.append(c);
-        } else if (c == '%') {
-        sb.append("%%");
-        } else {
-        sb.append(c);
-        }
-    }
-    args = new String[nparm];
-    blobs = new boolean[nparm];
-    try {
-        clearParameters();
-    } catch (SQLException e) {
-    }
-    return sb.toString();
-    }
-
-    private String fixup2(String sql) {
-    if (!conn.db.is3()) {
-        return sql;
-    }
-    StringBuffer sb = new StringBuffer();
-    int parm = -1;
-    for (int i = 0; i < sql.length(); i++) {
-        char c = sql.charAt(i);
-        if (c == '%') {
-        sb.append(c);
-        ++i;
-        c = sql.charAt(i);
-        if (c == 'Q') {
-            parm++;
-            if (blobs[parm]) {
-            c = 's';
-            }
-        }
-        }
-        sb.append(c);
-    }
-    return sb.toString();
-    }
-
-    public ResultSet executeQuery() throws SQLException {
-    return executeQuery(fixup2(sql), args, false);
-    }
-
-    public int executeUpdate() throws SQLException {
-    executeQuery(fixup2(sql), args, true);
-    return updcnt;
-    }
-
-    public void setNull(int parameterIndex, int sqlType) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = nullrepl ? "" : null;
-    blobs[parameterIndex - 1] = false;
-    }
-    
-    public void setBoolean(int parameterIndex, boolean x)
-    throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = x ? "1" : "0";
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setByte(int parameterIndex, byte x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = "" + x;
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setShort(int parameterIndex, short x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = "" + x;
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setInt(int parameterIndex, int x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = "" + x;
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setLong(int parameterIndex, long x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = "" + x;
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setFloat(int parameterIndex, float x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = "" + x;
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setDouble(int parameterIndex, double x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    args[parameterIndex - 1] = "" + x;
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setBigDecimal(int parameterIndex, BigDecimal x)
-    throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        args[parameterIndex - 1] = "" + x;
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setString(int parameterIndex, String x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        args[parameterIndex - 1] = x;
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setBytes(int parameterIndex, byte x[]) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    blobs[parameterIndex - 1] = false;
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        if (conn.db.is3()) {
-        args[parameterIndex - 1] = SQLite.StringEncoder.encodeX(x);
-        blobs[parameterIndex - 1] = true;
-        } else {
-        args[parameterIndex - 1] = SQLite.StringEncoder.encode(x);
-        }
-    }
-    }
-
-    public void setDate(int parameterIndex, java.sql.Date x)
-    throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        args[parameterIndex - 1] = x.toString();
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setTime(int parameterIndex, java.sql.Time x) 
-    throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        args[parameterIndex - 1] = x.toString();
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setTimestamp(int parameterIndex, java.sql.Timestamp x)
-    throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        args[parameterIndex - 1] = x.toString();
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setAsciiStream(int parameterIndex, java.io.InputStream x,
-                   int length) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    @Deprecated
-    public void setUnicodeStream(int parameterIndex, java.io.InputStream x, 
-                 int length) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setBinaryStream(int parameterIndex, java.io.InputStream x,
-                int length) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void clearParameters() throws SQLException {
-    for (int i = 0; i < args.length; i++) {
-        args[i] = nullrepl ? "" : null;
-        blobs[i] = false;
-    }
-    }
-
-    public void setObject(int parameterIndex, Object x, int targetSqlType,
-              int scale) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        if (x instanceof byte[]) {
-        byte[] bx = (byte[]) x;
-        if (conn.db.is3()) {
-            args[parameterIndex - 1] =
-              SQLite.StringEncoder.encodeX(bx);
-            blobs[parameterIndex - 1] = true;
-            return;
-        }
-        args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx);
-        } else {
-        args[parameterIndex - 1] = x.toString();
-        }
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setObject(int parameterIndex, Object x, int targetSqlType)
-    throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        if (x instanceof byte[]) {
-        byte[] bx = (byte[]) x;
-        if (conn.db.is3()) {
-            args[parameterIndex - 1] =
-            SQLite.StringEncoder.encodeX(bx);
-            blobs[parameterIndex - 1] = true;
-            return;
-        }
-        args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx);
-        } else {
-        args[parameterIndex - 1] = x.toString();
-        }
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public void setObject(int parameterIndex, Object x) throws SQLException {
-    if (parameterIndex < 1 || parameterIndex > args.length) {
-        throw new SQLException("bad parameter index");
-    }
-    if (x == null) {
-        args[parameterIndex - 1] = nullrepl ? "" : null;
-    } else {
-        if (x instanceof byte[]) {
-        byte[] bx = (byte[]) x;
-        if (conn.db.is3()) {
-            args[parameterIndex - 1] =
-            SQLite.StringEncoder.encodeX(bx);
-            blobs[parameterIndex - 1] = true;
-            return;
-        }
-        args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx);
-        } else {
-        args[parameterIndex - 1] = x.toString();
-        }
-    }
-    blobs[parameterIndex - 1] = false;
-    }
-
-    public boolean execute() throws SQLException {
-    return executeQuery(fixup2(sql), args, false) != null;
-    }
-
-    public void addBatch() throws SQLException {
-    if (batch == null) {
-        batch = new ArrayList<BatchArg>(args.length);
-    }
-    for (int i = 0; i < args.length; i++) {
-        batch.add(new BatchArg(args[i], blobs[i]));
-    }
-    }
-
-    public int[] executeBatch() throws SQLException {
-    if (batch == null) {
-        return new int[0];
-    }
-    int[] ret = new int[batch.size() / args.length];
-    for (int i = 0; i < ret.length; i++) {
-        ret[i] = EXECUTE_FAILED;
-    }
-    int errs = 0;
-    int index = 0;
-    for (int i = 0; i < ret.length; i++) {
-        for (int k = 0; k < args.length; k++) {
-        BatchArg b = (BatchArg) batch.get(index++);
-
-        args[i] = b.arg;
-        blobs[i] = b.blob;
-        }
-        try {
-        ret[i] = executeUpdate();
-        } catch (SQLException e) {
-        ++errs;
-        }
-    }
-    if (errs > 0) {
-        throw new BatchUpdateException("batch failed", ret);
-    }
-    return ret;
-    }
-
-    public void clearBatch() throws SQLException {
-    if (batch != null) {
-        batch.clear();
-        batch = null;
-    }
-    }
-
-    public void setCharacterStream(int parameterIndex,
-                   java.io.Reader reader,
-                   int length) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setRef(int i, Ref x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setBlob(int i, Blob x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setClob(int i, Clob x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setArray(int i, Array x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public ResultSetMetaData getMetaData() throws SQLException {
-    return rs.getMetaData();
-    }
-
-    public void setDate(int parameterIndex, java.sql.Date x, Calendar cal)
-    throws SQLException {
-    setDate(parameterIndex, x);
-    }
-
-    public void setTime(int parameterIndex, java.sql.Time x, Calendar cal)
-    throws SQLException {
-    setTime(parameterIndex, x);
-    }
-
-    public void setTimestamp(int parameterIndex, java.sql.Timestamp x,
-                 Calendar cal) throws SQLException {
-    setTimestamp(parameterIndex, x);
-    }
-
-    public void setNull(int parameterIndex, int sqlType, String typeName)
-    throws SQLException {
-    setNull(parameterIndex, sqlType);
-    }
-
-    public ParameterMetaData getParameterMetaData() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void registerOutputParameter(String parameterName, int sqlType)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void registerOutputParameter(String parameterName, int sqlType,
-                    int scale)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void registerOutputParameter(String parameterName, int sqlType,
-                    String typeName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.net.URL getURL(int parameterIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setURL(int parameterIndex, java.net.URL url)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setNull(String parameterName, int sqlType)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setBoolean(String parameterName, boolean val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setByte(String parameterName, byte val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setShort(String parameterName, short val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setInt(String parameterName, int val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setLong(String parameterName, long val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setFloat(String parameterName, float val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setDouble(String parameterName, double val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setBigDecimal(String parameterName, BigDecimal val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setString(String parameterName, String val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setBytes(String parameterName, byte val[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setDate(String parameterName, java.sql.Date val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setTime(String parameterName, java.sql.Time val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setTimestamp(String parameterName, java.sql.Timestamp val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setAsciiStream(String parameterName,
-                   java.io.InputStream s, int length)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setBinaryStream(String parameterName,
-                java.io.InputStream s, int length)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setObject(String parameterName, Object val, int targetSqlType,
-              int scale)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setObject(String parameterName, Object val, int targetSqlType)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setObject(String parameterName, Object val)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setCharacterStream(String parameterName,
-                   java.io.Reader r, int length)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setDate(String parameterName, java.sql.Date val,
-            Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setTime(String parameterName, java.sql.Time val,
-            Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setTimestamp(String parameterName, java.sql.Timestamp val,
-                 Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setNull(String parameterName, int sqlType, String typeName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public String getString(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean getBoolean(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public byte getByte(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public short getShort(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getInt(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public long getLong(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public float getFloat(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public double getDouble(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public byte[] getBytes(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Date getDate(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Time getTime(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Timestamp getTimestamp(String parameterName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Object getObject(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Object getObject(int parameterIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public BigDecimal getBigDecimal(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Object getObject(String parameterName, Map map)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Object getObject(int parameterIndex, Map map)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Ref getRef(int parameterIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Ref getRef(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Blob getBlob(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Blob getBlob(int parameterIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Clob getClob(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Clob getClob(int parameterIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Array getArray(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Array getArray(int parameterIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Date getDate(String parameterName, Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Date getDate(int parameterIndex, Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Time getTime(String parameterName, Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Time getTime(int parameterIndex, Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Timestamp getTimestamp(int parameterIndex, Calendar cal)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.net.URL getURL(String parameterName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-}
diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCResultSet.java b/sql/src/main/java/SQLite/JDBC2y/JDBCResultSet.java
deleted file mode 100644
index 06384eb..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/JDBCResultSet.java
+++ /dev/null
@@ -1,932 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.*;
-import java.math.BigDecimal;
-
-public class JDBCResultSet implements java.sql.ResultSet {
-
-    /**
-     * Current row to be retrieved.
-     */
-    private int row;
-
-    /**
-     * Table returned by Database.get_table()
-     */
-    protected SQLite.TableResult tr;
-
-    /**
-     * Statement from which result set was produced.
-     */
-    private JDBCStatement s;
-
-    /**
-     * Meta data for result set or null.
-     */
-    private JDBCResultSetMetaData m;
-
-    /**
-     * Last result cell retrieved or null.
-     */
-    private String lastg;
-
-
-    public JDBCResultSet(SQLite.TableResult tr, JDBCStatement s) {
-    this.tr = tr;
-    this.s = s;
-    this.m = null;
-    this.lastg = null;
-    this.row = -1;
-    }
-
-    public boolean next() throws SQLException {
-    if (tr == null) {
-        return false;
-    }
-    row++;
-    return row < tr.nrows;
-    }
-
-    public int findColumn(String columnName) throws SQLException {
-    JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
-    return m.findColByName(columnName);
-    }
-  
-    public int getRow() throws SQLException {
-    if (tr == null) {
-        throw new SQLException("no rows");
-    }
-    return row + 1;
-    }
-
-    public boolean previous() throws SQLException {
-    if (tr == null) {
-        return false;
-    }
-    if (row >= 0) {
-        row--;
-    }
-    return row >= 0;
-    }
-
-    public boolean absolute(int row) throws SQLException {
-    if (tr == null) {
-        return false;
-    }
-    if (row < 0) {
-        row = tr.nrows + 1 + row;
-    }
-    row--;
-    if (row < 0 || row > tr.nrows) {
-        return false;
-    }
-    this.row = row;
-    return true;
-    }
-
-    public boolean relative(int row) throws SQLException {
-    if (tr == null) {
-        return false;
-    }
-    if (this.row + row < 0 || this.row + row >= tr.nrows) {
-        return false;
-    }
-    this.row += row;
-    return true;
-    }
-
-    public void setFetchDirection(int dir) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getFetchDirection() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setFetchSize(int fsize) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getFetchSize() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public String getString(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    return lastg;
-    }
-
-    public String getString(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getString(col);
-    }
-
-    public int getInt(int columnIndex) throws SQLException {
-    Integer i = internalGetInt(columnIndex);
-    if (i != null) {
-        return i.intValue();
-    }
-    return 0;
-    }
-
-    private Integer internalGetInt(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return Integer.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public int getInt(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getInt(col);
-    }
-
-    public boolean getBoolean(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean getBoolean(String columnName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public ResultSetMetaData getMetaData() throws SQLException {
-    if (m == null) {
-        m = new JDBCResultSetMetaData(this);
-    }
-    return m;
-    }
-
-    public short getShort(int columnIndex) throws SQLException {
-    Short s = internalGetShort(columnIndex);
-    if (s != null) {
-        return s.shortValue();
-    }
-    return 0;
-    }
-
-    private Short internalGetShort(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return Short.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public short getShort(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getShort(col);
-    }
-
-    public java.sql.Time getTime(int columnIndex) throws SQLException {
-    return internalGetTime(columnIndex, null);
-    }
-
-    private java.sql.Time internalGetTime(int columnIndex,
-                      java.util.Calendar cal)
-    throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return java.sql.Time.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public java.sql.Time getTime(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getTime(col);
-    }
-
-    public java.sql.Time getTime(int columnIndex, java.util.Calendar cal)
-    throws SQLException {
-    return internalGetTime(columnIndex, cal);
-    }
-
-    public java.sql.Time getTime(String columnName, java.util.Calendar cal)
-    throws SQLException{
-    int col = findColumn(columnName);
-    return getTime(col, cal);
-    }
-
-    public java.sql.Timestamp getTimestamp(int columnIndex)
-    throws SQLException{
-    return internalGetTimestamp(columnIndex, null);
-    }
-
-    private java.sql.Timestamp internalGetTimestamp(int columnIndex,
-                            java.util.Calendar cal)
-    throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return java.sql.Timestamp.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public java.sql.Timestamp getTimestamp(String columnName)
-    throws SQLException{
-    int col = findColumn(columnName);
-    return getTimestamp(col);
-    }
-
-    public java.sql.Timestamp getTimestamp(int columnIndex,
-                       java.util.Calendar cal)
-    throws SQLException {
-    return internalGetTimestamp(columnIndex, cal);
-    }
-
-    public java.sql.Timestamp getTimestamp(String columnName,
-                       java.util.Calendar cal)
-    throws SQLException {
-    int col = findColumn(columnName);
-    return getTimestamp(col, cal);
-    }
-
-    public java.sql.Date getDate(int columnIndex) throws SQLException {
-    return internalGetDate(columnIndex, null);
-    }
-
-    private java.sql.Date internalGetDate(int columnIndex,
-                      java.util.Calendar cal)
-    throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return java.sql.Date.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public java.sql.Date getDate(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getDate(col);
-    }
-
-    public java.sql.Date getDate(int columnIndex, java.util.Calendar cal)
-    throws SQLException{
-    return internalGetDate(columnIndex, cal);
-    }
-
-    public java.sql.Date getDate(String columnName, java.util.Calendar cal)
-    throws SQLException{
-    int col = findColumn(columnName);
-    return getDate(col, cal);
-    }
-
-    public double getDouble(int columnIndex) throws SQLException {
-    Double d = internalGetDouble(columnIndex);
-    if (d != null) {
-        return d.doubleValue();
-    }
-    return 0;
-    }
-
-    private Double internalGetDouble(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return  Double.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-    
-    public double getDouble(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getDouble(col);
-    }
-
-    public float getFloat(int columnIndex) throws SQLException {
-    Float f = internalGetFloat(columnIndex);
-    if (f != null) {
-        return f.floatValue();
-    }
-    return 0;
-    }
-
-    private Float internalGetFloat(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return Float.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public float getFloat(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getFloat(col);
-    }
-
-    public long getLong(int columnIndex) throws SQLException {
-    Long l = internalGetLong(columnIndex);
-    if (l != null) {
-        return l.longValue();
-    }
-    return 0;
-    }
-
-    private Long internalGetLong(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    try {
-        return Long.valueOf(lastg);
-    } catch (java.lang.Exception e) {
-        lastg = null;
-    }
-    return null;
-    }
-
-    public long getLong(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getLong(col);
-    }
-
-    @Deprecated
-    public java.io.InputStream getUnicodeStream(int columnIndex)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    @Deprecated
-    public java.io.InputStream getUnicodeStream(String columnName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.io.InputStream getAsciiStream(String columnName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.io.InputStream getAsciiStream(int columnIndex)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public BigDecimal getBigDecimal(String columnName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    @Deprecated
-    public BigDecimal getBigDecimal(String columnName, int scale)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    @Deprecated
-    public BigDecimal getBigDecimal(int columnIndex, int scale)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.io.InputStream getBinaryStream(int columnIndex)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.io.InputStream getBinaryStream(String columnName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public byte getByte(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public byte getByte(String columnName) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public byte[] getBytes(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    byte ret[] = null;
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    if (lastg != null) {
-        ret = SQLite.StringEncoder.decode(lastg);
-    }
-    return ret;
-    }
-
-    public byte[] getBytes(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getBytes(col);
-    }
-
-    public String getCursorName() throws SQLException {
-    return null;
-    }
-
-    public Object getObject(int columnIndex) throws SQLException {
-    if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
-        throw new SQLException("column " + columnIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[columnIndex - 1];
-    Object ret = lastg;
-    if (tr instanceof TableResultX) {
-        switch (((TableResultX) tr).sql_type[columnIndex - 1]) {
-        case Types.SMALLINT:
-        ret = internalGetShort(columnIndex);
-        break;
-        case Types.INTEGER:
-        ret = internalGetInt(columnIndex);
-        break;
-        case Types.DOUBLE:
-        ret = internalGetDouble(columnIndex);
-        break;
-        case Types.FLOAT:
-        ret = internalGetFloat(columnIndex);
-        break;
-        case Types.BIGINT:
-        ret = internalGetLong(columnIndex);
-        break;
-        case Types.BINARY:
-        case Types.VARBINARY:
-        case Types.LONGVARBINARY:
-        ret = getBytes(columnIndex);
-        break;
-        case Types.NULL:
-        ret = null;
-        break;
-        /* defaults to String below */
-        }
-    }
-    return ret;
-    }
-
-    public Object getObject(String columnName) throws SQLException {
-    int col = findColumn(columnName);
-    return getObject(col);
-    }
-
-    public Object getObject(int columnIndex, java.util.Map map) 
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Object getObject(String columnIndex, java.util.Map map)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Ref getRef(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Ref getRef(String columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Blob getBlob(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Blob getBlob(String columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Clob getClob(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Clob getClob(String columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Array getArray(int columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.sql.Array getArray(String columnIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.io.Reader getCharacterStream(int columnIndex)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public java.io.Reader getCharacterStream(String columnName)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public SQLWarning getWarnings() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean wasNull() throws SQLException {
-    return lastg == null;
-    }
-    
-    public void clearWarnings() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean isFirst() throws SQLException {
-    if (tr == null) {
-        return true;
-    }
-    return row == 0;
-    }
-
-    public boolean isBeforeFirst() throws SQLException {
-    if (tr == null || tr.nrows <= 0) {
-        return false;
-    }
-    return row < 0;
-    }
-
-    public void beforeFirst() throws SQLException {
-    if (tr == null) {
-        return;
-    }
-    row = -1;
-    }
-
-    public boolean first() throws SQLException {
-    if (tr == null || tr.nrows <= 0) {
-        return false;
-    }
-    row = 0;
-    return true;
-    }
-
-    public boolean isAfterLast() throws SQLException {
-    if (tr == null || tr.nrows <= 0) {
-        return false;
-    }
-    return row >= tr.nrows;
-    }
-
-    public void afterLast() throws SQLException {
-    if (tr == null) {
-        return;
-    }
-    row = tr.nrows;
-    }
-
-    public boolean isLast() throws SQLException {
-    if (tr == null) {
-        return true;
-    }
-    return row == tr.nrows - 1;
-    }
-
-    public boolean last() throws SQLException {
-    if (tr == null || tr.nrows <= 0) {
-        return false;
-    }
-    row = tr.nrows -1;
-    return true;
-    }
-
-    public int getType() throws SQLException {
-    return TYPE_SCROLL_INSENSITIVE;
-    }
-
-    public int getConcurrency() throws SQLException {
-    return CONCUR_READ_ONLY;
-    }
-
-    public boolean rowUpdated() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean rowInserted() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean rowDeleted() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void insertRow() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateRow() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void deleteRow() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void refreshRow() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void cancelRowUpdates() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void moveToInsertRow() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void moveToCurrentRow() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateNull(int colIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBoolean(int colIndex, boolean b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateByte(int colIndex, byte b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateShort(int colIndex, short b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateInt(int colIndex, int b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateLong(int colIndex, long b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateFloat(int colIndex, float f) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateDouble(int colIndex, double f) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBigDecimal(int colIndex, BigDecimal f)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateString(int colIndex, String s) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBytes(int colIndex, byte[] s) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateDate(int colIndex, java.sql.Date d) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateTime(int colIndex, java.sql.Time t) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateTimestamp(int colIndex, java.sql.Timestamp t)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateAsciiStream(int colIndex, java.io.InputStream in, int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBinaryStream(int colIndex, java.io.InputStream in, int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateCharacterStream(int colIndex, java.io.Reader in, int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateObject(int colIndex, Object obj) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateObject(int colIndex, Object obj, int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateNull(String colIndex) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBoolean(String colIndex, boolean b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateByte(String colIndex, byte b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateShort(String colIndex, short b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateInt(String colIndex, int b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateLong(String colIndex, long b) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateFloat(String colIndex, float f) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateDouble(String colIndex, double f) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBigDecimal(String colIndex, BigDecimal f)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateString(String colIndex, String s) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBytes(String colIndex, byte[] s) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateDate(String colIndex, java.sql.Date d)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateTime(String colIndex, java.sql.Time t)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateTimestamp(String colIndex, java.sql.Timestamp t)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateAsciiStream(String colIndex, java.io.InputStream in,
-                  int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBinaryStream(String colIndex, java.io.InputStream in,
-                   int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateCharacterStream(String colIndex, java.io.Reader in,
-                      int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateObject(String colIndex, Object obj)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateObject(String colIndex, Object obj, int s)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public Statement getStatement() throws SQLException {
-    if (s == null) {
-        throw new SQLException("stale result set");
-    }
-    return s;
-    }
-
-    public void close() throws SQLException {
-    s = null;
-    tr = null;
-    lastg = null;
-    row = -1;
-    }
-
-    public java.net.URL getURL(int colIndex) throws SQLException {
-    if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
-        throw new SQLException("column " + colIndex + " not found");
-    }
-    String rd[] = (String []) tr.rows.elementAt(row);
-    lastg = rd[colIndex - 1];
-    java.net.URL url = null;
-    if (lastg == null) {
-        return url;
-    }
-    try {
-        url = new java.net.URL(lastg);
-    } catch (java.lang.Exception e) {
-        url = null;
-    }
-    return url;
-    }
-
-    public java.net.URL getURL(String colIndex) throws SQLException {
-    int col = findColumn(colIndex);
-    return getURL(col);
-    }
-
-    public void updateRef(int colIndex, java.sql.Ref x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateRef(String colIndex, java.sql.Ref x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBlob(int colIndex, java.sql.Blob x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateBlob(String colIndex, java.sql.Blob x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateClob(int colIndex, java.sql.Clob x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateClob(String colIndex, java.sql.Clob x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateArray(int colIndex, java.sql.Array x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void updateArray(String colIndex, java.sql.Array x)
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-}
diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java b/sql/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java
deleted file mode 100644
index 934ca78..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java
+++ /dev/null
@@ -1,212 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.*;
-
-public class JDBCResultSetMetaData implements java.sql.ResultSetMetaData {
-
-    private JDBCResultSet r;
-    
-    public JDBCResultSetMetaData(JDBCResultSet r) {
-    this.r = r;
-    }
- 
-    public String getCatalogName(int column) throws java.sql.SQLException {
-    return null;
-    }
-
-    public String getColumnClassName(int column) throws java.sql.SQLException {
-    column--;
-    if (r != null && r.tr != null) {
-        if (column < 0 || column >= r.tr.ncolumns) {
-        return null;
-        }
-        if (r.tr instanceof TableResultX) {
-        switch (((TableResultX) r.tr).sql_type[column]) {
-        case Types.SMALLINT:    return "java.lang.Short";
-        case Types.INTEGER:    return "java.lang.Integer";
-        case Types.DOUBLE:    return "java.lang.Double";
-        case Types.FLOAT:    return "java.lang.Float";
-        case Types.BIGINT:    return "java.lang.Long";
-        case Types.DATE:    return "java.sql.Date";
-        case Types.TIME:    return "java.sql.Time";
-        case Types.TIMESTAMP:    return "java.sql.Timestamp";
-        case Types.BINARY:
-        case Types.VARBINARY:    return "[B";
-        /* defaults to varchar below */
-        }
-        }
-        return "java.lang.String";
-    }
-    return null;
-    }
-
-    public int getColumnCount() throws java.sql.SQLException {
-    if (r != null && r.tr != null) {
-        return r.tr.ncolumns;
-    }
-    return 0;
-    }
-
-    public int getColumnDisplaySize(int column) throws java.sql.SQLException {
-    return 0;
-    }
-
-    public String getColumnLabel(int column) throws java.sql.SQLException {
-    column--;
-    String c = null;
-    if (r != null && r.tr != null) {
-        if (column < 0 || column >= r.tr.ncolumns) {
-        return c;
-        }
-        c = r.tr.column[column];
-    }
-    return c;
-    }
-
-    public String getColumnName(int column) throws java.sql.SQLException {
-    column--;
-    String c = null;
-    if (r != null && r.tr != null) {
-        if (column < 0 || column >= r.tr.ncolumns) {
-        return c;
-        }
-        c = r.tr.column[column];
-        if (c != null) {
-        int i = c.indexOf('.');
-        if (i > 0) {
-            return c.substring(i + 1);
-        }
-        }
-    }
-    return c;
-    }
-
-    public int getColumnType(int column) throws java.sql.SQLException {
-    column--;
-    if (r != null && r.tr != null) {
-        if (column >= 0 && column < r.tr.ncolumns) {
-        if (r.tr instanceof TableResultX) {
-            return ((TableResultX) r.tr).sql_type[column];
-        }
-        return Types.VARCHAR;
-        }
-    }
-    throw new SQLException("bad column index");
-    }
-
-    public String getColumnTypeName(int column) throws java.sql.SQLException {
-    column--;
-    if (r != null && r.tr != null) {
-        if (column >= 0 && column < r.tr.ncolumns) {
-        if (r.tr instanceof TableResultX) {
-            switch (((TableResultX) r.tr).sql_type[column]) {
-            case Types.SMALLINT:    return "smallint";
-            case Types.INTEGER:        return "integer";
-            case Types.DOUBLE:        return "double";
-            case Types.FLOAT:        return "float";
-            case Types.BIGINT:        return "bigint";
-            case Types.DATE:        return "date";
-            case Types.TIME:        return "time";
-            case Types.TIMESTAMP:    return "timestamp";
-            case Types.BINARY:        return "binary";
-            case Types.VARBINARY:    return "varbinary";
-            /* defaults to varchar below */
-            }
-        }
-        return "varchar";
-        }
-    }
-    throw new SQLException("bad column index");
-    }
-
-    public int getPrecision(int column) throws java.sql.SQLException {
-    return 0;
-    }
-
-    public int getScale(int column) throws java.sql.SQLException {
-    return 0;
-    }
-
-    public String getSchemaName(int column) throws java.sql.SQLException {
-    return null;
-    }
-
-    public String getTableName(int column) throws java.sql.SQLException {
-    column--;
-    String c = null;
-    if (r != null && r.tr != null) {
-        if (column < 0 || column >= r.tr.ncolumns) {
-        return c;
-        }
-        c = r.tr.column[column];
-        if (c != null) {
-        int i = c.indexOf('.');
-        if (i > 0) {
-            return c.substring(0, i);
-        }
-        c = null;
-        }
-    }
-    return c;
-    }
-
-    public boolean isAutoIncrement(int column) throws java.sql.SQLException {
-    return false;
-    }
-
-    public boolean isCaseSensitive(int column) throws java.sql.SQLException {
-    return false;
-    }
-
-    public boolean isCurrency(int column) throws java.sql.SQLException {
-    return false;
-    }
-
-    public boolean isDefinitelyWritable(int column) 
-    throws java.sql.SQLException {
-    return true;
-    }
-
-    public int isNullable(int column) throws java.sql.SQLException {
-    return columnNullableUnknown;
-    }
-
-    public boolean isReadOnly(int column) throws java.sql.SQLException {
-    return false;
-    }
-
-    public boolean isSearchable(int column) throws java.sql.SQLException {
-    return true;
-    }
-
-    public boolean isSigned(int column) throws java.sql.SQLException {
-    return false;
-    }
-
-    public boolean isWritable(int column) throws java.sql.SQLException {
-    return true;
-    }
-
-    int findColByName(String columnName) throws java.sql.SQLException {
-    String c = null;
-    if (r != null && r.tr != null) {
-        for (int i = 0; i < r.tr.ncolumns; i++) {
-        c = r.tr.column[i];
-        if (c != null) {
-            if (c.compareToIgnoreCase(columnName) == 0) {
-            return i + 1;
-            }
-            int k = c.indexOf('.');
-            if (k > 0) {
-            c = c.substring(k + 1);
-            if (c.compareToIgnoreCase(columnName) == 0) {
-                return i + 1;
-            }
-            }
-        }
-        c = null;
-        }
-    }
-    throw new SQLException("column " + columnName + " not found");
-    }
-}
diff --git a/sql/src/main/java/SQLite/JDBC2y/JDBCStatement.java b/sql/src/main/java/SQLite/JDBC2y/JDBCStatement.java
deleted file mode 100644
index 99d12d3..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/JDBCStatement.java
+++ /dev/null
@@ -1,287 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.*;
-import java.util.*;
-
-public class JDBCStatement implements java.sql.Statement {
-
-    protected JDBCConnection conn;
-    protected JDBCResultSet rs;
-    protected int updcnt;
-    private ArrayList<String> batch;
-
-    public JDBCStatement(JDBCConnection conn) {
-    this.conn = conn;
-    this.updcnt = 0;
-    this.rs = null;
-    this.batch = null;    
-    }
-
-    public void setFetchSize(int fetchSize) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getFetchSize() throws SQLException {
-    return 1;
-    }
-
-    public int getMaxRows() throws SQLException {
-    return 0;
-    }
-
-    public void setMaxRows(int max) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setFetchDirection(int fetchDirection) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getFetchDirection() throws SQLException {
-    return ResultSet.FETCH_UNKNOWN;
-    }
-
-    public int getResultSetConcurrency() throws SQLException {
-    return ResultSet.CONCUR_READ_ONLY;
-    }
-
-    public int getResultSetType() throws SQLException {
-    return ResultSet.TYPE_SCROLL_INSENSITIVE;
-    }
-
-    public void setQueryTimeout(int seconds) throws SQLException {
-    conn.timeout = seconds * 1000;
-    if (conn.timeout < 0) {
-        conn.timeout = 120000;
-    } else if (conn.timeout < 1000) {
-        conn.timeout = 5000;
-    }
-    }
-
-    public int getQueryTimeout() throws SQLException {
-    return conn.timeout;
-    }
-
-    public ResultSet getResultSet() throws SQLException {
-    return rs;
-    }
-
-    ResultSet executeQuery(String sql, String args[], boolean updonly)
-    throws SQLException {
-    SQLite.TableResult tr = null;
-    if (rs != null) {
-        rs.close();
-        rs = null;
-    }
-    updcnt = -1;
-    if (conn == null || conn.db == null) {
-        throw new SQLException("stale connection");
-    }
-    int busy = 0;
-    boolean starttrans = !conn.autocommit && !conn.intrans;
-    while (true) {
-        try {
-        if (starttrans) {
-            conn.db.exec("BEGIN TRANSACTION", null);
-            conn.intrans = true;
-        }
-        if (args == null) {
-            if (updonly) {
-            conn.db.exec(sql, null);
-            } else {
-            tr = conn.db.get_table(sql);
-            }
-        } else {
-            if (updonly) {
-            conn.db.exec(sql, null, args);
-            } else {
-            tr = conn.db.get_table(sql, args);
-            }
-        }
-        updcnt = (int) conn.db.changes();
-        } catch (SQLite.Exception e) {
-        if (conn.db.is3() &&
-            conn.db.last_error() == SQLite.Constants.SQLITE_BUSY &&
-            conn.busy3(conn.db, ++busy)) {
-            try {
-            if (starttrans && conn.intrans) {
-                conn.db.exec("ROLLBACK", null);
-                conn.intrans = false;
-            }
-            } catch (SQLite.Exception ee) {
-            }
-            try {
-            int ms = 20 + busy * 10;
-            if (ms > 1000) {
-                ms = 1000;
-            }
-            synchronized (this) {
-                this.wait(ms);
-            }
-            } catch (java.lang.Exception eee) {
-            }
-            continue;
-        }
-        throw new SQLException(e.toString());
-        }
-        break;
-    }
-    if (!updonly && tr == null) {
-        throw new SQLException("no result set produced");
-    }
-    if (!updonly && tr != null) {
-        rs = new JDBCResultSet(new TableResultX(tr), this);
-    }
-    return rs;
-    }
-
-    public ResultSet executeQuery(String sql) throws SQLException {
-    return executeQuery(sql, null, false);
-    }
-
-    public boolean execute(String sql) throws SQLException {
-    return executeQuery(sql) != null;
-    }
-
-    public void cancel() throws SQLException {
-    if (conn == null || conn.db == null) {
-        throw new SQLException("stale connection");
-    }
-    conn.db.interrupt();
-    }
-
-    public void clearWarnings() throws SQLException {
-    }
-
-    public Connection getConnection() throws SQLException {
-    return conn;
-    }
-
-    public void addBatch(String sql) throws SQLException {
-    if (batch == null) {
-        batch = new ArrayList<String>(1);
-    }
-    batch.add(sql);
-    }
-
-    public int[] executeBatch() throws SQLException {
-    if (batch == null) {
-        return new int[0];
-    }
-    int[] ret = new int[batch.size()];
-    for (int i = 0; i < ret.length; i++) {
-        ret[i] = EXECUTE_FAILED;
-    }
-    int errs = 0;
-    for (int i = 0; i < ret.length; i++) {
-        try {
-        execute((String) batch.get(i));
-        ret[i] = updcnt;
-        } catch (SQLException e) {
-        ++errs;
-        }
-    }
-    if (errs > 0) {
-        throw new BatchUpdateException("batch failed", ret);
-    }
-    return ret;
-    }
-
-    public void clearBatch() throws SQLException {
-    if (batch != null) {
-        batch.clear();
-        batch = null;
-    }
-    }
-
-    public void close() throws SQLException {
-    clearBatch();
-    conn = null;
-    }
-
-    public int executeUpdate(String sql) throws SQLException {
-    executeQuery(sql, null, true);
-    return updcnt;
-    }
-
-    public int getMaxFieldSize() throws SQLException {
-    return 0;
-    }
-
-    public boolean getMoreResults() throws SQLException {
-    if (rs != null) {
-        rs.close();
-        rs = null;
-    }
-    return false;
-    }
-
-    public int getUpdateCount() throws SQLException {
-    return updcnt;
-    }
-
-    public SQLWarning getWarnings() throws SQLException {
-    return null;
-    }
-
-    public void setCursorName(String name) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setEscapeProcessing(boolean enable) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public void setMaxFieldSize(int max) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean getMoreResults(int x) throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public ResultSet getGeneratedKeys() throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int executeUpdate(String sql, int autokeys)
-    throws SQLException {
-    if (autokeys != Statement.NO_GENERATED_KEYS) {
-        throw new SQLException("not supported");
-    }
-    return executeUpdate(sql);
-    }
-
-    public int executeUpdate(String sql, int colIndexes[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int executeUpdate(String sql, String colIndexes[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean execute(String sql, int autokeys)
-    throws SQLException {
-    if (autokeys != Statement.NO_GENERATED_KEYS) {
-        throw new SQLException("not supported");
-    }
-    return execute(sql);
-    }
-
-    public boolean execute(String sql, int colIndexes[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public boolean execute(String sql, String colIndexes[])
-    throws SQLException {
-    throw new SQLException("not supported");
-    }
-
-    public int getResultSetHoldability() throws SQLException {
-    return ResultSet.HOLD_CURSORS_OVER_COMMIT;
-    }
-
-}
diff --git a/sql/src/main/java/SQLite/JDBC2y/TableResultX.java b/sql/src/main/java/SQLite/JDBC2y/TableResultX.java
deleted file mode 100644
index 205372f..0000000
--- a/sql/src/main/java/SQLite/JDBC2y/TableResultX.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package SQLite.JDBC2y;
-
-import java.sql.Types;
-import java.util.Vector;
-
-public class TableResultX extends SQLite.TableResult {
-    public int sql_type[];
-
-    public TableResultX() {
-    super();
-    sql_type = new int[this.ncolumns];
-    for (int i = 0; i < this.ncolumns; i++) {
-        sql_type[i] = Types.VARCHAR;
-    }
-    }
-
-    public TableResultX(SQLite.TableResult tr) {
-    this.column = tr.column;
-    this.rows = tr.rows;
-    this.ncolumns = tr.ncolumns;
-    this.nrows = tr.nrows;
-    this.types = tr.types;
-    sql_type = new int[tr.ncolumns];
-    for (int i = 0; i < this.ncolumns; i++) {
-        sql_type[i] = Types.VARCHAR;
-    }
-    if (tr.types != null) {
-        for (int i = 0; i < tr.types.length; i++) {
-        sql_type[i] = JDBCDatabaseMetaData.mapSqlType(tr.types[i]);
-        }
-    }    
-    }
-
-    void sql_types(int types[]) {
-    sql_type = types;
-    } 
-}
diff --git a/sql/src/main/java/SQLite/JDBCDriver.java b/sql/src/main/java/SQLite/JDBCDriver.java
deleted file mode 100644
index 63b95ee..0000000
--- a/sql/src/main/java/SQLite/JDBCDriver.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package SQLite;
-
-import java.sql.*;
-import java.util.Properties;
-
-public class JDBCDriver implements java.sql.Driver {
-
-    public static final int MAJORVERSION = 1;
-    public static final int MINORVERSION = 2;
-
-    private static java.lang.reflect.Constructor makeConn = null;
-
-    protected Connection conn;
-
-    static {
-    try {
-        Class connClass = null;
-        Class args[] = new Class[2];
-        args[0] = Class.forName("java.lang.String");
-        args[1] = args[0];
-        String jvers = java.lang.System.getProperty("java.version");
-        String cvers;
-        if (jvers == null || jvers.startsWith("1.0")) {
-        throw new java.lang.Exception("unsupported java version");
-        } else if (jvers.startsWith("1.1")) {
-        cvers = "SQLite.JDBC1.JDBCConnection";
-        } else if (jvers.startsWith("1.2") || jvers.startsWith("1.3")) {
-        cvers = "SQLite.JDBC2.JDBCConnection";
-        } else if (jvers.startsWith("1.4")) {
-        cvers = "SQLite.JDBC2x.JDBCConnection";
-        } else if (jvers.startsWith("1.5")) {
-        cvers = "SQLite.JDBC2y.JDBCConnection";
-        try {
-            Class.forName(cvers);
-        } catch (java.lang.Exception e) {
-            cvers = "SQLite.JDBC2x.JDBCConnection";
-        }
-        } else {
-        cvers = "SQLite.JDBC2z.JDBCConnection";
-        try {
-            Class.forName(cvers);
-        } catch (java.lang.Exception e) {
-            cvers = "SQLite.JDBC2y.JDBCConnection";
-            try {
-            Class.forName(cvers);
-            } catch (java.lang.Exception ee) {
-            cvers = "SQLite.JDBC2x.JDBCConnection";
-            }
-        }
-        }
-        connClass = Class.forName(cvers);
-        makeConn = connClass.getConstructor(args);
-        java.sql.DriverManager.registerDriver(new JDBCDriver());
-    } catch (java.lang.Exception e) {
-        System.err.println(e);
-    }
-    }
-
-    public JDBCDriver() {
-    }
-    
-    public boolean acceptsURL(String url) throws SQLException {
-    return url.startsWith("sqlite:/") ||
-        url.startsWith("jdbc:sqlite:/");
-    }
-
-    public Connection connect(String url, Properties info)
-    throws SQLException {
-    if (!acceptsURL(url)) {
-        return null;
-    }
-    Object args[] = new Object[2];
-    args[0] = url;
-    if (info != null) {
-        args[1] = info.getProperty("encoding");
-    }
-    if (args[1] == null) {
-        args[1] = java.lang.System.getProperty("SQLite.encoding");
-    }
-    try {
-        conn = (Connection) makeConn.newInstance(args);
-    } catch (java.lang.reflect.InvocationTargetException ie) {
-        throw new SQLException(ie.getTargetException().toString());
-    } catch (java.lang.Exception e) {
-        throw new SQLException(e.toString());
-    }
-    return conn;
-    }
-
-    public int getMajorVersion() {
-    return MAJORVERSION;
-    }
-
-    public int getMinorVersion() {
-    return MINORVERSION;
-    }
-
-    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
-    throws SQLException {
-    DriverPropertyInfo p[] = new DriverPropertyInfo[1];
-    DriverPropertyInfo pp = new DriverPropertyInfo("encoding", "");
-    p[0] = pp;
-    return p;
-    }
-
-    public boolean jdbcCompliant() {
-    return false;
-    }
-}
diff --git a/sql/src/main/java/SQLite/Shell.java b/sql/src/main/java/SQLite/Shell.java
deleted file mode 100644
index 78d37a1..0000000
--- a/sql/src/main/java/SQLite/Shell.java
+++ /dev/null
@@ -1,669 +0,0 @@
-package SQLite;
-
-import SQLite.*;
-import java.io.*;
-import java.util.*;
-
-/**
- * SQLite command line shell. This is a partial reimplementaion
- * of sqlite/src/shell.c and can be invoked by:<P>
- *
- * <verb>
- *     java SQLite.Shell [OPTIONS] database [SHELLCMD]
- * or
- *     java -jar sqlite.jar [OPTIONS] database [SHELLCMD]
- * </verb>
- */
-
-public class Shell implements Callback {
-    Database db;
-    boolean echo;
-    int count;
-    int mode;
-    boolean showHeader;
-    String tableName;
-    String sep;
-    String cols[];
-    int colwidth[];
-    String destTable;
-    PrintWriter pw;
-    PrintWriter err;
-
-    static final int MODE_Line = 0;
-    static final int MODE_Column = 1;
-    static final int MODE_List = 2;
-    static final int MODE_Semi = 3;
-    static final int MODE_Html = 4;
-    static final int MODE_Insert = 5;
-    static final int MODE_Insert2 = 6;
-
-    public Shell(PrintWriter pw, PrintWriter err) {
-    this.pw = pw;
-    this.err = err;
-    }
-
-    public Shell(PrintStream ps, PrintStream errs) {
-    pw = new PrintWriter(ps);
-    err = new PrintWriter(errs);
-    }
-
-    protected Object clone() {
-        Shell s = new Shell(this.pw, this.err);
-    s.db = db;
-    s.echo = echo;
-    s.mode = mode;
-    s.count = 0;
-    s.showHeader = showHeader;
-    s.tableName = tableName;
-    s.sep = sep;
-    s.colwidth = colwidth;
-    return s;
-    }
-
-    static public String sql_quote_dbl(String str) {
-    if (str == null) {
-        return "NULL";
-    }
-    int i, single = 0, dbl = 0;
-    for (i = 0; i < str.length(); i++) {
-        if (str.charAt(i) == '\'') {
-        single++;
-        } else if (str.charAt(i) == '"') {
-        dbl++;
-        }
-    }
-    if (dbl == 0) {
-        return "\"" + str + "\"";
-    }
-    StringBuffer sb = new StringBuffer("\"");
-    for (i = 0; i < str.length(); i++) {
-        char c = str.charAt(i);
-        if (c == '"') {
-        sb.append("\"\"");
-        } else {
-        sb.append(c);
-        }
-    }
-    return sb.toString();
-    }
-
-    static public String sql_quote(String str) {
-    if (str == null) {
-        return "NULL";
-    }
-    int i, single = 0, dbl = 0;
-    for (i = 0; i < str.length(); i++) {
-        if (str.charAt(i) == '\'') {
-        single++;
-        } else if (str.charAt(i) == '"') {
-        dbl++;
-        }
-    }
-    if (single == 0) {
-        return "'" + str + "'";
-    }
-    if (dbl == 0) {
-        return "\"" + str + "\"";
-    }
-    StringBuffer sb = new StringBuffer("'");
-    for (i = 0; i < str.length(); i++) {
-        char c = str.charAt(i);
-        if (c == '\'') {
-        sb.append("''");
-        } else {
-        sb.append(c);
-        }
-    }
-    return sb.toString();
-    }
-
-    static String html_quote(String str) {
-    if (str == null) {
-        return "NULL";
-    }
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < str.length(); i++) {
-        char c = str.charAt(i);
-        if (c == '<') {
-        sb.append("&lt;");
-        } else if (c == '>') {
-        sb.append("&gt;");
-        } else if (c == '&') {
-        sb.append("&amp;");
-        } else {
-        int x = c;
-        if (x < 32 || x > 127) {
-            sb.append("&#" + x + ";");
-        } else {
-            sb.append(c);
-        }
-        }
-    }
-    return sb.toString();
-    }
-
-    static boolean is_numeric(String str) {
-    try {
-        Double d = Double.valueOf(str);
-    } catch (java.lang.Exception e) {
-        return false;
-    }
-    return true;
-    }
-
-    void set_table_name(String str) {
-    if (str == null) {
-        tableName = "";
-        return;
-    }
-    tableName = Shell.sql_quote(str);
-    }
-
-    public void columns(String args[]) {
-    cols = args;
-    }
-
-    public void types(String args[]) {
-    /* Empty body to satisfy SQLite.Callback interface. */
-    }
-
-    public boolean newrow(String args[]) {
-    int i;
-    String tname;
-    switch (mode) {
-    case Shell.MODE_Line:
-        if (args.length == 0) {
-        break;
-        }
-        if (count++ > 0) {
-        pw.println("");
-        }
-        for (i = 0; i < args.length; i++) {
-        pw.println(cols[i] + " = " +
-               args[i] == null ? "NULL" : args[i]);
-        }
-        break;
-    case Shell.MODE_Column:
-        String csep = "";
-        if (count++ == 0) {
-        colwidth = new int[args.length];
-        for (i = 0; i < args.length; i++) {
-            int w, n;
-            w = cols[i].length();
-            if (w < 10) {
-            w = 10;
-            }
-            colwidth[i] = w;
-            if (showHeader) {
-            pw.print(csep + cols[i]);
-            csep = " ";
-            }
-        }
-        if (showHeader) {
-            pw.println("");
-        }
-        }
-        if (args.length == 0) {
-        break;
-        }
-        csep = "";
-        for (i = 0; i < args.length; i++) {
-        pw.print(csep + (args[i] == null ? "NULL" : args[i]));
-        csep = " ";
-        }
-        pw.println("");
-        break;
-    case Shell.MODE_Semi:
-    case Shell.MODE_List:
-        if (count++ == 0 && showHeader) {
-        for (i = 0; i < args.length; i++) {
-            pw.print(cols[i] +
-                 (i == args.length - 1 ? "\n" : sep));
-        }
-        }
-        if (args.length == 0) {
-        break;
-        }
-        for (i = 0; i < args.length; i++) {
-        pw.print(args[i] == null ? "NULL" : args[i]);
-        if (mode == Shell.MODE_Semi) {
-            pw.print(";");
-        } else if (i < args.length - 1) {
-            pw.print(sep);
-        }
-        }
-        pw.println("");
-        break;
-    case MODE_Html:
-        if (count++ == 0 && showHeader) {
-        pw.print("<TR>");
-        for (i = 0; i < args.length; i++) {
-            pw.print("<TH>" + html_quote(cols[i]) + "</TH>");
-        }
-        pw.println("</TR>");
-        }
-        if (args.length == 0) {
-        break;
-        }
-        pw.print("<TR>");
-        for (i = 0; i < args.length; i++) {
-        pw.print("<TD>" + html_quote(args[i]) + "</TD>");
-        }
-        pw.println("</TR>");
-        break;
-    case MODE_Insert:
-        if (args.length == 0) {
-        break;
-        }
-        tname = tableName;
-        if (destTable != null) {
-            tname = destTable;
-        }
-        pw.print("INSERT INTO " + tname + " VALUES(");
-        for (i = 0; i < args.length; i++) {
-            String tsep = i > 0 ? "," : "";
-        if (args[i] == null) {
-            pw.print(tsep + "NULL");
-        } else if (is_numeric(args[i])) {
-            pw.print(tsep + args[i]);
-        } else {
-            pw.print(tsep + sql_quote(args[i]));
-        }
-        }
-        pw.println(");");
-        break;
-    case MODE_Insert2:
-        if (args.length == 0) {
-        break;
-        }
-        tname = tableName;
-        if (destTable != null) {
-            tname = destTable;
-        }
-        pw.print("INSERT INTO " + tname + " VALUES(");
-        for (i = 0; i < args.length; i++) {
-            String tsep = i > 0 ? "," : "";
-        pw.print(tsep + args[i]);
-        }
-        pw.println(");");
-        break;
-    }
-    return false;
-    }
-
-    void do_meta(String line) {
-        StringTokenizer st = new StringTokenizer(line.toLowerCase());
-    int n = st.countTokens();
-    if (n <= 0) {
-        return;
-    }
-    String cmd = st.nextToken();
-    String args[] = new String[n - 1];
-    int i = 0;
-    while (st.hasMoreTokens()) {
-        args[i] = st.nextToken();
-        ++i;
-    }
-    if (cmd.compareTo(".dump") == 0) {
-        new DBDump(this, args);
-        return;
-    }
-    if (cmd.compareTo(".echo") == 0) {
-        if (args.length > 0 &&
-        (args[0].startsWith("y") || args[0].startsWith("on"))) {
-        echo = true;
-        }
-        return;
-    }
-    if (cmd.compareTo(".exit") == 0) {
-        try {
-        db.close();
-        } catch (Exception e) {
-        }
-        System.exit(0);
-    }
-    if (cmd.compareTo(".header") == 0) {
-        if (args.length > 0 &&
-        (args[0].startsWith("y") || args[0].startsWith("on"))) {
-        showHeader = true;
-        }
-        return;
-    }
-    if (cmd.compareTo(".help") == 0) {
-        pw.println(".dump ?TABLE? ...  Dump database in text fmt");
-        pw.println(".echo ON|OFF       Command echo on or off");
-        pw.println(".enc ?NAME?        Change encoding");
-        pw.println(".exit              Exit program");
-        pw.println(".header ON|OFF     Display headers on or off");
-        pw.println(".help              This message");
-        pw.println(".mode MODE         Set output mode to\n" +
-               "                   line, column, insert\n" +
-               "                   list, or html");
-        pw.println(".mode insert TABLE Generate SQL insert stmts");
-        pw.println(".schema ?PATTERN?  List table schema");
-        pw.println(".separator STRING  Set separator string");
-        pw.println(".tables ?PATTERN?  List table names");
-        return;
-    }
-    if (cmd.compareTo(".mode") == 0) {
-        if (args.length > 0) {
-        if (args[0].compareTo("line") == 0) {
-            mode = Shell.MODE_Line;
-        } else if (args[0].compareTo("column") == 0) {
-            mode = Shell.MODE_Column;
-        } else if (args[0].compareTo("list") == 0) {
-            mode = Shell.MODE_List;
-        } else if (args[0].compareTo("html") == 0) {
-            mode = Shell.MODE_Html;
-        } else if (args[0].compareTo("insert") == 0) {
-            mode = Shell.MODE_Insert;
-            if (args.length > 1) {
-            destTable = args[1];
-            }
-        }
-        }
-        return;
-    }
-    if (cmd.compareTo(".separator") == 0) {
-        if (args.length > 0) {
-        sep = args[0];
-        }
-        return;
-    }
-    if (cmd.compareTo(".tables") == 0) {
-        TableResult t = null;
-        if (args.length > 0) {
-        try {
-            String qarg[] = new String[1];
-            qarg[0] = args[0];
-            t = db.get_table("SELECT name FROM sqlite_master " +
-                     "WHERE type='table' AND " +
-                     "name LIKE '%%%q%%' " +
-                     "ORDER BY name", qarg);
-        } catch (Exception e) {
-            err.println("SQL Error: " + e);
-            err.flush();
-        }
-        } else {
-        try {
-            t = db.get_table("SELECT name FROM sqlite_master " +
-                     "WHERE type='table' ORDER BY name");
-        } catch (Exception e) {
-            err.println("SQL Error: " + e);
-            err.flush();
-        }
-        }
-        if (t != null) {
-        for (i = 0; i < t.nrows; i++) {
-            String tab = ((String[]) t.rows.elementAt(i))[0];
-            if (tab != null) {
-            pw.println(tab);
-            }
-        }
-        }
-        return;
-    }
-    if (cmd.compareTo(".schema") == 0) {
-        if (args.length > 0) {
-        try {
-            String qarg[] = new String[1];
-            qarg[0] = args[0];
-            db.exec("SELECT sql FROM sqlite_master " +
-                "WHERE type!='meta' AND " +
-                "name LIKE '%%%q%%' AND " +
-                "sql NOTNULL " +
-                "ORDER BY type DESC, name",
-                this, qarg);
-        } catch (Exception e) {
-            err.println("SQL Error: " + e);
-            err.flush();
-        }
-        } else {
-        try {
-            db.exec("SELECT sql FROM sqlite_master " +
-                "WHERE type!='meta' AND " +
-                "sql NOTNULL " +
-                "ORDER BY tbl_name, type DESC, name",
-                this);
-        } catch (Exception e) {
-            err.println("SQL Error: " + e);
-            err.flush();
-        }
-        }
-        return;
-    }
-    if (cmd.compareTo(".enc") == 0) {
-        try {
-        db.set_encoding(args.length > 0 ? args[0] : null);
-        } catch (Exception e) {
-        err.println("" + e);
-        err.flush();
-        }
-        return;
-    }
-    err.println("Unknown command '" + cmd + "'");
-    err.flush();
-    }
-
-    String read_line(BufferedReader is, String prompt) {
-    try {
-        if (prompt != null) {
-        pw.print(prompt);
-        pw.flush();
-        }
-        String line = is.readLine();
-        return line;
-    } catch (IOException e) {
-        return null;
-    }
-    }
-
-    void do_input(BufferedReader is) {
-    String line, sql = null;
-    String prompt = "SQLITE> ";
-    while ((line = read_line(is, prompt)) != null) {
-        if (echo) {
-        pw.println(line);
-        }
-        if (line.length() > 0 && line.charAt(0) == '.') {
-            do_meta(line);
-        } else {
-        if (sql == null) {
-            sql = line;
-        } else {
-            sql = sql + " " + line;
-        }
-        if (Database.complete(sql)) {
-            try {
-            db.exec(sql, this);
-            } catch (Exception e) {
-            if (!echo) {
-                err.println(sql);
-            }
-            err.println("SQL Error: " + e);
-            err.flush();
-            }
-            sql = null;
-            prompt = "SQLITE> ";
-        } else {
-            prompt = "SQLITE? ";
-        }
-        }
-        pw.flush();
-    }
-    if (sql != null) {
-        err.println("Incomplete SQL: " + sql);
-        err.flush();
-    }
-    }
-
-    void do_cmd(String sql) {
-        if (db == null) {
-        return;
-    }
-        if (sql.length() > 0 && sql.charAt(0) == '.') {
-        do_meta(sql);
-    } else {
-        try {
-            db.exec(sql, this);
-        } catch (Exception e) {
-        err.println("SQL Error: " + e);
-        err.flush();
-        }
-    }
-    }
-
-    public static void main(String args[]) {
-    Shell s = new Shell(System.out, System.err);
-    s.mode = Shell.MODE_List;
-    s.sep = "|";
-    s.showHeader = false;
-    s.db = new Database();
-    String dbname = null, sql = null;
-    for (int i = 0; i < args.length; i++) {
-        if(args[i].compareTo("-html") ==0) {
-        s.mode = Shell.MODE_Html;
-        } else if (args[i].compareTo("-list") == 0) {
-        s.mode = Shell.MODE_List;
-        } else if (args[i].compareTo("-line") == 0) {
-        s.mode = Shell.MODE_Line;
-        } else if (i < args.length - 1 &&
-               args[i].compareTo("-separator") == 0) {
-        ++i;
-        s.sep = args[i];
-        } else if (args[i].compareTo("-header") == 0) {
-        s.showHeader = true;
-        } else if (args[i].compareTo("-noheader") == 0) {
-        s.showHeader = false;
-        } else if (args[i].compareTo("-echo") == 0) {
-        s.echo = true;
-        } else if (dbname == null) {
-        dbname = args[i];
-        } else if (sql == null) {
-        sql = args[i];
-        } else {
-        System.err.println("Arguments: ?OPTIONS? FILENAME ?SQL?");
-        System.exit(1);
-        }
-    }
-    if (dbname == null) {
-        System.err.println("No database file given");
-        System.exit(1);
-    }
-    try {
-        s.db.open(dbname, 0);
-    } catch (Exception e) {
-        System.err.println("Unable to open database: " + e);
-        System.exit(1);
-    }
-    if (sql != null) {
-        s.do_cmd(sql);
-    } else {
-        // BEGIN android-modified
-        BufferedReader is =
-            new BufferedReader(new InputStreamReader(System.in), 8192);
-        // END android-modified
-        s.do_input(is);
-    }
-    try {
-        s.db.close();
-    } catch (Exception ee) {
-    }
-    }
-}
-
-/**
- * Internal class for dumping an entire database.
- * It contains a special callback interface to traverse the
- * tables of the current database and output create SQL statements
- * and for the data insert SQL statements.
- */
-
-class DBDump implements Callback {
-    Shell s;
-
-    DBDump(Shell s, String tables[]) {
-        this.s = s;
-    s.pw.println("BEGIN TRANSACTION;");
-        if (tables == null || tables.length == 0) {
-        try {
-            s.db.exec("SELECT name, type, sql FROM sqlite_master " +
-              "WHERE type!='meta' AND sql NOT NULL " +
-              "ORDER BY substr(type,2,1), name", this);
-        } catch (Exception e) {
-            s.err.println("SQL Error: " + e);
-        s.err.flush();
-        }
-    } else {
-        String arg[] = new String[1];
-        for (int i = 0; i < tables.length; i++) {
-            arg[0] = tables[i];
-        try {
-            s.db.exec("SELECT name, type, sql FROM sqlite_master " +
-                  "WHERE tbl_name LIKE '%q' AND type!='meta' " +
-                  " AND sql NOT NULL " +
-                  " ORDER BY substr(type,2,1), name",
-                  this, arg);
-        } catch (Exception e) {
-            s.err.println("SQL Error: " + e);
-            s.err.flush();
-        }
-        }
-    }
-    s.pw.println("COMMIT;");
-    }
-
-    public void columns(String col[]) {
-    /* Empty body to satisfy SQLite.Callback interface. */
-    }
-
-    public void types(String args[]) {
-    /* Empty body to satisfy SQLite.Callback interface. */
-    }
-
-    public boolean newrow(String args[]) {
-        if (args.length != 3) {
-        return true;
-    }
-    s.pw.println(args[2] + ";");
-    if (args[1].compareTo("table") == 0) {
-        Shell s2 = (Shell) s.clone();
-        s2.mode = Shell.MODE_Insert;
-        s2.set_table_name(args[0]);
-        String qargs[] = new String[1];
-        qargs[0] = args[0];
-        try {
-            if (s2.db.is3()) {
-            TableResult t = null;
-            t = s2.db.get_table("PRAGMA table_info('%q')", qargs);
-            String query;
-            if (t != null) {
-                StringBuffer sb = new StringBuffer();
-            String sep = "";
-
-            sb.append("SELECT ");
-            for (int i = 0; i < t.nrows; i++) {
-                String col = ((String[]) t.rows.elementAt(i))[1];
-                sb.append(sep + "quote(" +
-                      Shell.sql_quote_dbl(col) + ")");
-                sep = ",";
-            }
-            sb.append(" from '%q'");
-            query = sb.toString();
-            s2.mode = Shell.MODE_Insert2;
-            } else {
-                query = "SELECT * from '%q'";
-            }
-            s2.db.exec(query, s2, qargs);
-        } else {
-            s2.db.exec("SELECT * from '%q'", s2, qargs);
-        }
-        } catch (Exception e) {
-            s.err.println("SQL Error: " + e);
-        s.err.flush();
-        return true;
-        }
-    }
-    return false;
-    }
-}
diff --git a/sql/src/main/java/SQLite/StringEncoder.java b/sql/src/main/java/SQLite/StringEncoder.java
deleted file mode 100644
index c2f20ad..0000000
--- a/sql/src/main/java/SQLite/StringEncoder.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package SQLite;
-
-/**
- * String encoder/decoder for SQLite.
- *
- * This module was kindly donated by Eric van der Maarel of Nedap N.V.
- *
- * This encoder was implemented based on an original idea from an anonymous
- * author in the source code of the SQLite distribution.
- * I feel obliged to provide a quote from the original C-source code:
- *
- * "The author disclaims copyright to this source code.  In place of
- *  a legal notice, here is a blessing:
- *
- *     May you do good and not evil.
- *     May you find forgiveness for yourself and forgive others.
- *     May you share freely, never taking more than you give."
- *
- */
-
-public class StringEncoder {
-
-    /**
-     * Encodes the given byte array into a string that can be used by
-     * the SQLite database. The database cannot handle null (0x00) and
-     * the character '\'' (0x27). The encoding consists of escaping
-     * these characters with a reserved character (0x01). The escaping
-     * is applied after determining and applying a shift that minimizes
-     * the number of escapes required.
-     * With this encoding the data of original size n is increased to a
-     * maximum of 1+(n*257)/254.
-     * For sufficiently large n the overhead is thus less than 1.2%.
-     * @param a the byte array to be encoded. A null reference is handled as
-     *     an empty array.
-     * @return the encoded bytes as a string. When an empty array is
-     *     provided a string of length 1 is returned, the value of
-     *     which is bogus.
-     *     When decoded with this class' <code>decode</code> method
-     *     a string of size 1 will return an empty byte array.
-     */
-
-    public static String encode(byte[] a) {
-    // check input
-    if (a == null || a.length == 0) {
-        // bogus shift, no data
-        return "x";
-    }
-    // determine count
-    int[] cnt = new int[256];
-    for (int i = 0 ; i < a.length; i++) {
-        cnt[a[i] & 0xff]++;
-    }
-    // determine shift for minimum number of escapes
-    int shift = 1;
-    int nEscapes = a.length;
-    for (int i = 1; i < 256; i++) {
-        if (i == '\'') {
-        continue;
-        }
-        int sum = cnt[i] + cnt[(i + 1) & 0xff] + cnt[(i + '\'') & 0xff];
-        if (sum < nEscapes) {
-        nEscapes = sum;
-        shift = i;
-        if (nEscapes == 0) {
-            // cannot become smaller
-            break;
-        }
-        }
-    }
-    // construct encoded output
-    int outLen = a.length + nEscapes + 1;
-    StringBuffer out = new StringBuffer(outLen);
-    out.append((char)shift);
-    for (int i = 0; i < a.length; i++) {
-        // apply shift
-        char c = (char)((a[i] - shift)&0xff);
-        // insert escapes
-        if (c == 0) { // forbidden
-        out.append((char)1);
-        out.append((char)1);
-        } else if (c == 1) { // escape character
-        out.append((char)1);
-        out.append((char)2);
-        } else if (c == '\'') { // forbidden
-        out.append((char)1);
-        out.append((char)3);
-        } else {
-        out.append(c);
-        }
-    }
-    return out.toString();
-    }
-
-    /**
-     * Decodes the given string that is assumed to be a valid encoding
-     * of a byte array. Typically the given string is generated by
-     * this class' <code>encode</code> method.
-     * @param s the given string encoding.
-     * @return the byte array obtained from the decoding.
-     * @throws IllegalArgumentException when the string given is not
-     *    a valid encoded string for this encoder.
-     */
-
-    public static byte[] decode(String s) {
-    char[] a = s.toCharArray();
-    if (a.length > 2 && a[0] == 'X' &&
-        a[1] == '\'' && a[a.length-1] == '\'') {
-        // SQLite3 BLOB syntax
-        byte[] result = new byte[(a.length-3)/2];
-        for (int i = 2, k = 0; i < a.length - 1; i += 2, k++) {
-        byte tmp = (byte) (a[i] - '0');
-        if (tmp > 15) {
-            tmp -= 0x20;
-        }
-        result[k] = (byte) (tmp << 4);
-        tmp = (byte) (a[i+1] - '0');
-        if (tmp > 15) {
-            tmp -= 0x20;
-        }
-        result[k] |= tmp;
-        }
-        return result;
-    }
-    // first element is the shift
-    byte[] result = new byte[a.length-1];
-    int i = 0;
-    int shift = s.charAt(i++);
-    int j = 0;
-    while (i < s.length()) {
-        int c;
-        if ((c = s.charAt(i++)) == 1) { // escape character found
-        if ((c = s.charAt(i++)) == 1) {
-            c = 0;
-        } else if (c == 2) {
-            c = 1;
-        } else if (c == 3) {
-            c = '\'';
-        } else {
-            throw new IllegalArgumentException(
-            "invalid string passed to decoder: " + j);
-        }
-        }
-        // do shift
-        result[j++] = (byte)((c + shift) & 0xff);
-    }
-    int outLen = j;
-    // provide array of correct length
-    if (result.length != outLen) {
-        result = byteCopy(result, 0, outLen, new byte[outLen]);
-    }
-    return result;
-    }
-
-    /**
-     * Copies count elements from source, starting at element with
-     * index offset, to the given target.
-     * @param source the source.
-     * @param offset the offset.
-     * @param count the number of elements to be copied.
-     * @param target the target to be returned.
-     * @return the target being copied to.
-     */
-
-    private static byte[] byteCopy(byte[] source, int offset,
-                   int count, byte[] target) {
-    for (int i = offset, j = 0; i < offset + count; i++, j++) {
-        target[j] = source[i];
-    }
-    return target;
-    }
-
-
-    static final char[] xdigits = {
-    '0', '1', '2', '3', '4', '5', '6', '7',
-    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-    };
-
-    /**
-     * Encodes the given byte array into SQLite3 blob notation, ie X'..'
-     * @param a the byte array to be encoded. A null reference is handled as
-     *     an empty array.
-     * @return the encoded bytes as a string.
-     */
-
-    public static String encodeX(byte[] a) {
-    // check input
-    if (a == null || a.length == 0) {
-        return "X''";
-    }
-    int outLen = a.length + 3;
-    StringBuffer out = new StringBuffer(outLen);
-    out.append('X');
-    out.append('\'');
-    for (int i = 0; i < a.length; i++) {
-        out.append(xdigits[a[i] >> 4]);
-        out.append(xdigits[a[i] & 0x0F]);
-    }
-    out.append('\'');
-    return out.toString();
-    }
-}
diff --git a/sql/src/main/java/SQLite/TableResult.java b/sql/src/main/java/SQLite/TableResult.java
deleted file mode 100644
index 1a7fb57..0000000
--- a/sql/src/main/java/SQLite/TableResult.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package SQLite;
-
-import java.util.Vector;
-
-/**
- * Class representing an SQLite result set as
- * returned by the
- * <A HREF="Database.html#get_table(java.lang.String)">Database.get_table</A>
- * convenience method.
- * <BR><BR>
- * Example:<BR>
- *
- * <PRE>
- *   ...
- *   SQLite.Database db = new SQLite.Database();
- *   db.open("db", 0);
- *   System.out.print(db.get_table("select * from TEST"));
- *   ...
- * </PRE>
- * Example output:<BR>
- *
- * <PRE>
- *   id|firstname|lastname|
- *   0|John|Doe|
- *   1|Speedy|Gonzales|
- *   ...
- * </PRE>
- */
-
-public class TableResult implements Callback {
-
-    /**
-     * Number of columns in the result set.
-     */
-
-    public int ncolumns;
-
-    /**
-     * Number of rows in the result set.
-     */
-
-    public int nrows;
-
-    /**
-     * Column names of the result set.
-     */
-
-    public String column[];
-
-    /**
-     * Types of columns of the result set or null.
-     */
-
-    public String types[];
-
-    /**
-     * Rows of the result set. Each row is stored as a String array.
-     */
-
-    public Vector rows;
-
-    /**
-     * Create an empty result set.
-     */
-
-    public TableResult() {
-    clear();
-    }
-
-    /**
-     * Clear result set.
-     */
-
-    public void clear() {
-    column = new String[0];
-    types = null;
-    rows = new Vector();
-    ncolumns = nrows = 0;
-    }
-
-    /**
-     * Callback method used while the query is executed.
-     */
-
-    public void columns(String coldata[]) {
-    column = coldata;
-    ncolumns = column.length;
-    }
-
-    /**
-     * Callback method used while the query is executed.
-     */
-
-    public void types(String types[]) {
-    this.types = types;
-    }
-
-    /**
-     * Callback method used while the query is executed.
-     */
-
-    public boolean newrow(String rowdata[]) {
-    if (rowdata != null) {
-        rows.addElement(rowdata);
-        nrows++;
-    }
-    return false;
-    }
-
-    /**
-     * Make String representation of result set.
-     */
-
-    public String toString() {
-    StringBuffer sb = new StringBuffer();
-    int i;
-    for (i = 0; i < ncolumns; i++) {
-        sb.append(column[i] == null ? "NULL" : column[i]);
-        sb.append('|');
-    }
-    sb.append('\n');
-    for (i = 0; i < nrows; i++) {
-        int k;
-        String row[] = (String[]) rows.elementAt(i);
-        for (k = 0; k < ncolumns; k++) {
-        sb.append(row[k] == null ? "NULL" : row[k]);
-        sb.append('|');
-        }
-        sb.append('\n');
-    }
-    return sb.toString();
-    }
-}
diff --git a/sql/src/main/java/java/sql/DriverManager.java b/sql/src/main/java/java/sql/DriverManager.java
index 1c41a46..8d3adde 100644
--- a/sql/src/main/java/java/sql/DriverManager.java
+++ b/sql/src/main/java/java/sql/DriverManager.java
@@ -17,20 +17,17 @@
 
 package java.sql;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import java.util.Enumeration;
-import java.util.Iterator;
+import dalvik.system.VMStack;
 import java.io.PrintStream;
 import java.io.PrintWriter;
-import java.util.Vector;
 import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.Vector;
 import org.apache.harmony.luni.util.PriviAction;
-import org.apache.harmony.sql.internal.nls.Messages;
-// BEGIN android-changed
-import dalvik.system.VMStack;
-// END android-changed
 
 /**
  * Provides facilities for managing JDBC drivers.
@@ -59,8 +56,7 @@
     private static final List<Driver> theDrivers = new ArrayList<Driver>(10);
 
     // Permission for setting log
-    private static final SQLPermission logPermission = new SQLPermission(
-            "setLog"); //$NON-NLS-1$
+    private static final SQLPermission logPermission = new SQLPermission("setLog");
 
     /*
      * Load drivers on initialization
@@ -75,7 +71,7 @@
      */
     private static void loadInitialDrivers() {
         String theDriverList = AccessController
-                .doPrivileged(new PriviAction<String>("jdbc.drivers", null)); //$NON-NLS-1$
+                .doPrivileged(new PriviAction<String>("jdbc.drivers", null));
 
         if (theDriverList == null) {
             return;
@@ -85,7 +81,7 @@
          * Get the names of the drivers as an array of Strings from the system
          * property by splitting the property at the separator character ':'
          */
-        String[] theDriverNames = theDriverList.split(":"); //$NON-NLS-1$
+        String[] theDriverNames = theDriverList.split(":");
 
         for (String element : theDriverNames) {
             try {
@@ -125,15 +121,10 @@
         if (driver == null) {
             return;
         }
-        // BEGIN android-changed
         ClassLoader callerClassLoader = VMStack.getCallingClassLoader();
-        // END android-changed
-
         if (!DriverManager.isClassFromClassLoader(driver, callerClassLoader)) {
-            // sql.1=DriverManager: calling class not authorized to deregister
-            // JDBC driver
-            throw new SecurityException(Messages.getString("sql.1")); //$NON-NLS-1$
-        } // end if
+            throw new SecurityException("calling class not authorized to deregister JDBC driver");
+        }
         synchronized (theDrivers) {
             theDrivers.remove(driver);
         }
@@ -172,14 +163,12 @@
      *             if there is an error while attempting to connect to the
      *             database identified by the URL.
      */
-    public static Connection getConnection(String url, Properties info)
-            throws SQLException {
+    public static Connection getConnection(String url, Properties info) throws SQLException {
         // 08 - connection exception
         // 001 - SQL-client unable to establish SQL-connection
-        String sqlState = "08001"; //$NON-NLS-1$
+        String sqlState = "08001";
         if (url == null) {
-            // sql.5=The url cannot be null
-            throw new SQLException(Messages.getString("sql.5"), sqlState); //$NON-NLS-1$
+            throw new SQLException("The url cannot be null", sqlState);
         }
         synchronized (theDrivers) {
             /*
@@ -195,8 +184,7 @@
             }
         }
         // If we get here, none of the drivers are able to resolve the URL
-        // sql.6=No suitable driver
-        throw new SQLException(Messages.getString("sql.6"), sqlState); //$NON-NLS-1$ 
+        throw new SQLException("No suitable driver", sqlState);
     }
 
     /**
@@ -218,10 +206,10 @@
             String password) throws SQLException {
         Properties theProperties = new Properties();
         if (null != user) {
-            theProperties.setProperty("user", user); //$NON-NLS-1$
+            theProperties.setProperty("user", user);
         }
         if (null != password) {
-            theProperties.setProperty("password", password); //$NON-NLS-1$
+            theProperties.setProperty("password", password);
         }
         return getConnection(url, theProperties);
     }
@@ -258,10 +246,9 @@
             }
         }
         // If no drivers understand the URL, throw an SQLException
-        // sql.6=No suitable driver
         // SQLState: 08 - connection exception
         // 001 - SQL-client unable to establish SQL-connection
-        throw new SQLException(Messages.getString("sql.6"), "08001"); //$NON-NLS-1$ //$NON-NLS-2$
+        throw new SQLException("No suitable driver", "08001");
     }
 
     /**
diff --git a/sql/src/main/java/java/sql/SQLWarning.java b/sql/src/main/java/java/sql/SQLWarning.java
index 3ef67f5..9089984 100644
--- a/sql/src/main/java/java/sql/SQLWarning.java
+++ b/sql/src/main/java/java/sql/SQLWarning.java
@@ -19,8 +19,6 @@
 
 import java.io.Serializable;
 
-import org.apache.harmony.sql.internal.nls.Messages;
-
 /**
  * An exception class that holds information about Database access warnings.
  */
@@ -95,7 +93,7 @@
         if (next instanceof SQLWarning) {
             return (SQLWarning) next;
         }
-        throw new Error(Messages.getString("sql.8")); //$NON-NLS-1$
+        throw new Error("SQLWarning chain holds value that is not a SQLWarning");
     }
 
     /**
diff --git a/sql/src/main/java/java/sql/Timestamp.java b/sql/src/main/java/java/sql/Timestamp.java
index f16d93a..9f5ef31 100644
--- a/sql/src/main/java/java/sql/Timestamp.java
+++ b/sql/src/main/java/java/sql/Timestamp.java
@@ -22,8 +22,6 @@
 import java.util.Date;
 import java.util.regex.Pattern;
 
-import org.apache.harmony.sql.internal.nls.Messages;
-
 /**
  * A Java representation of the SQL {@code TIMESTAMP} type. It provides the
  * capability of representing the SQL {@code TIMESTAMP} nanosecond value, in
@@ -51,7 +49,7 @@
     private int nanos;
 
     // The regex pattern of yyyy-mm-dd hh:mm:ss
-    private static final String TIME_FORMAT_REGEX = "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*"; //$NON-NLS-1$
+    private static final String TIME_FORMAT_REGEX = "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*";
 
     /**
      * Returns a {@code Timestamp} corresponding to the time specified by the
@@ -302,8 +300,7 @@
      */
     public void setNanos(int n) throws IllegalArgumentException {
         if ((n < 0) || (n > 999999999)) {
-            // sql.0=Value out of range
-            throw new IllegalArgumentException(Messages.getString("sql.0")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Value out of range");
         }
         nanos = n;
     }
@@ -379,7 +376,7 @@
         return sb.toString();
     }
 
-    private static final String PADDING = "000000000";  //$NON-NLS-1$
+    private static final String PADDING = "000000000";
 
     /* 
     * Private method to format the time 
@@ -407,17 +404,16 @@
      */
     public static Timestamp valueOf(String s) throws IllegalArgumentException {
         if (s == null) {
-            // sql.3=Argument cannot be null
-            throw new IllegalArgumentException(Messages.getString("sql.3")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Argument cannot be null");
         }
 
-        // omit trailing whitespaces
+        // omit trailing whitespace
         s = s.trim();
         if (!Pattern.matches(TIME_FORMAT_REGEX, s)) {
-            throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+            throw badTimestampString(s);
         }
 
-        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //$NON-NLS-1$
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         ParsePosition pp = new ParsePosition(0);
 
         /*
@@ -431,11 +427,11 @@
         try {
             theDate = df.parse(s, pp);
         } catch (Exception e) {
-            throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+            throw badTimestampString(s);
         }
 
         if (theDate == null) {
-            throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+            throw badTimestampString(s);
         }
 
         /*
@@ -458,23 +454,22 @@
              * Case where fraction of a second is specified: Require 1 character
              * plus the "." in the remaining part of the string...
              */
-            if ((s.length() - position) < ".n".length()) { //$NON-NLS-1$
-                throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+            if ((s.length() - position) < ".n".length()) {
+                throw badTimestampString(s);
             }
 
             /*
              * If we're strict, we should not allow any EXTRA characters after
              * the 9 digits
              */
-            if ((s.length() - position) > ".nnnnnnnnn".length()) { //$NON-NLS-1$
-                throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+            if ((s.length() - position) > ".nnnnnnnnn".length()) {
+                throw badTimestampString(s);
             }
 
             // Require the next character to be a "."
             if (s.charAt(position) != '.') {
-                // sql.4=Bad input string format: expected '.' not {0}
-                throw new NumberFormatException(Messages.getString(
-                        "sql.4", s.charAt(position))); //$NON-NLS-1$
+                throw new NumberFormatException("Bad input string format: expected '.' not '" +
+                        s.charAt(position) + "'");
             }
             // Get the length of the number string - need to account for the '.'
             int nanoLength = s.length() - position - 1;
@@ -486,19 +481,19 @@
              * We must adjust for the cases where the nanos String was not 9
              * characters long by padding out with zeros
              */
-            theNanoString = theNanoString + "000000000"; //$NON-NLS-1$
+            theNanoString = theNanoString + "000000000";
             theNanoString = theNanoString.substring(0, 9);
 
             try {
                 theNanos = Integer.parseInt(theNanoString);
             } catch (Exception e) {
                 // If we get here, the string was not a number
-                throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+                throw badTimestampString(s);
             }
         }
 
         if (theNanos < 0 || theNanos > 999999999) {
-            throw new IllegalArgumentException(Messages.getString("sql.2")); //$NON-NLS-1$
+            throw badTimestampString(s);
         }
 
         Timestamp theTimestamp = new Timestamp(theDate.getTime());
@@ -506,4 +501,9 @@
 
         return theTimestamp;
     }
+    
+    private static IllegalArgumentException badTimestampString(String s) {
+        throw new IllegalArgumentException("Timestamp format must be " +
+                "yyyy-mm-dd hh:mm:ss.fffffffff; was '" + s + "'");
+    }
 }
diff --git a/sql/src/main/java/javax/sql/package.html b/sql/src/main/java/javax/sql/package.html
index 6c9500f..7fdf1ce 100644
--- a/sql/src/main/java/javax/sql/package.html
+++ b/sql/src/main/java/javax/sql/package.html
@@ -4,6 +4,5 @@
       Provides extensions to the standard interface for accessing SQL-based
       databases.
     <p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/sql/src/main/java/org/apache/harmony/sql/internal/nls/Messages.java b/sql/src/main/java/org/apache/harmony/sql/internal/nls/Messages.java
deleted file mode 100644
index 234bdc9..0000000
--- a/sql/src/main/java/org/apache/harmony/sql/internal/nls/Messages.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.sql.internal.nls;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.sql.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.sql.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties b/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties
deleted file mode 100644
index 6927cf2..0000000
--- a/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties
+++ /dev/null
@@ -1,61 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-sql.0=Value out of range
-sql.1=DriverManager: calling class not authorized to deregister JDBC driver
-sql.2=Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff
-sql.3=Argument cannot be null
-sql.4=Bad input string format: expected '.' not {0}
-sql.5=The url cannot be null
-sql.6=No suitable driver
-sql.8=SQLWarning chain holds value that is not a SQLWarning
-sql.9=Cannot instantiate a SerialRef object with a null Ref object
-sql.10=Cannot instantiate a SerialRef object that returns a null base type name
-sql.11=SQLException: {0}
-sql.12=Cannot serialize empty URL instance
-sql.13=Cannot instantiate a SerialBlob object with a null Blob object
-sql.14=Invalid starting position or length
-sql.15=Invalid position in BLOB object set
-sql.16=Invalid offset in byte array set
-sql.17=javax.sql.rowset.serial.SerialException: Length more than what can be truncated
-sql.18=Unsupported operation. SerialBlob cannot return a writable binary stream, unless instantiated with a Blob object that provides a setBinaryStream() implementation
-sql.19=Cannot instantiate a SerialClob object with a null Clob object
-sql.20=Invalid Clob object. Calls to getCharacterStream or getAsciiStream return null which cannot be serialized.
-sql.21=Invalid position in CLOB object set
-sql.22=Invalid position and substring length
-sql.23=Buffer is not sufficient to hold the value
-sql.24=Invalid length for truncate
-sql.25=Unsupported operation. SerialClob is not instantiated with a fully implemented Clob object.
-sql.26=Invalid column count. Cannot be less or equal to zero
-sql.27=Invalid column index :{0}
-sql.28=Invalid SQL type for column
-sql.29=Invalid nullable constant set. Must be either columnNoNulls, columnNullable or columnNullableUnknown
-sql.30=Invalid column display size. Cannot be less than zero
-sql.31=Invalid precision value. Cannot be less than zero
-sql.32=Invalid scale size. Cannot be less than zero
-sql.33=Cannot instantiate a SQLOutputImpl instance with null parameters
-sql.34=Cannot instantiate a SQLInputImpl instance with null parameters
-sql.35=SQLInputImpl exception: Invalid read position
-sql.36=No more attributes
-sql.37=Operation not supported
-sql.38=Object is invalid
-sql.39=Cannot instantiate a SerialArray object with a null Array object
-sql.40=ClassNotFoundException: {0}
-sql.41=Invalid JNDI context supplied
-sql.42=Illegal Argument
-sql.43=The object is not serializable
-sql.44=No logger has been set
diff --git a/sql/src/main/native/sqlite_jni_registration.c b/sql/src/main/native/sqlite_jni_registration.c
deleted file mode 100644
index 1ef5192..0000000
--- a/sql/src/main/native/sqlite_jni_registration.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
-
-#include "JNIHelp.h"
-#include "sqlite_jni.h"
-
-/* Methods for class SQLite_Database */
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1open
-  (JNIEnv *, jobject, jstring, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1open_1aux_1file
-  (JNIEnv *, jobject, jstring);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1finalize
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1close
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2
-  (JNIEnv *, jobject, jstring, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2_3Ljava_lang_String_2
-  (JNIEnv *, jobject, jstring, jobject, jobjectArray);
-extern JNIEXPORT jlong JNICALL Java_SQLite_Database__1last_1insert_1rowid
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1interrupt
-  (JNIEnv *, jobject);
-extern JNIEXPORT jlong JNICALL Java_SQLite_Database__1changes
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1busy_1handler
-  (JNIEnv *, jobject, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1busy_1timeout
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jboolean JNICALL Java_SQLite_Database__1complete
-  (JNIEnv *, jclass, jstring);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Database_version
-  (JNIEnv *, jclass);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Database_dbversion
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1create_1function
-  (JNIEnv *, jobject, jstring, jint, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1create_1aggregate
-  (JNIEnv *, jobject, jstring, jint, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1function_1type
-  (JNIEnv *, jobject, jstring, jint);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Database__1errmsg
-  (JNIEnv *, jobject);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Database_error_1string
-  (JNIEnv *, jclass, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1set_1encoding
-  (JNIEnv *, jobject, jstring);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1set_1authorizer
-  (JNIEnv *, jobject, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1trace
-  (JNIEnv *, jobject, jobject);
-extern JNIEXPORT jboolean JNICALL Java_SQLite_Database_is3
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database_vm_1compile
-  (JNIEnv *, jobject, jstring, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database_vm_1compile_1args
-  (JNIEnv *, jobject, jstring, jobject, jobjectArray);
-extern JNIEXPORT void JNICALL Java_SQLite_Database_stmt_1prepare
-  (JNIEnv *, jobject, jstring, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1open_1blob
-  (JNIEnv *, jobject, jstring, jstring, jstring, jlong, jboolean, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database__1progress_1handler
-  (JNIEnv *, jobject, jint, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Database_internal_1init
-  (JNIEnv *, jclass);
-
-
-/* Methods for class SQLite_Vm */
-
-extern JNIEXPORT jboolean JNICALL Java_SQLite_Vm_step
-  (JNIEnv *, jobject, jobject);
-extern JNIEXPORT jboolean JNICALL Java_SQLite_Vm_compile
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Vm_stop
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Vm_finalize
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Vm_internal_1init
-  (JNIEnv *, jclass);
-
-/* Methods for class SQLite_FunctionContext */
-
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_set_1result__Ljava_lang_String_2
-  (JNIEnv *, jobject, jstring);
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_set_1result__I
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_set_1result__D
-  (JNIEnv *, jobject, jdouble);
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_set_1error
-  (JNIEnv *, jobject, jstring);
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_set_1result___3B
-  (JNIEnv *, jobject, jbyteArray);
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_set_1result_1zeroblob
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jint JNICALL Java_SQLite_FunctionContext_count
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_FunctionContext_internal_1init
-  (JNIEnv *, jclass);
-
-/* Methods for class SQLite_Stmt */
-
-extern JNIEXPORT jboolean JNICALL Java_SQLite_Stmt_prepare
-  (JNIEnv *, jobject);
-extern JNIEXPORT jboolean JNICALL Java_SQLite_Stmt_step
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_close
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_reset
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_clear_1bindings
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind__II
-  (JNIEnv *, jobject, jint, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind__IJ
-  (JNIEnv *, jobject, jint, jlong);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind__ID
-  (JNIEnv *, jobject, jint, jdouble);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind__I_3B
-  (JNIEnv *, jobject, jint, jbyteArray);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind__ILjava_lang_String_2
-  (JNIEnv *, jobject, jint, jstring);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind__I
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_bind_1zeroblob
-  (JNIEnv *, jobject, jint, jint);
-extern JNIEXPORT jint JNICALL Java_SQLite_Stmt_bind_1parameter_1count
-  (JNIEnv *, jobject);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Stmt_bind_1parameter_1name
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jint JNICALL Java_SQLite_Stmt_bind_1parameter_1index
-  (JNIEnv *, jobject, jstring);
-extern JNIEXPORT jint JNICALL Java_SQLite_Stmt_column_1int
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jlong JNICALL Java_SQLite_Stmt_column_1long
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jdouble JNICALL Java_SQLite_Stmt_column_1double
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jbyteArray JNICALL Java_SQLite_Stmt_column_1bytes
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Stmt_column_1string
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jint JNICALL Java_SQLite_Stmt_column_1type
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jint JNICALL Java_SQLite_Stmt_column_1count
-  (JNIEnv *, jobject);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Stmt_column_1table_1name
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Stmt_column_1database_1name
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Stmt_column_1decltype
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT jstring JNICALL Java_SQLite_Stmt_column_1origin_1name
-  (JNIEnv *, jobject, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_finalize
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Stmt_internal_1init
-  (JNIEnv *, jclass);
-
-/* Methods for class SQLite_Blob */
-
-extern JNIEXPORT void JNICALL Java_SQLite_Blob_close
-  (JNIEnv *, jobject);
-extern JNIEXPORT jint JNICALL Java_SQLite_Blob_write
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint);
-extern JNIEXPORT jint JNICALL Java_SQLite_Blob_read
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint);
-extern JNIEXPORT void JNICALL Java_SQLite_Blob_finalize
-  (JNIEnv *, jobject);
-extern JNIEXPORT void JNICALL Java_SQLite_Blob_internal_1init
-  (JNIEnv *, jclass);
-
-/*
- * JNI registration
- */
-static JNINativeMethod sqliteDatabaseMethods[] = {
-    /* name, signature, funcPtr */
-/* Header for class SQLite_Database */
-{ "_open", "(Ljava/lang/String;I)V", Java_SQLite_Database__1open},
-{ "_open_aux_file", "(Ljava/lang/String;)V", Java_SQLite_Database__1open_1aux_1file},
-{ "_finalize", "()V", Java_SQLite_Database__1finalize},
-{ "_close", "()V", Java_SQLite_Database__1close},
-{ "_exec", "(Ljava/lang/String;LSQLite/Callback;)V", Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2},
-{ "_exec", "(Ljava/lang/String;LSQLite/Callback;[Ljava/lang/String;)V", Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2_3Ljava_lang_String_2},
-{ "_last_insert_rowid", "()J", Java_SQLite_Database__1last_1insert_1rowid},
-{ "_interrupt", "()V", Java_SQLite_Database__1interrupt},
-{ "_changes", "()J", Java_SQLite_Database__1changes},
-{ "_busy_handler", "(LSQLite/BusyHandler;)V", Java_SQLite_Database__1busy_1handler},
-{ "_busy_timeout", "(I)V", Java_SQLite_Database__1busy_1timeout},
-{ "_complete", "(Ljava/lang/String;)Z", Java_SQLite_Database__1complete},
-{ "version", "()Ljava/lang/String;", Java_SQLite_Database_version},
-{ "dbversion", "()Ljava/lang/String;", Java_SQLite_Database_dbversion},
-{ "_create_function", "(Ljava/lang/String;ILSQLite/Function;)V", Java_SQLite_Database__1create_1function},
-{ "_create_aggregate", "(Ljava/lang/String;ILSQLite/Function;)V", Java_SQLite_Database__1create_1aggregate},
-{ "_function_type", "(Ljava/lang/String;I)V", Java_SQLite_Database__1function_1type},
-{ "_errmsg", "()Ljava/lang/String;", Java_SQLite_Database__1errmsg},
-{ "error_string", "(I)Ljava/lang/String;", Java_SQLite_Database_error_1string},
-{ "_set_encoding", "(Ljava/lang/String;)V", Java_SQLite_Database__1set_1encoding},
-{ "_set_authorizer", "(LSQLite/Authorizer;)V", Java_SQLite_Database__1set_1authorizer},
-{ "_trace", "(LSQLite/Trace;)V", Java_SQLite_Database__1trace},
-{ "is3", "()Z", Java_SQLite_Database_is3},
-{ "vm_compile", "(Ljava/lang/String;LSQLite/Vm;)V", Java_SQLite_Database_vm_1compile},
-{ "vm_compile_args", "(Ljava/lang/String;LSQLite/Vm;[Ljava/lang/String;)V", Java_SQLite_Database_vm_1compile_1args},
-{ "stmt_prepare", "(Ljava/lang/String;LSQLite/Stmt;)V", Java_SQLite_Database_stmt_1prepare},
-{ "_open_blob", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZLSQLite/Blob;)V", Java_SQLite_Database__1open_1blob},
-{ "_progress_handler", "(ILSQLite/ProgressHandler;)V", Java_SQLite_Database__1progress_1handler},
-{ "internal_init", "()V", Java_SQLite_Database_internal_1init}
-};
-
-static JNINativeMethod sqliteVmMethods[] = {
-/* Header for class SQLite_Vm */
-{ "step", "(LSQLite/Callback;)Z", Java_SQLite_Vm_step},
-{ "compile", "()Z", Java_SQLite_Vm_compile},
-{ "stop", "()V", Java_SQLite_Vm_stop},
-{ "finalize", "()V", Java_SQLite_Vm_finalize},
-{ "internal_init", "()V", Java_SQLite_Vm_internal_1init}
-};
-
-static JNINativeMethod sqliteFunctionContextMethods[] = {
-/* Header for class SQLite_FunctionContext */
-{ "set_result", "(Ljava/lang/String;)V", Java_SQLite_FunctionContext_set_1result__Ljava_lang_String_2},
-{ "set_result", "(I)V", Java_SQLite_FunctionContext_set_1result__I},
-{ "set_result", "(D)V", Java_SQLite_FunctionContext_set_1result__D},
-{ "set_error", "(Ljava/lang/String;)V", Java_SQLite_FunctionContext_set_1error},
-{ "set_result", "([B)V", Java_SQLite_FunctionContext_set_1result___3B},
-{ "set_result_zeroblob", "(I)V", Java_SQLite_FunctionContext_set_1result_1zeroblob},
-{ "count", "()I", Java_SQLite_FunctionContext_count},
-{ "internal_init", "()V", Java_SQLite_FunctionContext_internal_1init}
-};
-
-static JNINativeMethod sqliteStmtMethods[] = {
-/* Header for class SQLite_Stmt */
-{ "prepare", "()Z", Java_SQLite_Stmt_prepare},
-{ "step", "()Z", JNICALL Java_SQLite_Stmt_step},
-{ "close", "()V", Java_SQLite_Stmt_close},
-{ "reset", "()V", Java_SQLite_Stmt_reset},
-{ "clear_bindings", "()V", Java_SQLite_Stmt_clear_1bindings},
-{ "bind", "(II)V", Java_SQLite_Stmt_bind__II},
-{ "bind", "(IJ)V", Java_SQLite_Stmt_bind__IJ},
-{ "bind", "(ID)V", Java_SQLite_Stmt_bind__ID},
-{ "bind", "(I[B)V", Java_SQLite_Stmt_bind__I_3B},
-{ "bind", "(ILjava/lang/String;)V", Java_SQLite_Stmt_bind__ILjava_lang_String_2},
-{ "bind", "(I)V", Java_SQLite_Stmt_bind__I},
-{ "bind_zeroblob", "(II)V", Java_SQLite_Stmt_bind_1zeroblob},
-{ "bind_parameter_count", "()I", Java_SQLite_Stmt_bind_1parameter_1count},
-{ "bind_parameter_name", "(I)Ljava/lang/String;", Java_SQLite_Stmt_bind_1parameter_1name},
-{ "bind_parameter_index", "(Ljava/lang/String;)I", Java_SQLite_Stmt_bind_1parameter_1index},
-{ "column_int", "(I)I", Java_SQLite_Stmt_column_1int},
-{ "column_long", "(I)J", Java_SQLite_Stmt_column_1long},
-{ "column_double", "(I)D", Java_SQLite_Stmt_column_1double},
-{ "column_bytes", "(I)[B", Java_SQLite_Stmt_column_1bytes},
-{ "column_string", "(I)Ljava/lang/String;", Java_SQLite_Stmt_column_1string},
-{ "column_type", "(I)I", Java_SQLite_Stmt_column_1type},
-{ "column_count", "()I", Java_SQLite_Stmt_column_1count},
-{ "column_table_name", "(I)Ljava/lang/String;", Java_SQLite_Stmt_column_1table_1name},
-{ "column_database_name", "(I)Ljava/lang/String;", Java_SQLite_Stmt_column_1database_1name},
-{ "column_decltype", "(I)Ljava/lang/String;", Java_SQLite_Stmt_column_1decltype},
-{ "column_origin_name", "(I)Ljava/lang/String;", Java_SQLite_Stmt_column_1origin_1name},
-{ "finalize", "()V", Java_SQLite_Stmt_finalize},
-{ "internal_init", "()V", Java_SQLite_Stmt_internal_1init}
-};
-
-static JNINativeMethod sqliteBlobMethods[] = {
-/* Header for class SQLite_Blob */
-
-{ "close", "()V", Java_SQLite_Blob_close},
-{ "write", "([BIII)I", Java_SQLite_Blob_write},
-{ "read", "([BIII)I", Java_SQLite_Blob_read},
-{ "finalize", "()V", Java_SQLite_Blob_finalize},
-{ "internal_init", "()V", Java_SQLite_Blob_internal_1init}
-};
-
-int register_SQLite_Database(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "SQLite/Database",
-        sqliteDatabaseMethods, NELEM(sqliteDatabaseMethods));
-}
-
-int register_SQLite_Vm(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "SQLite/Vm",
-        sqliteVmMethods, NELEM(sqliteVmMethods));
-}
-
-int register_SQLite_FunctionContext(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "SQLite/FunctionContext",
-        sqliteFunctionContextMethods, NELEM(sqliteFunctionContextMethods));
-}
-
-int register_SQLite_Stmt(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "SQLite/Stmt",
-        sqliteStmtMethods, NELEM(sqliteStmtMethods));
-}
-
-int register_SQLite_Blob(JNIEnv* env) {
-    return jniRegisterNativeMethods(env, "SQLite/Blob",
-        sqliteBlobMethods, NELEM(sqliteBlobMethods));
-}
diff --git a/sql/src/main/native/sub.mk b/sql/src/main/native/sub.mk
deleted file mode 100644
index d84e0b6..0000000
--- a/sql/src/main/native/sub.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# 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.
-
-LOCAL_SRC_FILES := \
-	sqlite_jni.c \
-	sqlite_jni_registration.c
-
-LOCAL_C_INCLUDES += \
-	external/sqlite/dist
-
-# Any shared/static libs that are listed here must also
-# be listed in libs/nativehelper/Android.mk.
-# TODO: fix this requirement
-
-LOCAL_SHARED_LIBRARIES += \
-	libsqlite
-
-LOCAL_STATIC_LIBRARIES +=
diff --git a/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/AllTests.java b/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/AllTests.java
index 58c670a..1b0bb59 100644
--- a/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/AllTests.java
+++ b/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.sql.tests.java.sql;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.sql.tests.java.sql;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(BatchUpdateExceptionTest.class);
diff --git a/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java b/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
index 6fa7949..069d46f 100644
--- a/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
+++ b/sql/src/test/java/org/apache/harmony/sql/tests/java/sql/DriverManagerTest.java
@@ -372,7 +372,6 @@
         method = "getDrivers",
         args = {}
     )
-    @KnownFailure("We're working out issues with built-in SQL drivers")
     public void testGetDrivers() {
         // Load a driver manager
         Enumeration<Driver> driverList = DriverManager.getDrivers();
@@ -384,16 +383,9 @@
         } // end while
 
         // Check that all the drivers are in the list...
-        // BEGIN android-changed
-        // We have a ClassLoader issue in the DriverManager: The
-        // Drivermanager loads the System drivers in a static initialisation
-        // method loadInitialDrivers. This initialisation happens in the cts
-        // environment before the test sets the drivers via the system property
-        // "jdbc.drivers".
-        // Therefore the system drivers are not returned via getDrivers()
-        final int noOfSystemDriversLoaded = 2; //DRIVER4 + DRIVER5
-        assertEquals("testGetDrivers: Don't see all the loaded drivers - ", numberLoaded - noOfSystemDriversLoaded, i);
-        // END android-changed
+        // There might be other drivers loaded in other classes
+        assertTrue("testGetDrivers: Don't see all the loaded drivers - ",
+                i >= numberLoaded);
     } // end method testGetDrivers()
 
     static int timeout1 = 25;
@@ -717,7 +709,6 @@
     /**
      * Regression for HARMONY-4303
      */
-    @KnownFailure("The test doesn't fork the VM properly.")
     public void test_initClass() throws Exception {
         ProcessBuilder builder = javaProcessBuilder();
         builder.command().add("org/apache/harmony/sql/tests/java/sql/TestMainForDriver");
@@ -761,5 +752,3 @@
     }
 
 } // end class DriverManagerTest
-
-
diff --git a/sql/src/test/java/org/apache/harmony/sql/tests/javax/sql/AllTests.java b/sql/src/test/java/org/apache/harmony/sql/tests/javax/sql/AllTests.java
index abbb8b0..8183bbf 100644
--- a/sql/src/test/java/org/apache/harmony/sql/tests/javax/sql/AllTests.java
+++ b/sql/src/test/java/org/apache/harmony/sql/tests/javax/sql/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.sql.tests.javax.sql;");
+        TestSuite suite = new TestSuite("All tests for package org.apache.harmony.sql.tests.javax.sql;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(ConnectionEventTest.class);
diff --git a/sql/src/test/java/tests/SQLite/AllTests.java b/sql/src/test/java/tests/SQLite/AllTests.java
index 2cf0f61..ea8b841 100644
--- a/sql/src/test/java/tests/SQLite/AllTests.java
+++ b/sql/src/test/java/tests/SQLite/AllTests.java
@@ -23,12 +23,11 @@
 
     //All tests executed with sqlite3 only
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for SQLite");
+        TestSuite suite = new TestSuite("Tests for SQLite");
         //$JUnit-BEGIN$
         suite.addTestSuite(DatabaseTest.class);
         suite.addTestSuite(JDBCDriverFunctionalTest.class);
         suite.addTestSuite(JDBCDriverTest.class);
-        suite.addTestSuite(ConstantsTest.class);
         suite.addTestSuite(BlobTest.class);
         suite.addTestSuite(StmtTest.class);
         suite.addTestSuite(ExceptionTest.class);
diff --git a/sql/src/test/java/tests/SQLite/ConstantsTest.java b/sql/src/test/java/tests/SQLite/ConstantsTest.java
deleted file mode 100644
index 2a4961f..0000000
--- a/sql/src/test/java/tests/SQLite/ConstantsTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package tests.SQLite;
-
-import SQLite.Constants;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-
-import junit.framework.TestCase;
-
-@TestTargetClass(Constants.class)
-public class ConstantsTest extends TestCase {
-
-    /**
-     * @tests Constants#Constants()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "constructor test",
-        method = "Constants",
-        args = {}
-    )
-    public void testConstants() {
-        Constants c = new Constants();
-            
-        assertNotNull(c);
-        assertEquals(c.SQLITE_OK, 0);
-        assertEquals(c.SQLITE_ERROR, 1);
-        assertEquals(c.SQLITE_INTERNAL, 2);
-        assertEquals(c.SQLITE_PERM, 3);
-        assertEquals(c.SQLITE_ABORT, 4);
-        assertEquals(c.SQLITE_BUSY, 5);
-        assertEquals(c.SQLITE_LOCKED, 6);
-        assertEquals(c.SQLITE_NOMEM, 7);
-        assertEquals(c.SQLITE_READONLY, 8);
-        assertEquals(c.SQLITE_INTERRUPT, 9);
-        assertEquals(c.SQLITE_IOERR, 10);
-        assertEquals(c.SQLITE_CORRUPT, 11);
-        assertEquals(c.SQLITE_NOTFOUND, 12);
-        assertEquals(c.SQLITE_FULL, 13);
-        assertEquals(c.SQLITE_CANTOPEN, 14);
-        assertEquals(c.SQLITE_PROTOCOL, 15);
-        assertEquals(c.SQLITE_EMPTY, 16);
-        assertEquals(c.SQLITE_SCHEMA, 17);
-        assertEquals(c.SQLITE_TOOBIG, 18);
-        assertEquals(c.SQLITE_CONSTRAINT, 19);
-        assertEquals(c.SQLITE_MISMATCH, 20);
-        assertEquals(c.SQLITE_MISUSE, 21);
-        assertEquals(c.SQLITE_NOLFS, 22);
-        assertEquals(c.SQLITE_AUTH, 23);
-        assertEquals(c.SQLITE_FORMAT, 24);
-        assertEquals(c.SQLITE_RANGE, 25);
-        assertEquals(c.SQLITE_NOTADB, 26);
-        assertEquals(c.SQLITE_ROW, 100);
-        assertEquals(c.SQLITE_DONE, 101);
-        assertEquals(c.SQLITE_INTEGER, 1);
-        assertEquals(c.SQLITE_FLOAT, 2);
-        assertEquals(c.SQLITE_BLOB, 4);
-        assertEquals(c.SQLITE_NULL, 5);
-        assertEquals(c.SQLITE3_TEXT, 3);
-        assertEquals(c.SQLITE_NUMERIC, -1);
-        assertEquals(c.SQLITE_TEXT, 3);
-        assertEquals(c.SQLITE2_TEXT, -2);
-        assertEquals(c.SQLITE_ARGS, -3);
-        assertEquals(c.SQLITE_COPY, 0);
-        assertEquals(c.SQLITE_CREATE_INDEX, 1);
-        assertEquals(c.SQLITE_CREATE_TABLE, 2);
-        assertEquals(c.SQLITE_CREATE_TEMP_INDEX, 3);
-        assertEquals(c.SQLITE_CREATE_TEMP_TABLE, 4);
-        assertEquals(c.SQLITE_CREATE_TEMP_TRIGGER, 5);
-        assertEquals(c.SQLITE_CREATE_TEMP_VIEW, 6);
-        assertEquals(c.SQLITE_CREATE_TRIGGER, 7);
-        assertEquals(c.SQLITE_CREATE_VIEW, 8);
-        assertEquals(c.SQLITE_DELETE, 9);
-        assertEquals(c.SQLITE_DROP_INDEX, 10);
-        assertEquals(c.SQLITE_DROP_TABLE, 11);
-        assertEquals(c.SQLITE_DROP_TEMP_INDEX, 12);
-        assertEquals(c.SQLITE_DROP_TEMP_TABLE, 13);
-        assertEquals(c.SQLITE_DROP_TEMP_TRIGGER, 14);
-        assertEquals(c.SQLITE_DROP_TEMP_VIEW, 15);
-        assertEquals(c.SQLITE_DROP_TRIGGER, 16);
-        assertEquals(c.SQLITE_DROP_VIEW, 17);
-        assertEquals(c.SQLITE_INSERT, 18);
-        assertEquals(c.SQLITE_PRAGMA, 19);
-        assertEquals(c.SQLITE_READ, 20);
-        assertEquals(c.SQLITE_SELECT, 21);
-        assertEquals(c.SQLITE_TRANSACTION, 22);
-        assertEquals(c.SQLITE_UPDATE, 23);
-        assertEquals(c.SQLITE_ATTACH, 24);
-        assertEquals(c.SQLITE_DETACH, 25);
-        assertEquals(c.SQLITE_DENY, 1);
-        assertEquals(c.SQLITE_IGNORE, 2);
-    }
-}
diff --git a/sql/src/test/java/tests/SQLite/DatabaseTest.java b/sql/src/test/java/tests/SQLite/DatabaseTest.java
index 95ce7c8..12a556d 100644
--- a/sql/src/test/java/tests/SQLite/DatabaseTest.java
+++ b/sql/src/test/java/tests/SQLite/DatabaseTest.java
@@ -1069,7 +1069,7 @@
             db.exec("insert into TEST values(4, 'Fiona', 'Apple'); ", null);
             db.trace((Trace) t);
             db.create_aggregate("myaggfunc", 1, aggFunction);
-            db.function_type("myaggfunc", Constants.SQLITE_TEXT);
+            db.function_type("myaggfunc", Constants.SQLITE3_TEXT);
             db.exec("PRAGMA show_datatypes = on", null);
             
             assertFalse(aggFunction.functionCalled);
@@ -1125,7 +1125,7 @@
                 null);
         
         db.create_function("sin", 1, sinFunc);
-        db.function_type("sin", Constants.SQLITE_NUMERIC);
+        db.function_type("sin", Constants.SQLITE_FLOAT);
         res = db.get_table("select sin(res) from TEST WHERE res = "
                 + Double.toString(input));
          
@@ -2036,4 +2036,3 @@
     }
    
 }
-
diff --git a/sql/src/test/java/tests/SQLite/StmtTest.java b/sql/src/test/java/tests/SQLite/StmtTest.java
index cb71243..7a37154 100644
--- a/sql/src/test/java/tests/SQLite/StmtTest.java
+++ b/sql/src/test/java/tests/SQLite/StmtTest.java
@@ -982,17 +982,6 @@
         }
     }
     
-    /**
-     * @throws Exception 
-     * @tests {@link Stmt#column_type(int)}
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "method test",
-        method = "column_type",
-        args = {int.class}
-    )
-    @KnownFailure("For numeric, float and blob wrong type is returned")
     public void testColumn_type() throws Exception {
         db.exec(createAllTypes, null);
         db.exec(insertAllTypes, null);
@@ -1033,10 +1022,8 @@
         assertEquals(Constants.SQLITE_NULL, st.column_type(29));
 
         // Failing tests
-        assertTrue("NUMERIC".equalsIgnoreCase(st.column_decltype(12)));
-        assertEquals(Constants.SQLITE_NUMERIC, st.column_type(12)); // NUMERIC
-                                                                    // -> got
-                                                                    // INTEGER
+        assertTrue("INTEGER".equalsIgnoreCase(st.column_decltype(12)));
+        assertEquals(Constants.SQLITE_INTEGER, st.column_type(12));
         
         assertTrue("FLOAT".equalsIgnoreCase(st.column_decltype(11)));
         assertEquals(Constants.SQLITE_FLOAT, st.column_type(11)); // FLOAT ->
diff --git a/sql/src/test/java/tests/java/sql/AllTests.java b/sql/src/test/java/tests/java/sql/AllTests.java
index c6a2bff..5c9345b 100644
--- a/sql/src/test/java/tests/java/sql/AllTests.java
+++ b/sql/src/test/java/tests/java/sql/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.java.sql;");
+        TestSuite suite = new TestSuite("All tests for package tests.java.sql;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(MultiThreadAccessTest.class);
diff --git a/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java b/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java
index b09b7792..c03bd6f 100644
--- a/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java
+++ b/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java
@@ -941,23 +941,14 @@
                 meta.ownInsertsAreVisible(100));
     }
 
-    /**
-     * @tests {@link java.sql.DatabaseMetaData#ownUpdatesAreVisible(int)}
-     */
-    @TestTargetNew(
-        level = TestLevel.NOT_FEASIBLE,
-        notes = "not supported. Verification with invalid parameters missed.",
-        method = "ownUpdatesAreVisible",
-        args = {int.class}
-    )
     public void test_ownUpdatesAreVisibleI() throws SQLException {
-        assertFalse(
+        assertTrue(
                 "result set's own updates are visible for TYPE_FORWARD_ONLY type",
                 meta.ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY));
-        assertFalse(
+        assertTrue(
                 "result set's own updates are visible for TYPE_SCROLL_INSENSITIVE type",
                 meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE));
-        assertFalse(
+        assertTrue(
                 "result set's own updates are visible for TYPE_SCROLL_SENSITIVE type",
                 meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE));
         assertFalse("result set's own updates are visible for unknown type",
@@ -1090,18 +1081,8 @@
 
     }
 
-    /**
-     * @tests java.sql.DatabaseMetaData#supportsBatchUpdates()
-     */
-    @TestTargetNew(
-        level = TestLevel.NOT_FEASIBLE,
-        notes = "not supported",
-        method = "supportsBatchUpdates",
-        args = {}
-    )
     public void test_supportsBatchUpdates() throws SQLException {
-        // NOT_FEASIBLE: SQLITE does not implement this functionality
-        assertFalse(meta.supportsBatchUpdates());
+        assertTrue(meta.supportsBatchUpdates());
     }
 
     /**
@@ -1792,32 +1773,12 @@
         assertFalse(meta.supportsTransactions());
     }
 
-    /**
-     * @tests java.sql.DatabaseMetaData#supportsUnion()
-     */
-    @TestTargetNew(
-        level = TestLevel.NOT_FEASIBLE,
-        notes = "not supported",
-        method = "supportsUnion",
-        args = {}
-    )
     public void test_supportsUnion() throws SQLException {
-        // NOT_FEASIBLE: SQLITE does not implement this functionality
-        assertFalse(meta.supportsUnion());
+        assertTrue(meta.supportsUnion());
     }
 
-    /**
-     * @tests java.sql.DatabaseMetaData#supportsUnionAll()
-     */
-    @TestTargetNew(
-        level = TestLevel.NOT_FEASIBLE,
-        notes = "not supported",
-        method = "supportsUnionAll",
-        args = {}
-    )
     public void test_supportsUnionAll() throws SQLException {
-        // NOT_FEASIBLE: SQLITE does not implement this functionality
-        assertFalse(meta.supportsUnionAll());
+        assertTrue(meta.supportsUnionAll());
     }
     
     /**
diff --git a/sql/src/test/java/tests/sql/AllTests.java b/sql/src/test/java/tests/sql/AllTests.java
index 4d59cd4..6eda690 100644
--- a/sql/src/test/java/tests/sql/AllTests.java
+++ b/sql/src/test/java/tests/sql/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the Math project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All SQL test suites");
+        TestSuite suite = new TestSuite("All SQL test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.sql.tests.java.sql.AllTests.suite());
         suite.addTest(org.apache.harmony.sql.tests.javax.sql.AllTests.suite());
diff --git a/sql/src/test/java/tests/sql/PreparedStatementTest.java b/sql/src/test/java/tests/sql/PreparedStatementTest.java
index 26147ed..1546d38 100755
--- a/sql/src/test/java/tests/sql/PreparedStatementTest.java
+++ b/sql/src/test/java/tests/sql/PreparedStatementTest.java
@@ -2981,16 +2981,6 @@
         }
     }
     
-    /**
-     * @test {@link java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader, int)}
-     * 
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "not supported",
-        method = "setCharacterStream",
-        args = {int.class, java.io.Reader.class, int.class}
-    )
     public void testSetCharacterSteam() {
         ResultSet res = null;
         PreparedStatement ps = null;
@@ -3002,9 +2992,6 @@
             assertNotNull("Error in test setup: file not found",file);
             Reader reader = new InputStreamReader(file);
             ps.setCharacterStream(1, reader, 100);
-            fail("Exception expected not supported"); 
-        } catch (SQLException e) {
-            // ok     
         } catch (Exception e) {
             fail("Error in test setup "+e.getMessage());
             e.printStackTrace();
diff --git a/sql/src/test/java/tests/sql/ResultSetGetterTests.java b/sql/src/test/java/tests/sql/ResultSetGetterTests.java
index 9b12fc1..fccfd94 100644
--- a/sql/src/test/java/tests/sql/ResultSetGetterTests.java
+++ b/sql/src/test/java/tests/sql/ResultSetGetterTests.java
@@ -299,7 +299,6 @@
         method = "getBytes",
         args = {int.class}
     )
-    @KnownFailure("last assertion fails: invalid conversion. Test passes on RI")
     public void testGetBytesIntVarbinary() throws SQLException {
 
         Statement st = null;
@@ -347,7 +346,6 @@
         method = "getBytes",
         args = {int.class}
     )
-     @KnownFailure("last assertion fails: invalid conversion. Test passes on RI")
     public void testGetBytesIntBinary() throws SQLException {
 
         Statement st = null;
@@ -511,18 +509,9 @@
         }
     }
 
-    /**
-     * Test method for {@link java.sql.ResultSet#getConcurrency()}.
-     */
-    @TestTargetNew(
-        level = TestLevel.SUFFICIENT,
-        notes = "Not fully supported: CONCUR_UPDATABLE not supported",
-        method = "getConcurrency",
-        args = {}
-    )
     public void testGetConcurrency() {
         try {
-            assertEquals(ResultSet.CONCUR_READ_ONLY, res.getConcurrency());
+            assertEquals(ResultSet.CONCUR_UPDATABLE, res.getConcurrency());
         } catch (SQLException e) {
             fail("Unexpected exception: " + e.getMessage());
         }
diff --git a/sql/src/test/java/tests/sql/ResultSetTest.java b/sql/src/test/java/tests/sql/ResultSetTest.java
index 796c6a4..5b6d74a 100644
--- a/sql/src/test/java/tests/sql/ResultSetTest.java
+++ b/sql/src/test/java/tests/sql/ResultSetTest.java
@@ -107,19 +107,6 @@
         } catch (SQLException e) {
             fail("Unexpected exception: " + e.getMessage());
         }
-        
-        try {
-//          Go back in position with forward only cursor
-            assertEquals(ResultSet.TYPE_FORWARD_ONLY, target.getFetchDirection());
-            target.absolute(2);
-            target.absolute(1);
-            fail("Should get SQLException");
-        } catch (SQLException e) {
-            // ok
-        }
-        
-        
-        
     }
 
     /**
@@ -598,42 +585,8 @@
         
     }
 
-    /**
-     * Test method for {@link java.sql.ResultSet#previous()}.
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "tests SQLException",
-        method = "previous",
-        args = {}
-    )
-    public void testPrevious() {
-        
+    public void testPrevious() throws SQLException {
         try {
-            assertEquals(ResultSet.FETCH_FORWARD, target.getFetchDirection());
-            target.last();
-            target.previous();
-            fail("Should get SQLException");
-        } catch (SQLException e) {
-            // ok
-        }
-    }
-    
-    /**
-     * Test method for {@link java.sql.ResultSet#previous()}.
-     * @throws SQLException 
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "not supported",
-        method = "previous",
-        args = {}
-    )
-    @KnownFailure("not supported")
-    public void testPrevious2() throws SQLException {
-        try {
-            assertSame(ResultSet.TYPE_SCROLL_INSENSITIVE, scrollableTarget.getFetchDirection());
-            
             target.first();
             target.previous();
             assertTrue(target.isBeforeFirst());
diff --git a/sql/src/test/java/tests/sql/StatementTest.java b/sql/src/test/java/tests/sql/StatementTest.java
index f884782..55bd7ab 100755
--- a/sql/src/test/java/tests/sql/StatementTest.java
+++ b/sql/src/test/java/tests/sql/StatementTest.java
@@ -692,29 +692,28 @@
         }
     }
 
-    /**
-     * @test java.sql.Statement#setMaxRows(int max)
-     * TODO not supported
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "not supported",
-        method = "setMaxRows",
-        args = {int.class}
-    )
-    public void testSetMaxRows() {
+    public void testMaxRows() {
         Statement st = null;
         try {
             st = conn.createStatement();
-            st.execute("select * from zoo;");
-            for (int i = 0; i < 300; i += 50) {
+            for (int i = 0; i < 300; i += 50) { 
                 try {
                     st.setMaxRows(i);
                     assertEquals(i, st.getMaxRows());
-                    fail("Revise test implemenation for feature impl. has changed");
+                    ResultSet r = st.executeQuery("select * from zoo;");
+                    int rowCount = 0;
+                    while (r.next()) {
+                        ++rowCount;
+                    }
+                    if (i == 0) {
+                        // 0 means unlimited.
+                        assertTrue("rowCount=" + rowCount + " i=" + i, rowCount > i);
+                    } else {
+                        assertTrue("rowCount=" + rowCount + " i=" + i, rowCount <= i);
+                    }
+                    r.close();
                 } catch (SQLException sqle) {
-                    assertEquals("not supported", sqle.getMessage());
-//                   fail("SQLException is thrown: " + sqle.getMessage());
+                    fail("SQLException is thrown: " + sqle.getMessage());
                 }
             }
             try {
@@ -735,41 +734,6 @@
     }
 
     /**
-     * @test java.sql.Statement#getMaxRows()
-     * TODO not supported
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "not supported",
-        method = "getMaxRows",
-        args = {}
-    )
-    public void testGetMaxRows() {
-        Statement st = null;
-        try {
-            st = conn.createStatement();
-            for (int i = 200; i < 500; i += 50) {
-                try {
-                    st.setMaxRows(i);
-                    assertEquals(i, st.getMaxRows());
-                    fail("Revise test implemenation for feature impl. has changed");
-                } catch (SQLException sqle) {
-                    assertEquals("not supported", sqle.getMessage());
-//                    fail("SQLException is thrown: " + sqle.getMessage());
-                }
-            }
-        } catch (SQLException e) {
-            fail("Can't create statement, SQLException is thrown: "
-                    + e.getMessage());
-        } finally {
-            try {
-                st.close();
-            } catch (SQLException ee) {
-            }
-        }
-    }
-
-    /**
      * @test java.sql.Statement#close()
      * not passed according to Java Docs: should release all resources 
      * IMMEDIATELY
diff --git a/sqlite-jdbc/Android.mk b/sqlite-jdbc/Android.mk
new file mode 100644
index 0000000..2c3926a
--- /dev/null
+++ b/sqlite-jdbc/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	src/main/native/sqlite_jni.c
+
+LOCAL_C_INCLUDES += \
+        $(JNI_H_INCLUDE) \
+	external/sqlite/dist
+
+LOCAL_SHARED_LIBRARIES += \
+	libsqlite
+
+LOCAL_STATIC_LIBRARIES +=
+
+# This name is dictated by the fact that the SQLite code calls
+# loadLibrary("sqlite_jni").
+LOCAL_MODULE := libsqlite_jni
+
+TARGET_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/sql/MODULE_LICENSE_BSD_LIKE b/sqlite-jdbc/MODULE_LICENSE_BSD_LIKE
similarity index 100%
rename from sql/MODULE_LICENSE_BSD_LIKE
rename to sqlite-jdbc/MODULE_LICENSE_BSD_LIKE
diff --git a/sqlite-jdbc/VERSION b/sqlite-jdbc/VERSION
new file mode 100644
index 0000000..23bd019
--- /dev/null
+++ b/sqlite-jdbc/VERSION
@@ -0,0 +1 @@
+20100131
diff --git a/sql/src/main/java/SQLite/Authorizer.java b/sqlite-jdbc/src/main/java/SQLite/Authorizer.java
similarity index 96%
rename from sql/src/main/java/SQLite/Authorizer.java
rename to sqlite-jdbc/src/main/java/SQLite/Authorizer.java
index cdc321d..24fc459 100644
--- a/sql/src/main/java/SQLite/Authorizer.java
+++ b/sqlite-jdbc/src/main/java/SQLite/Authorizer.java
@@ -20,6 +20,6 @@
      */
 
     public int authorize(int what, String arg1, String arg2, String arg3,
-             String arg4);
+			 String arg4);
 }
 
diff --git a/sql/src/main/java/SQLite/Blob.java b/sqlite-jdbc/src/main/java/SQLite/Blob.java
similarity index 75%
rename from sql/src/main/java/SQLite/Blob.java
rename to sqlite-jdbc/src/main/java/SQLite/Blob.java
index 16fecf1..2724670 100644
--- a/sql/src/main/java/SQLite/Blob.java
+++ b/sqlite-jdbc/src/main/java/SQLite/Blob.java
@@ -26,14 +26,14 @@
      */
 
     BlobR(Blob blob) {
-    this.blob = blob;
-    this.pos = 0;
+	this.blob = blob;
+	this.pos = 0;
     }
 
     @Override
     public int available() throws IOException {
-    int ret = blob.size - pos;
-    return (ret < 0) ? 0 : ret;
+	int ret = blob.size - pos;
+	return (ret < 0) ? 0 : ret;
     }
 
     /**
@@ -56,7 +56,7 @@
      */
 
     public boolean markSupported() {
-    return false;
+	return false;
     }
 
     /**
@@ -65,8 +65,8 @@
 
     public void close() throws IOException {
         blob.close();
-    blob = null;
-    pos = 0;
+	blob = null;
+	pos = 0;
     }
 
     /**
@@ -74,17 +74,17 @@
      */
 
     public long skip(long n) throws IOException {
-    long ret = pos + n;
-    if (ret < 0) {
-        ret = 0;
-        pos = 0;
-    } else if (ret > blob.size) {
-        ret = blob.size;
-        pos = blob.size;
-    } else {
-        pos = (int) ret;
-    }
-    return ret;
+	long ret = pos + n;
+	if (ret < 0) {
+	    ret = 0;
+	    pos = 0;
+	} else if (ret > blob.size) {
+	    ret = blob.size;
+	    pos = blob.size;
+	} else {
+	    pos = (int) ret;
+	}
+	return ret;
     }
 
     /**
@@ -93,13 +93,13 @@
      */
 
     public int read() throws IOException {
-    byte b[] = new byte[1];
-    int n = blob.read(b, 0, pos, b.length);
-    if (n > 0) {
-        pos += n;
-        return b[0];
-    }
-    return -1;
+	byte b[] = new byte[1];
+	int n = blob.read(b, 0, pos, b.length);
+	if (n > 0) {
+	    pos += n;
+	    return b[0];
+	}
+	return -1;
     }
 
     /**
@@ -109,12 +109,12 @@
      */
 
     public int read(byte b[]) throws IOException {
-    int n = blob.read(b, 0, pos, b.length);
-    if (n > 0) {
-        pos += n;
-        return n;
-    }
-    return -1;
+	int n = blob.read(b, 0, pos, b.length);
+	if (n > 0) {
+	    pos += n;
+	    return n;
+	}
+	return -1;
     }
 
     /**
@@ -126,21 +126,21 @@
      */
 
     public int read(byte b[], int off, int len) throws IOException {
-    if (off + len > b.length) {
-        len = b.length - off;
-    }
-    if (len < 0) {
-        return -1;
-    }
-    if (len == 0) {
-        return 0;
-    }
-    int n = blob.read(b, off, pos, len);
-    if (n > 0) {
-        pos += n;
-        return n;
-    }
-    return -1;
+	if (off + len > b.length) {
+	    len = b.length - off;
+	}
+	if (len < 0) {
+	    return -1;
+	}
+	if (len == 0) {
+	    return 0;
+	}
+	int n = blob.read(b, off, pos, len);
+	if (n > 0) {
+	    pos += n;
+	    return n;
+	}
+	return -1;
     }
 }
 
@@ -168,8 +168,8 @@
      */
 
     BlobW(Blob blob) {
-    this.blob = blob;
-    this.pos = 0;
+	this.blob = blob;
+	this.pos = 0;
     }
 
     /**
@@ -185,8 +185,8 @@
 
     public void close() throws IOException {
         blob.close();
-    blob = null;
-    pos = 0;
+	blob = null;
+	pos = 0;
     }
 
     /**
@@ -195,9 +195,9 @@
      */
 
     public void write(int v) throws IOException {
-    byte b[] = new byte[1];
-    b[0] = (byte) v;
-    pos += blob.write(b, 0, pos, 1);
+	byte b[] = new byte[1];
+	b[0] = (byte) v;
+	pos += blob.write(b, 0, pos, 1);
     }
 
     /**
@@ -206,9 +206,9 @@
      */
 
     public void write(byte[] b) throws IOException {
-    if (b != null && b.length > 0) {
-        pos += blob.write(b, 0, pos, b.length);
-    }
+	if (b != null && b.length > 0) {
+	    pos += blob.write(b, 0, pos, b.length);
+	}
     }
 
     /**
@@ -219,15 +219,15 @@
      */
 
     public void write(byte[] b, int off, int len) throws IOException {
-    if (b != null) {
-        if (off + len > b.length) {
-        len = b.length - off;
-        }
-        if (len <= 0) {
-        return;
-        }
-        pos += blob.write(b, off, pos, len);
-    }
+	if (b != null) {
+	    if (off + len > b.length) {
+		len = b.length - off;
+	    }
+	    if (len <= 0) {
+		return;
+	    }
+	    pos += blob.write(b, off, pos, len);
+	}
     }
 }
 
@@ -261,7 +261,7 @@
      */
 
     public InputStream getInputStream() {
-    return (InputStream) new BlobR(this);
+	return (InputStream) new BlobR(this);
     }
 
     /**
@@ -270,7 +270,7 @@
      */
 
     public OutputStream getOutputStream() {
-    return (OutputStream) new BlobW(this);
+	return (OutputStream) new BlobW(this);
     }
 
     /**
@@ -314,6 +314,6 @@
     private static native void internal_init();
 
     static {
-    internal_init();
+	internal_init();
     }
 }
diff --git a/sql/src/main/java/SQLite/BusyHandler.java b/sqlite-jdbc/src/main/java/SQLite/BusyHandler.java
similarity index 100%
rename from sql/src/main/java/SQLite/BusyHandler.java
rename to sqlite-jdbc/src/main/java/SQLite/BusyHandler.java
diff --git a/sql/src/main/java/SQLite/Callback.java b/sqlite-jdbc/src/main/java/SQLite/Callback.java
similarity index 100%
rename from sql/src/main/java/SQLite/Callback.java
rename to sqlite-jdbc/src/main/java/SQLite/Callback.java
diff --git a/sqlite-jdbc/src/main/java/SQLite/Constants.java b/sqlite-jdbc/src/main/java/SQLite/Constants.java
new file mode 100644
index 0000000..017c49c
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/Constants.java
@@ -0,0 +1,201 @@
+/* DO NOT EDIT */
+
+package SQLite;
+
+/**
+ * Container for SQLite constants.
+ * 
+ * Usually generated by "native/mkconst.c". For Android, I pasted in the output of this one-liner:
+ * 
+ * perl -ne '$_ =~ s/#define\s+(SQLITE\S+)\s+([0-9x]+)/    public static final int $1 = $2;/ && print $_;' external/sqlite/dist/sqlite3.h
+ */
+public final class Constants {
+    // Copied from VERSION.
+    public static final int drv_minor = 20100131;
+    // Generated by the one-liner above.
+    public static final int SQLITE_VERSION_NUMBER = 3006022;
+    public static final int SQLITE_OK = 0;   /* Successful result */
+    public static final int SQLITE_ERROR = 1;   /* SQL error or missing database */
+    public static final int SQLITE_INTERNAL = 2;   /* Internal logic error in SQLite */
+    public static final int SQLITE_PERM = 3;   /* Access permission denied */
+    public static final int SQLITE_ABORT = 4;   /* Callback routine requested an abort */
+    public static final int SQLITE_BUSY = 5;   /* The database file is locked */
+    public static final int SQLITE_LOCKED = 6;   /* A table in the database is locked */
+    public static final int SQLITE_NOMEM = 7;   /* A malloc() failed */
+    public static final int SQLITE_READONLY = 8;   /* Attempt to write a readonly database */
+    public static final int SQLITE_INTERRUPT = 9;   /* Operation terminated by sqlite3_interrupt()*/
+    public static final int SQLITE_IOERR = 10;   /* Some kind of disk I/O error occurred */
+    public static final int SQLITE_CORRUPT = 11;   /* The database disk image is malformed */
+    public static final int SQLITE_NOTFOUND = 12;   /* NOT USED. Table or record not found */
+    public static final int SQLITE_FULL = 13;   /* Insertion failed because database is full */
+    public static final int SQLITE_CANTOPEN = 14;   /* Unable to open the database file */
+    public static final int SQLITE_PROTOCOL = 15;   /* NOT USED. Database lock protocol error */
+    public static final int SQLITE_EMPTY = 16;   /* Database is empty */
+    public static final int SQLITE_SCHEMA = 17;   /* The database schema changed */
+    public static final int SQLITE_TOOBIG = 18;   /* String or BLOB exceeds size limit */
+    public static final int SQLITE_CONSTRAINT = 19;   /* Abort due to constraint violation */
+    public static final int SQLITE_MISMATCH = 20;   /* Data type mismatch */
+    public static final int SQLITE_MISUSE = 21;   /* Library used incorrectly */
+    public static final int SQLITE_NOLFS = 22;   /* Uses OS features not supported on host */
+    public static final int SQLITE_AUTH = 23;   /* Authorization denied */
+    public static final int SQLITE_FORMAT = 24;   /* Auxiliary database format error */
+    public static final int SQLITE_RANGE = 25;   /* 2nd parameter to sqlite3_bind out of range */
+    public static final int SQLITE_NOTADB = 26;   /* File opened that is not a database file */
+    public static final int SQLITE_ROW = 100;  /* sqlite3_step() has another row ready */
+    public static final int SQLITE_DONE = 101;  /* sqlite3_step() has finished executing */
+    public static final int SQLITE_OPEN_READONLY = 0x00000001;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_OPEN_READWRITE = 0x00000002;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_OPEN_CREATE = 0x00000004;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_OPEN_DELETEONCLOSE = 0x00000008;  /* VFS only */
+    public static final int SQLITE_OPEN_EXCLUSIVE = 0x00000010;  /* VFS only */
+    public static final int SQLITE_OPEN_MAIN_DB = 0x00000100;  /* VFS only */
+    public static final int SQLITE_OPEN_TEMP_DB = 0x00000200;  /* VFS only */
+    public static final int SQLITE_OPEN_TRANSIENT_DB = 0x00000400;  /* VFS only */
+    public static final int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800;  /* VFS only */
+    public static final int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000;  /* VFS only */
+    public static final int SQLITE_OPEN_SUBJOURNAL = 0x00002000;  /* VFS only */
+    public static final int SQLITE_OPEN_MASTER_JOURNAL = 0x00004000;  /* VFS only */
+    public static final int SQLITE_OPEN_NOMUTEX = 0x00008000;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_OPEN_FULLMUTEX = 0x00010000;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_OPEN_SHAREDCACHE = 0x00020000;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_OPEN_PRIVATECACHE = 0x00040000;  /* Ok for sqlite3_open_v2() */
+    public static final int SQLITE_IOCAP_ATOMIC = 0x00000001;
+    public static final int SQLITE_IOCAP_ATOMIC512 = 0x00000002;
+    public static final int SQLITE_IOCAP_ATOMIC1K = 0x00000004;
+    public static final int SQLITE_IOCAP_ATOMIC2K = 0x00000008;
+    public static final int SQLITE_IOCAP_ATOMIC4K = 0x00000010;
+    public static final int SQLITE_IOCAP_ATOMIC8K = 0x00000020;
+    public static final int SQLITE_IOCAP_ATOMIC16K = 0x00000040;
+    public static final int SQLITE_IOCAP_ATOMIC32K = 0x00000080;
+    public static final int SQLITE_IOCAP_ATOMIC64K = 0x00000100;
+    public static final int SQLITE_IOCAP_SAFE_APPEND = 0x00000200;
+    public static final int SQLITE_IOCAP_SEQUENTIAL = 0x00000400;
+    public static final int SQLITE_LOCK_NONE = 0;
+    public static final int SQLITE_LOCK_SHARED = 1;
+    public static final int SQLITE_LOCK_RESERVED = 2;
+    public static final int SQLITE_LOCK_PENDING = 3;
+    public static final int SQLITE_LOCK_EXCLUSIVE = 4;
+    public static final int SQLITE_SYNC_NORMAL = 0x00002;
+    public static final int SQLITE_SYNC_FULL = 0x00003;
+    public static final int SQLITE_SYNC_DATAONLY = 0x00010;
+    public static final int SQLITE_FCNTL_LOCKSTATE = 1;
+    public static final int SQLITE_GET_LOCKPROXYFILE = 2;
+    public static final int SQLITE_SET_LOCKPROXYFILE = 3;
+    public static final int SQLITE_LAST_ERRNO = 4;
+    public static final int SQLITE_ACCESS_EXISTS = 0;
+    public static final int SQLITE_ACCESS_READWRITE = 1;
+    public static final int SQLITE_ACCESS_READ = 2;
+    public static final int SQLITE_CONFIG_SINGLETHREAD = 1;  /* nil */
+    public static final int SQLITE_CONFIG_MULTITHREAD = 2;  /* nil */
+    public static final int SQLITE_CONFIG_SERIALIZED = 3;  /* nil */
+    public static final int SQLITE_CONFIG_MALLOC = 4;  /* sqlite3_mem_methods* */
+    public static final int SQLITE_CONFIG_GETMALLOC = 5;  /* sqlite3_mem_methods* */
+    public static final int SQLITE_CONFIG_SCRATCH = 6;  /* void*, int sz, int N */
+    public static final int SQLITE_CONFIG_PAGECACHE = 7;  /* void*, int sz, int N */
+    public static final int SQLITE_CONFIG_HEAP = 8;  /* void*, int nByte, int min */
+    public static final int SQLITE_CONFIG_MEMSTATUS = 9;  /* boolean */
+    public static final int SQLITE_CONFIG_MUTEX = 10;  /* sqlite3_mutex_methods* */
+    public static final int SQLITE_CONFIG_GETMUTEX = 11;  /* sqlite3_mutex_methods* */
+    public static final int SQLITE_CONFIG_LOOKASIDE = 13;  /* int int */
+    public static final int SQLITE_CONFIG_PCACHE = 14;  /* sqlite3_pcache_methods* */
+    public static final int SQLITE_CONFIG_GETPCACHE = 15;  /* sqlite3_pcache_methods* */
+    public static final int SQLITE_DBCONFIG_LOOKASIDE = 1001;  /* void* int int */
+    public static final int SQLITE_DENY = 1;   /* Abort the SQL statement with an error */
+    public static final int SQLITE_IGNORE = 2;   /* Don't allow access, but don't generate an error */
+    public static final int SQLITE_CREATE_INDEX = 1;   /* Index Name      Table Name      */
+    public static final int SQLITE_CREATE_TABLE = 2;   /* Table Name      NULL            */
+    public static final int SQLITE_CREATE_TEMP_INDEX = 3;   /* Index Name      Table Name      */
+    public static final int SQLITE_CREATE_TEMP_TABLE = 4;   /* Table Name      NULL            */
+    public static final int SQLITE_CREATE_TEMP_TRIGGER = 5;   /* Trigger Name    Table Name      */
+    public static final int SQLITE_CREATE_TEMP_VIEW = 6;   /* View Name       NULL            */
+    public static final int SQLITE_CREATE_TRIGGER = 7;   /* Trigger Name    Table Name      */
+    public static final int SQLITE_CREATE_VIEW = 8;   /* View Name       NULL            */
+    public static final int SQLITE_DELETE = 9;   /* Table Name      NULL            */
+    public static final int SQLITE_DROP_INDEX = 10;   /* Index Name      Table Name      */
+    public static final int SQLITE_DROP_TABLE = 11;   /* Table Name      NULL            */
+    public static final int SQLITE_DROP_TEMP_INDEX = 12;   /* Index Name      Table Name      */
+    public static final int SQLITE_DROP_TEMP_TABLE = 13;   /* Table Name      NULL            */
+    public static final int SQLITE_DROP_TEMP_TRIGGER = 14;   /* Trigger Name    Table Name      */
+    public static final int SQLITE_DROP_TEMP_VIEW = 15;   /* View Name       NULL            */
+    public static final int SQLITE_DROP_TRIGGER = 16;   /* Trigger Name    Table Name      */
+    public static final int SQLITE_DROP_VIEW = 17;   /* View Name       NULL            */
+    public static final int SQLITE_INSERT = 18;   /* Table Name      NULL            */
+    public static final int SQLITE_PRAGMA = 19;   /* Pragma Name     1st arg or NULL */
+    public static final int SQLITE_READ = 20;   /* Table Name      Column Name     */
+    public static final int SQLITE_SELECT = 21;   /* NULL            NULL            */
+    public static final int SQLITE_TRANSACTION = 22;   /* Operation       NULL            */
+    public static final int SQLITE_UPDATE = 23;   /* Table Name      Column Name     */
+    public static final int SQLITE_ATTACH = 24;   /* Filename        NULL            */
+    public static final int SQLITE_DETACH = 25;   /* Database Name   NULL            */
+    public static final int SQLITE_ALTER_TABLE = 26;   /* Database Name   Table Name      */
+    public static final int SQLITE_REINDEX = 27;   /* Index Name      NULL            */
+    public static final int SQLITE_ANALYZE = 28;   /* Table Name      NULL            */
+    public static final int SQLITE_CREATE_VTABLE = 29;   /* Table Name      Module Name     */
+    public static final int SQLITE_DROP_VTABLE = 30;   /* Table Name      Module Name     */
+    public static final int SQLITE_FUNCTION = 31;   /* NULL            Function Name   */
+    public static final int SQLITE_SAVEPOINT = 32;   /* Operation       Savepoint Name  */
+    public static final int SQLITE_COPY = 0;   /* No longer used */
+    public static final int SQLITE_LIMIT_LENGTH = 0;
+    public static final int SQLITE_LIMIT_SQL_LENGTH = 1;
+    public static final int SQLITE_LIMIT_COLUMN = 2;
+    public static final int SQLITE_LIMIT_EXPR_DEPTH = 3;
+    public static final int SQLITE_LIMIT_COMPOUND_SELECT = 4;
+    public static final int SQLITE_LIMIT_VDBE_OP = 5;
+    public static final int SQLITE_LIMIT_FUNCTION_ARG = 6;
+    public static final int SQLITE_LIMIT_ATTACHED = 7;
+    public static final int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8;
+    public static final int SQLITE_LIMIT_VARIABLE_NUMBER = 9;
+    public static final int SQLITE_LIMIT_TRIGGER_DEPTH = 10;
+    public static final int SQLITE_INTEGER = 1;
+    public static final int SQLITE_FLOAT = 2;
+    public static final int SQLITE_BLOB = 4;
+    public static final int SQLITE_NULL = 5;
+    public static final int SQLITE3_TEXT = 3;
+    public static final int SQLITE_UTF8 = 1;
+    public static final int SQLITE_UTF16LE = 2;
+    public static final int SQLITE_UTF16BE = 3;
+    public static final int SQLITE_UTF16 = 4;    /* Use native byte order */
+    public static final int SQLITE_ANY = 5;    /* sqlite3_create_function only */
+    public static final int SQLITE_UTF16_ALIGNED = 8;    /* sqlite3_create_collation only */
+    public static final int SQLITE_INDEX_CONSTRAINT_EQ = 2;
+    public static final int SQLITE_INDEX_CONSTRAINT_GT = 4;
+    public static final int SQLITE_INDEX_CONSTRAINT_LE = 8;
+    public static final int SQLITE_INDEX_CONSTRAINT_LT = 16;
+    public static final int SQLITE_INDEX_CONSTRAINT_GE = 32;
+    public static final int SQLITE_INDEX_CONSTRAINT_MATCH = 64;
+    public static final int SQLITE_MUTEX_FAST = 0;
+    public static final int SQLITE_MUTEX_RECURSIVE = 1;
+    public static final int SQLITE_MUTEX_STATIC_MASTER = 2;
+    public static final int SQLITE_MUTEX_STATIC_MEM = 3;  /* sqlite3_malloc() */
+    public static final int SQLITE_MUTEX_STATIC_MEM2 = 4;  /* NOT USED */
+    public static final int SQLITE_MUTEX_STATIC_OPEN = 4;  /* sqlite3BtreeOpen() */
+    public static final int SQLITE_MUTEX_STATIC_PRNG = 5;  /* sqlite3_random() */
+    public static final int SQLITE_MUTEX_STATIC_LRU = 6;  /* lru page list */
+    public static final int SQLITE_MUTEX_STATIC_LRU2 = 7;  /* lru page list */
+    public static final int SQLITE_TESTCTRL_FIRST = 5;
+    public static final int SQLITE_TESTCTRL_PRNG_SAVE = 5;
+    public static final int SQLITE_TESTCTRL_PRNG_RESTORE = 6;
+    public static final int SQLITE_TESTCTRL_PRNG_RESET = 7;
+    public static final int SQLITE_TESTCTRL_BITVEC_TEST = 8;
+    public static final int SQLITE_TESTCTRL_FAULT_INSTALL = 9;
+    public static final int SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10;
+    public static final int SQLITE_TESTCTRL_PENDING_BYTE = 11;
+    public static final int SQLITE_TESTCTRL_ASSERT = 12;
+    public static final int SQLITE_TESTCTRL_ALWAYS = 13;
+    public static final int SQLITE_TESTCTRL_RESERVE = 14;
+    public static final int SQLITE_TESTCTRL_OPTIMIZATIONS = 15;
+    public static final int SQLITE_TESTCTRL_ISKEYWORD = 16;
+    public static final int SQLITE_TESTCTRL_LAST = 16;
+    public static final int SQLITE_STATUS_MEMORY_USED = 0;
+    public static final int SQLITE_STATUS_PAGECACHE_USED = 1;
+    public static final int SQLITE_STATUS_PAGECACHE_OVERFLOW = 2;
+    public static final int SQLITE_STATUS_SCRATCH_USED = 3;
+    public static final int SQLITE_STATUS_SCRATCH_OVERFLOW = 4;
+    public static final int SQLITE_STATUS_MALLOC_SIZE = 5;
+    public static final int SQLITE_STATUS_PARSER_STACK = 6;
+    public static final int SQLITE_STATUS_PAGECACHE_SIZE = 7;
+    public static final int SQLITE_STATUS_SCRATCH_SIZE = 8;
+    public static final int SQLITE_DBSTATUS_LOOKASIDE_USED = 0;
+    public static final int SQLITE_STMTSTATUS_FULLSCAN_STEP = 1;
+    public static final int SQLITE_STMTSTATUS_SORT = 2;
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/Database.java b/sqlite-jdbc/src/main/java/SQLite/Database.java
new file mode 100644
index 0000000..200a9bf
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/Database.java
@@ -0,0 +1,904 @@
+package SQLite;
+
+/**
+ * Main class wrapping an SQLite database.
+ */
+
+public class Database {
+
+    /**
+     * Internal handle for the native SQLite API.
+     */
+
+    protected long handle = 0;
+
+    /**
+     * Internal last error code for exec() methods.
+     */
+
+    protected int error_code = 0;
+
+    /**
+     * Open an SQLite database file.
+     *
+     * @param filename the name of the database file
+     * @param mode open mode (e.g. SQLITE_OPEN_READONLY)
+     */
+
+    public void open(String filename, int mode) throws SQLite.Exception {
+	if ((mode & 0200) != 0) {
+	    mode = SQLite.Constants.SQLITE_OPEN_READWRITE |
+		   SQLite.Constants.SQLITE_OPEN_CREATE;
+	} else if ((mode & 0400) != 0) {
+	    mode = SQLite.Constants.SQLITE_OPEN_READONLY;
+	}
+	synchronized(this) {
+	    try {
+		_open4(filename, mode, null, false);
+	    } catch (SQLite.Exception se) {
+		throw se;
+	    } catch (java.lang.OutOfMemoryError me) {
+		throw me;
+	    } catch (Throwable t) {
+		_open(filename, mode);
+	    }
+	}
+    }
+
+    /**
+     * Open an SQLite database file.
+     *
+     * @param filename the name of the database file
+     * @param mode open mode (e.g. SQLITE_OPEN_READONLY)
+     * @param vfs VFS name (for SQLite >= 3.5)
+     */
+
+    public void open(String filename, int mode, String vfs)
+	throws SQLite.Exception {
+	if ((mode & 0200) != 0) {
+	    mode = SQLite.Constants.SQLITE_OPEN_READWRITE |
+		   SQLite.Constants.SQLITE_OPEN_CREATE;
+	} else if ((mode & 0400) != 0) {
+	    mode = SQLite.Constants.SQLITE_OPEN_READONLY;
+	}
+	synchronized(this) {
+	    try {
+		_open4(filename, mode, vfs, false);
+	    } catch (SQLite.Exception se) {
+		throw se;
+	    } catch (java.lang.OutOfMemoryError me) {
+		throw me;
+	    } catch (Throwable t) {
+		_open(filename, mode);
+	    }
+	}
+    }
+
+    /**
+     * Open an SQLite database file.
+     *
+     * @param filename the name of the database file
+     * @param mode open mode (e.g. SQLITE_OPEN_READONLY)
+     * @param vfs VFS name (for SQLite >= 3.5)
+     * @param ver2 flag to force version on create (false = SQLite3, true = SQLite2)
+     */
+
+    public void open(String filename, int mode, String vfs, boolean ver2)
+	throws SQLite.Exception {
+	if ((mode & 0200) != 0) {
+	    mode = SQLite.Constants.SQLITE_OPEN_READWRITE |
+		   SQLite.Constants.SQLITE_OPEN_CREATE;
+	} else if ((mode & 0400) != 0) {
+	    mode = SQLite.Constants.SQLITE_OPEN_READONLY;
+	}
+	synchronized(this) {
+	    try {
+		_open4(filename, mode, vfs, ver2);
+	    } catch (SQLite.Exception se) {
+		throw se;
+	    } catch (java.lang.OutOfMemoryError me) {
+		throw me;
+	    } catch (Throwable t) {
+		_open(filename, mode);
+	    }
+	}
+    }
+
+    /*
+     * For backward compatibility to older sqlite.jar, sqlite_jni
+     */
+
+    private native void _open(String filename, int mode)
+	throws SQLite.Exception;
+
+    /*
+     * Newer full interface
+     */
+
+    private native void _open4(String filename, int mode, String vfs,
+			       boolean ver2)
+	throws SQLite.Exception;
+
+    /**
+     * Open SQLite auxiliary database file for temporary
+     * tables.
+     *
+     * @param filename the name of the auxiliary file or null
+     */
+
+    public void open_aux_file(String filename) throws SQLite.Exception {
+	synchronized(this) {
+	    _open_aux_file(filename);
+	}
+    }
+
+    private native void _open_aux_file(String filename)
+	throws SQLite.Exception;
+
+    /**
+     * Destructor for object.
+     */
+
+    protected void finalize() {
+	synchronized(this) {
+	    _finalize();
+	}
+    }
+
+    private native void _finalize();
+
+    /**
+     * Close the underlying SQLite database file.
+     */
+
+    public void close()	throws SQLite.Exception {
+	synchronized(this) {
+	    _close();
+	}
+    }
+
+    private native void _close()
+	throws SQLite.Exception;
+
+    /**
+     * Execute an SQL statement and invoke callback methods
+     * for each row of the result set.<P>
+     *
+     * It the method fails, an SQLite.Exception is thrown and
+     * an error code is set, which later can be retrieved by
+     * the last_error() method.
+     *
+     * @param sql the SQL statement to be executed
+     * @param cb the object implementing the callback methods
+     */
+
+    public void exec(String sql, SQLite.Callback cb) throws SQLite.Exception {
+	synchronized(this) {
+	    _exec(sql, cb);
+	}
+    }
+
+    private native void _exec(String sql, SQLite.Callback cb)
+	throws SQLite.Exception;
+
+    /**
+     * Execute an SQL statement and invoke callback methods
+     * for each row of the result set. Each '%q' or %Q in the
+     * statement string is substituted by its corresponding
+     * element in the argument vector.
+     * <BR><BR>
+     * Example:<BR>
+     * <PRE>
+     *   String args[] = new String[1];
+     *   args[0] = "tab%";
+     *   db.exec("select * from sqlite_master where type like '%q'",
+     *           null, args);
+     * </PRE>
+     *
+     * It the method fails, an SQLite.Exception is thrown and
+     * an error code is set, which later can be retrieved by
+     * the last_error() method.
+     *
+     * @param sql the SQL statement to be executed
+     * @param cb the object implementing the callback methods
+     * @param args arguments for the SQL statement, '%q' substitution
+     */
+
+    public void exec(String sql, SQLite.Callback cb,
+		     String args[]) throws SQLite.Exception {
+	synchronized(this) {
+	    _exec(sql, cb, args);
+	}
+    }
+
+    private native void _exec(String sql, SQLite.Callback cb, String args[])
+	throws SQLite.Exception;
+
+    /**
+     * Return the row identifier of the last inserted
+     * row.
+     */
+
+    public long last_insert_rowid() {
+	synchronized(this) {
+	    return _last_insert_rowid();
+	}
+    }
+
+    private native long _last_insert_rowid();
+
+    /**
+     * Abort the current SQLite operation.
+     */
+
+    public void interrupt() {
+	synchronized(this) {
+	    _interrupt();
+	}
+    }
+
+    private native void _interrupt();
+
+    /**
+     * Return the number of changed rows for the last statement.
+     */
+
+    public long changes() {
+	synchronized(this) {
+	    return _changes();
+	}
+    }
+
+    private native long _changes();
+
+    /**
+     * Establish a busy callback method which gets called when
+     * an SQLite table is locked.
+     *
+     * @param bh the object implementing the busy callback method
+     */
+
+    public void busy_handler(SQLite.BusyHandler bh) {
+	synchronized(this) {
+	    _busy_handler(bh);
+	}
+    }
+
+    private native void _busy_handler(SQLite.BusyHandler bh);
+
+    /**
+     * Set the timeout for waiting for an SQLite table to become
+     * unlocked.
+     *
+     * @param ms number of millisecond to wait
+     */
+
+    public void busy_timeout(int ms) {
+	synchronized(this) {
+	    _busy_timeout(ms);
+	}
+    }
+
+    private native void _busy_timeout(int ms);
+
+    /**
+     * Convenience method to retrieve an entire result
+     * set into memory.
+     *
+     * @param sql the SQL statement to be executed
+     * @param maxrows the max. number of rows to retrieve
+     * @return result set
+     */
+
+    public TableResult get_table(String sql, int maxrows)
+	throws SQLite.Exception {
+	TableResult ret = new TableResult(maxrows);
+	if (!is3()) {
+	    try {
+		exec(sql, ret);
+	    } catch (SQLite.Exception e) {
+		if (maxrows <= 0 || !ret.atmaxrows) {
+		    throw e;
+		}
+	    }
+	} else {
+	    synchronized(this) {
+		/* only one statement !!! */
+		Vm vm = compile(sql);
+		set_last_error(vm.error_code);
+		if (ret.maxrows > 0) {
+		    while (ret.nrows < ret.maxrows && vm.step(ret)) {
+			set_last_error(vm.error_code);
+		    }
+		} else {
+		    while (vm.step(ret)) {
+			set_last_error(vm.error_code);
+		    }
+		}
+		vm.finalize();
+	    }
+	}
+	return ret;
+    }
+
+    /**
+     * Convenience method to retrieve an entire result
+     * set into memory.
+     *
+     * @param sql the SQL statement to be executed
+     * @return result set
+     */
+
+    public TableResult get_table(String sql) throws SQLite.Exception {
+	return get_table(sql, 0);
+    }
+
+    /**
+     * Convenience method to retrieve an entire result
+     * set into memory.
+     *
+     * @param sql the SQL statement to be executed
+     * @param maxrows the max. number of rows to retrieve
+     * @param args arguments for the SQL statement, '%q' substitution
+     * @return result set
+     */
+
+    public TableResult get_table(String sql, int maxrows, String args[])
+	throws SQLite.Exception {
+	TableResult ret = new TableResult(maxrows);
+	if (!is3()) {
+	    try {
+		exec(sql, ret, args);
+	    } catch (SQLite.Exception e) {
+		if (maxrows <= 0 || !ret.atmaxrows) {
+		    throw e;
+		}
+	    }
+	} else {
+	    synchronized(this) {
+		/* only one statement !!! */
+		Vm vm = compile(sql, args);
+		set_last_error(vm.error_code);
+		if (ret.maxrows > 0) {
+		    while (ret.nrows < ret.maxrows && vm.step(ret)) {
+			set_last_error(vm.error_code);
+		    }
+		} else {
+		    while (vm.step(ret)) {
+			set_last_error(vm.error_code);
+		    }
+		}
+		vm.finalize();
+	    }
+	}
+	return ret;
+    }
+
+    /**
+     * Convenience method to retrieve an entire result
+     * set into memory.
+     *
+     * @param sql the SQL statement to be executed
+     * @param args arguments for the SQL statement, '%q' substitution
+     * @return result set
+     */
+
+    public TableResult get_table(String sql, String args[])
+	throws SQLite.Exception {
+	return get_table(sql, 0, args);
+    }
+
+    /**
+     * Convenience method to retrieve an entire result
+     * set into memory.
+     *
+     * @param sql the SQL statement to be executed
+     * @param args arguments for the SQL statement, '%q' substitution
+     * @param tbl TableResult to receive result set
+     * @return result set
+     */
+
+    public void get_table(String sql, String args[], TableResult tbl)
+	throws SQLite.Exception {
+	tbl.clear();
+	if (!is3()) {
+	    try {
+		exec(sql, tbl, args);
+	    } catch (SQLite.Exception e) {
+		if (tbl.maxrows <= 0 || !tbl.atmaxrows) {
+		    throw e;
+		}
+	    }
+	} else {
+	    synchronized(this) {
+		/* only one statement !!! */
+		Vm vm = compile(sql, args);
+		if (tbl.maxrows > 0) {
+		    while (tbl.nrows < tbl.maxrows && vm.step(tbl)) {
+			set_last_error(vm.error_code);
+		    }
+		} else {
+		    while (vm.step(tbl)) {
+			set_last_error(vm.error_code);
+		    }
+		}
+		vm.finalize();
+	    }
+	}
+    }
+
+    /**
+     * See if an SQL statement is complete.
+     * Returns true if the input string comprises
+     * one or more complete SQL statements.
+     *
+     * @param sql the SQL statement to be checked
+     */
+
+    public synchronized static boolean complete(String sql) {
+	return _complete(sql);
+    }
+
+    private native static boolean _complete(String sql);
+
+    /**
+     * Return SQLite version number as string.
+     * Don't rely on this when both SQLite 2 and 3 are compiled
+     * into the native part. Use the class method in this case.
+     */
+
+    public native static String version();
+
+    /**
+     * Return SQLite version number as string.
+     * If the database is not open, <tt>unknown</tt> is returned.
+     */
+
+    public native String dbversion();
+
+    /**
+     * Create regular function.
+     *
+     * @param name the name of the new function
+     * @param nargs number of arguments to function
+     * @param f interface of function
+     */
+
+    public void create_function(String name, int nargs, Function f) {
+	synchronized(this) {
+	    _create_function(name, nargs, f);
+	}
+    }
+
+    private native void _create_function(String name, int nargs, Function f);
+
+    /**
+     * Create aggregate function.
+     *
+     * @param name the name of the new function
+     * @param nargs number of arguments to function
+     * @param f interface of function
+     */
+
+    public void create_aggregate(String name, int nargs, Function f) {
+	synchronized(this) {
+	    _create_aggregate(name, nargs, f);
+	}
+    }
+
+    private native void _create_aggregate(String name, int nargs, Function f);
+
+    /**
+     * Set function return type. Only available in SQLite 2.6.0 and
+     * above, otherwise a no-op.
+     *
+     * @param name the name of the function whose return type is to be set
+     * @param type return type code, e.g. SQLite.Constants.SQLITE_NUMERIC
+     */
+
+    public void function_type(String name, int type) {
+	synchronized(this) {
+	    _function_type(name, type);
+	}
+    }
+
+    private native void _function_type(String name, int type);
+
+    /**
+     * Return the code of the last error occured in
+     * any of the exec() methods. The value is valid
+     * after an Exception has been reported by one of
+     * these methods. See the <A HREF="Constants.html">Constants</A>
+     * class for possible values.
+     *
+     * @return SQLite error code
+     */
+
+    public int last_error() {
+	return error_code;
+    }
+
+    /**
+     * Internal: set error code.
+     * @param error_code new error code
+     */
+
+    protected void set_last_error(int error_code) {
+	this.error_code = error_code;
+    }
+
+    /**
+     * Return last error message of SQLite3 engine.
+     *
+     * @return error string or null
+     */
+
+    public String error_message() {
+	synchronized(this) {
+	    return _errmsg();
+	}
+    }
+
+    private native String _errmsg();
+
+    /**
+     * Return error string given SQLite error code (SQLite2).
+     *
+     * @param error_code the error code
+     * @return error string
+     */
+
+    public static native String error_string(int error_code);
+
+    /**
+     * Set character encoding.
+     * @param enc name of encoding
+     */
+
+    public void set_encoding(String enc) throws SQLite.Exception {
+	synchronized(this) {
+	    _set_encoding(enc);
+	}
+    }
+
+    private native void _set_encoding(String enc)
+	throws SQLite.Exception;
+
+    /**
+     * Set authorizer function. Only available in SQLite 2.7.6 and
+     * above, otherwise a no-op.
+     *
+     * @param auth the authorizer function
+     */
+
+    public void set_authorizer(Authorizer auth) {
+	synchronized(this) {
+	    _set_authorizer(auth);
+	}
+    }
+
+    private native void _set_authorizer(Authorizer auth);
+
+    /**
+     * Set trace function. Only available in SQLite 2.7.6 and above,
+     * otherwise a no-op.
+     *
+     * @param tr the trace function
+     */
+
+    public void trace(Trace tr) {
+	synchronized(this) {
+	    _trace(tr);
+	}
+    }
+
+    private native void _trace(Trace tr);
+
+    /**
+     * Compile and return SQLite VM for SQL statement. Only available
+     * in SQLite 2.8.0 and above, otherwise a no-op.
+     *
+     * @param sql SQL statement to be compiled
+     * @return a Vm object
+     */
+
+    public Vm compile(String sql) throws SQLite.Exception {
+	synchronized(this) {
+	    Vm vm = new Vm();
+	    vm_compile(sql, vm);
+	    return vm;
+	}
+    }
+
+    /**
+     * Compile and return SQLite VM for SQL statement. Only available
+     * in SQLite 3.0 and above, otherwise a no-op.
+     *
+     * @param sql SQL statement to be compiled
+     * @param args arguments for the SQL statement, '%q' substitution
+     * @return a Vm object
+     */
+
+    public Vm compile(String sql, String args[]) throws SQLite.Exception {
+	synchronized(this) {
+	    Vm vm = new Vm();
+	    vm_compile_args(sql, vm, args);
+	    return vm;
+	}
+    }
+
+    /**
+     * Prepare and return SQLite3 statement for SQL. Only available
+     * in SQLite 3.0 and above, otherwise a no-op.
+     *
+     * @param sql SQL statement to be prepared
+     * @return a Stmt object
+     */
+
+    public Stmt prepare(String sql) throws SQLite.Exception {
+	synchronized(this) {
+	    Stmt stmt = new Stmt();
+	    stmt_prepare(sql, stmt);
+	    return stmt;
+	}
+    }
+
+    /**
+     * Open an SQLite3 blob. Only available in SQLite 3.4.0 and above.
+     * @param db database name
+     * @param table table name
+     * @param column column name
+     * @param row row identifier
+     * @param rw if true, open for read-write, else read-only
+     * @return a Blob object
+     */
+
+    public Blob open_blob(String db, String table, String column,
+			  long row, boolean rw) throws SQLite.Exception {
+	synchronized(this) {
+	    Blob blob = new Blob();
+	    _open_blob(db, table, column, row, rw, blob);
+	    return blob;
+	}
+    }
+
+    /**
+     * Check type of open database.
+     * @return true if SQLite3 database
+     */
+
+    public native boolean is3();
+
+    /**
+     * Internal compile method.
+     * @param sql SQL statement
+     * @param vm Vm object
+     */
+
+    private native void vm_compile(String sql, Vm vm)
+	throws SQLite.Exception;
+
+    /**
+     * Internal compile method, SQLite 3.0 only.
+     * @param sql SQL statement
+     * @param args arguments for the SQL statement, '%q' substitution
+     * @param vm Vm object
+     */
+
+    private native void vm_compile_args(String sql, Vm vm, String args[])
+	throws SQLite.Exception;
+
+    /**
+     * Internal SQLite3 prepare method.
+     * @param sql SQL statement
+     * @param stmt Stmt object
+     */
+
+    private native void stmt_prepare(String sql, Stmt stmt)
+	throws SQLite.Exception;
+
+    /**
+     * Internal SQLite open blob method.
+     * @param db database name
+     * @param table table name
+     * @param column column name
+     * @param row row identifier
+     * @param rw if true, open for read-write, else read-only
+     * @param blob Blob object
+     */
+
+    private native void _open_blob(String db, String table, String column,
+				   long row, boolean rw, Blob blob)
+	throws SQLite.Exception;
+
+    /**
+     * Establish a progress callback method which gets called after
+     * N SQLite VM opcodes.
+     *
+     * @param n number of SQLite VM opcodes until callback is invoked
+     * @param p the object implementing the progress callback method
+     */
+
+    public void progress_handler(int n, SQLite.ProgressHandler p) {
+	synchronized(this) {
+	    _progress_handler(n, p);
+	}
+    }
+
+    private native void _progress_handler(int n, SQLite.ProgressHandler p);
+
+    /**
+     * Specify key for encrypted database. To be called
+     * right after open() on SQLite3 databases.
+     * Not available in public releases of SQLite.
+     *
+     * @param ekey the key as byte array
+     */
+
+    public void key(byte[] ekey) throws SQLite.Exception {
+	synchronized(this) {
+	    _key(ekey);
+	}
+    }
+
+    /**
+     * Specify key for encrypted database. To be called
+     * right after open() on SQLite3 databases.
+     * Not available in public releases of SQLite.
+     *
+     * @param skey the key as String
+     */
+
+    public void key(String skey) throws SQLite.Exception {
+	synchronized(this) {
+	    byte ekey[] = null;
+	    if (skey != null && skey.length() > 0) {
+		ekey = new byte[skey.length()];
+		for (int i = 0; i< skey.length(); i++) {
+		    char c = skey.charAt(i);
+		    ekey[i] = (byte) ((c & 0xff) ^ (c >> 8));
+		}
+	    }
+	    _key(ekey);
+	}
+    }
+
+    private native void _key(byte[] ekey);
+
+    /**
+     * Change the key of a encrypted database. The
+     * SQLite3 database must have been open()ed.
+     * Not available in public releases of SQLite.
+     *
+     * @param ekey the key as byte array
+     */
+
+    public void rekey(byte[] ekey) throws SQLite.Exception {
+	synchronized(this) {
+	    _rekey(ekey);
+	}
+    }
+
+    /**
+     * Change the key of a encrypted database. The
+     * SQLite3 database must have been open()ed.
+     * Not available in public releases of SQLite.
+     *
+     * @param skey the key as String
+     */
+
+    public void rekey(String skey) throws SQLite.Exception {
+	synchronized(this) {
+	    byte ekey[] = null;
+	    if (skey != null && skey.length() > 0) {
+		ekey = new byte[skey.length()];
+		for (int i = 0; i< skey.length(); i++) {
+		    char c = skey.charAt(i);
+		    ekey[i] = (byte) ((c & 0xff) ^ (c >> 8));
+		}
+	    }
+	    _rekey(ekey);
+	}
+    }
+
+    private native void _rekey(byte[] ekey);
+
+    /**
+     * Enable/disable shared cache mode (SQLite 3.x only).
+     *
+     * @param onoff boolean to enable or disable shared cache
+     * @return boolean when true, function supported/succeeded
+     */
+
+    protected static native boolean _enable_shared_cache(boolean onoff);
+
+    /**
+     * Internal native initializer.
+     */
+
+    private static native void internal_init();
+
+    /**
+     * Make long value from julian date for java.lang.Date
+     *
+     * @param d double value (julian date in SQLite3 format)
+     * @return long
+     */
+
+    public static long long_from_julian(double d) {
+	d -= 2440587.5;
+	d *= 86400000.0;
+	return (long) d;
+    }
+
+    /**
+     * Make long value from julian date for java.lang.Date
+     *
+     * @param s string (double value) (julian date in SQLite3 format)
+     * @return long
+     */
+
+    public static long long_from_julian(String s) throws SQLite.Exception {
+	try {
+	    double d = Double.parseDouble(s); // android-changed: performance
+	    return long_from_julian(d);
+	} catch (java.lang.Exception ee) {
+	    throw new SQLite.Exception("not a julian date");
+	}
+    }
+
+    /**
+     * Make julian date value from java.lang.Date
+     *
+     * @param ms millisecond value of java.lang.Date
+     * @return double
+     */
+
+    public static double julian_from_long(long ms) {
+	double adj = (ms < 0) ? 0 : 0.5;
+	double d = (ms + adj) / 86400000.0 + 2440587.5;
+	return d;
+    }
+
+    /**
+     * Static initializer to load the native part.
+     */
+
+    static {
+	try {
+	    String path = System.getProperty("SQLite.library.path");
+	    if (path == null || path.length() == 0) {
+		System.loadLibrary("sqlite_jni");
+	    } else {
+		try {
+		    java.lang.reflect.Method mapLibraryName;
+		    Class param[] = new Class[1];
+		    param[0] = String.class;
+		    mapLibraryName = System.class.getMethod("mapLibraryName",
+							    param);
+		    Object args[] = new Object[1];
+		    args[0] = "sqlite_jni";
+		    String mapped = (String) mapLibraryName.invoke(null, args);
+		    System.load(path + java.io.File.separator + mapped);
+		} catch (Throwable t) {
+		    System.err.println("Unable to load sqlite_jni from" +
+				       "SQLite.library.path=" + path +
+				       ", trying system default: " + t);
+		    System.loadLibrary("sqlite_jni");
+		}
+	    }
+	} catch (Throwable t) {
+	    System.err.println("Unable to load sqlite_jni: " + t);
+	}
+	/*
+	 * Call native initializer functions now, since the
+	 * native part could have been linked statically, i.e.
+	 * the try/catch above would have failed in that case.
+	 */
+	try {
+	    internal_init();
+	    new FunctionContext();
+	} catch (java.lang.Exception e) {
+	}
+    }
+}
diff --git a/sql/src/main/java/SQLite/Exception.java b/sqlite-jdbc/src/main/java/SQLite/Exception.java
similarity index 93%
rename from sql/src/main/java/SQLite/Exception.java
rename to sqlite-jdbc/src/main/java/SQLite/Exception.java
index cc26b99..589fa4b 100644
--- a/sql/src/main/java/SQLite/Exception.java
+++ b/sqlite-jdbc/src/main/java/SQLite/Exception.java
@@ -13,6 +13,6 @@
      */
 
     public Exception(String string) {
-    super(string);
+	super(string);
     }
 }
diff --git a/sql/src/main/java/SQLite/Function.java b/sqlite-jdbc/src/main/java/SQLite/Function.java
similarity index 100%
rename from sql/src/main/java/SQLite/Function.java
rename to sqlite-jdbc/src/main/java/SQLite/Function.java
diff --git a/sql/src/main/java/SQLite/FunctionContext.java b/sqlite-jdbc/src/main/java/SQLite/FunctionContext.java
similarity index 98%
rename from sql/src/main/java/SQLite/FunctionContext.java
rename to sqlite-jdbc/src/main/java/SQLite/FunctionContext.java
index d0b5182..8509b4d 100644
--- a/sql/src/main/java/SQLite/FunctionContext.java
+++ b/sqlite-jdbc/src/main/java/SQLite/FunctionContext.java
@@ -77,6 +77,6 @@
     private static native void internal_init();
 
     static {
-    internal_init();
+	internal_init();
     }
 }
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java
new file mode 100644
index 0000000..67e95da
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java
@@ -0,0 +1,516 @@
+package SQLite.JDBC2y;
+
+import java.sql.*;
+import java.util.*;
+
+public class JDBCConnection
+    implements java.sql.Connection, SQLite.BusyHandler {
+
+    /**
+     * Open database.
+     */
+    protected DatabaseX db;
+
+    /**
+     * Database URL.
+     */
+    protected String url;
+
+    /**
+     * Character encoding.
+     */
+    protected String enc;
+
+    /**
+     * SQLite 3 VFS to use.
+     */
+    protected String vfs;
+
+    /**
+     * Autocommit flag, true means autocommit.
+     */
+    protected boolean autocommit = true;
+
+    /**
+     * In-transaction flag.
+     * Can be true only when autocommit false.
+     */
+    protected boolean intrans = false;
+
+    /**
+     * Timeout for Database.exec()
+     */
+    protected int timeout = 1000000;
+
+    /**
+     * Use double/julian date representation.
+     */
+    protected boolean useJulian = false;
+
+    /**
+     * File name of database.
+     */
+    private String dbfile = null;
+
+    /**
+     * Reference to meta data or null.
+     */
+    private JDBCDatabaseMetaData meta = null;
+
+    /**
+     * Base time value for timeout handling.
+     */
+    private long t0;
+
+    /**
+     * Database in readonly mode.
+     */
+    private boolean readonly = false;
+
+    /**
+     * Transaction isolation mode.
+     */
+    private int trmode = TRANSACTION_SERIALIZABLE;
+
+    private boolean busy0(DatabaseX db, int count) {
+	if (count <= 1) {
+	    t0 = System.currentTimeMillis();
+	}
+	if (db != null) {
+	    long t1 = System.currentTimeMillis();
+	    if (t1 - t0 > timeout) {
+		return false;
+	    }
+	    db.wait(100);
+	    return true;
+	}
+	return false;
+    }
+
+    public boolean busy(String table, int count) {
+	return busy0(db, count);
+    }
+
+    protected boolean busy3(DatabaseX db, int count) {
+	if (count <= 1) {
+	    t0 = System.currentTimeMillis();
+	}
+	if (db != null) {
+	    long t1 = System.currentTimeMillis();
+	    if (t1 - t0 > timeout) {
+		return false;
+	    }
+	    return true;
+	}
+	return false;
+    }
+
+    private DatabaseX open(boolean readonly) throws SQLException {
+	DatabaseX dbx = null;
+	try {
+	    dbx = new DatabaseX();
+	    dbx.open(dbfile, readonly ? SQLite.Constants.SQLITE_OPEN_READONLY :
+		     (SQLite.Constants.SQLITE_OPEN_READWRITE |
+		      SQLite.Constants.SQLITE_OPEN_CREATE), vfs);
+	    dbx.set_encoding(enc);
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.toString());
+	}
+	int loop = 0;
+	while (true) {
+	    try {
+		dbx.exec("PRAGMA short_column_names = off;", null);
+		dbx.exec("PRAGMA full_column_names = on;", null);
+		dbx.exec("PRAGMA empty_result_callbacks = on;", null);
+		if (SQLite.Database.version().compareTo("2.6.0") >= 0) {
+		    dbx.exec("PRAGMA show_datatypes = on;", null);
+		}
+	    } catch (SQLite.Exception e) {
+		if (dbx.last_error() != SQLite.Constants.SQLITE_BUSY ||
+		    !busy0(dbx, ++loop)) {
+		    try {
+			dbx.close();
+		    } catch (SQLite.Exception ee) {
+		    }
+		    throw new SQLException(e.toString());
+		}
+		continue;
+	    }
+	    break;
+	}
+	return dbx;
+    }
+
+    public JDBCConnection(String url, String enc, String pwd, String drep,
+			  String vfs)
+	throws SQLException {
+	if (url.startsWith("sqlite:/")) {
+	    dbfile = url.substring(8);
+	} else if (url.startsWith("jdbc:sqlite:/")) {
+	    dbfile = url.substring(13);
+	} else {
+	    throw new SQLException("unsupported url");
+	}
+	this.url = url;
+	this.enc = enc;
+	this.vfs = vfs;
+	try {
+	    db = open(readonly);
+	    try {
+		if (pwd != null && pwd.length() > 0) {
+		    db.key(pwd);
+		}
+	    } catch (SQLite.Exception se) {
+		throw new SQLException("error while setting key");
+	    }
+	    db.busy_handler(this);
+	} catch (SQLException e) {
+	    if (db != null) {
+		try {
+		    db.close();
+		} catch (SQLite.Exception ee) {
+		}
+	    }
+	    throw e;
+	}
+	useJulian = drep != null &&
+	    (drep.startsWith("j") || drep.startsWith("J"));
+    }
+
+    /* non-standard */
+    public SQLite.Database getSQLiteDatabase() {
+	return (SQLite.Database) db;
+    }
+  
+    public Statement createStatement() {
+	JDBCStatement s = new JDBCStatement(this);
+	return s;
+    }
+
+    public Statement createStatement(int resultSetType,
+				     int resultSetConcurrency)
+	throws SQLException {
+	if (resultSetType != ResultSet.TYPE_FORWARD_ONLY &&
+	    resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE &&
+	    resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
+	    throw new SQLException("unsupported result set type");
+	}
+	if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
+	    resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
+	    throw new SQLException("unsupported result set concurrency");
+	}
+	JDBCStatement s = new JDBCStatement(this);
+	return s;
+    }
+	
+    public DatabaseMetaData getMetaData() throws SQLException {
+	if (meta == null) {
+	    meta = new JDBCDatabaseMetaData(this);
+	}
+	return meta;
+    }
+
+    public void close() throws SQLException {
+	try {
+	    rollback();
+	} catch (SQLException e) {
+	    /* ignored */
+	}
+	intrans = false;
+	if (db != null) {
+	    try {
+		db.close();
+		db = null;
+	    } catch (SQLite.Exception e) {
+		throw new SQLException(e.toString());
+	    }
+	}
+    }
+
+    public boolean isClosed() throws SQLException {
+	return db == null;
+    }
+
+    public boolean isReadOnly() throws SQLException {
+	return readonly;
+    }
+
+    public void clearWarnings() throws SQLException {
+    }
+
+    public void commit() throws SQLException {
+	if (db == null) {
+	    throw new SQLException("stale connection");
+	}
+	if (!intrans) {
+	    return;
+	}
+	try {
+	    db.exec("COMMIT", null);
+	    intrans = false;
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.toString());
+	}
+    }
+
+    public boolean getAutoCommit() throws SQLException {
+	return autocommit;
+    }
+
+    public String getCatalog() throws SQLException {
+	return null;
+    }
+
+    public int getTransactionIsolation() throws SQLException {
+	return trmode;
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+	return null;
+    }
+
+    public String nativeSQL(String sql) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public CallableStatement prepareCall(String sql) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public CallableStatement prepareCall(String sql, int x, int y)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+	JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
+	return s;
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+					      int resultSetConcurrency)
+	throws SQLException {
+	if (resultSetType != ResultSet.TYPE_FORWARD_ONLY &&
+	    resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE &&
+	    resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
+	    throw new SQLException("unsupported result set type");
+	}
+	if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
+	    resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
+	    throw new SQLException("unsupported result set concurrency");
+	}
+	JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
+	return s;
+    }
+
+    public void rollback() throws SQLException {
+	if (db == null) {
+	    throw new SQLException("stale connection");
+	}
+	if (!intrans) {
+	    return;
+	}
+	try {
+	    db.exec("ROLLBACK", null);
+	    intrans = false;
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.toString());
+	}
+    }
+
+    public void setAutoCommit(boolean ac) throws SQLException {
+	if (ac && intrans && db != null) {
+	    try {
+		db.exec("ROLLBACK", null);
+	    } catch (SQLite.Exception e) {
+		throw new SQLException(e.toString());
+	    } finally {
+		intrans = false;
+	    }
+	}
+	autocommit = ac;
+    }
+
+    public void setCatalog(String catalog) throws SQLException {
+    }
+
+    public void setReadOnly(boolean ro) throws SQLException {
+	if (intrans) {
+	    throw new SQLException("incomplete transaction");
+	}
+	if (ro != readonly) {
+	    DatabaseX dbx = null;
+	    try {
+		dbx = open(ro);
+		db.close();
+		db = dbx;
+		dbx = null;
+		readonly = ro;
+	    } catch (SQLException e) {
+		throw e;
+	    } catch (SQLite.Exception ee) {
+		if (dbx != null) {
+		    try {
+			dbx.close();
+		    } catch (SQLite.Exception eee) {
+		    }
+		}
+		throw new SQLException(ee.toString());
+	    }
+	}
+    }
+
+    public void setTransactionIsolation(int level) throws SQLException {
+	if (db.is3() && SQLite.JDBCDriver.sharedCache) {
+	    String flag = null;
+	    if (level == TRANSACTION_READ_UNCOMMITTED &&
+		trmode != TRANSACTION_READ_UNCOMMITTED) {
+		flag = "on";
+	    } else if (level == TRANSACTION_SERIALIZABLE &&
+		       trmode != TRANSACTION_SERIALIZABLE) {
+		flag = "off";
+	    }
+	    if (flag != null) {
+		try {
+		    db.exec("PRAGMA read_uncommitted = " + flag + ";", null);
+		    trmode = level;
+		} catch (java.lang.Exception e) {
+		}
+	    }
+	}
+	if (level != trmode) {
+	    throw new SQLException("not supported");
+	}
+    }
+
+    public java.util.Map<String, Class<?>> getTypeMap() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setTypeMap(java.util.Map map) throws SQLException {
+	throw new SQLException("not supported");
+    }
+  
+    public int getHoldability() throws SQLException {
+	return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+    }
+
+    public void setHoldability(int holdability) throws SQLException {
+	if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) {
+	    return;
+	}
+	throw new SQLException("not supported");
+    }
+
+    public Savepoint setSavepoint() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Savepoint setSavepoint(String name) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void rollback(Savepoint x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void releaseSavepoint(Savepoint x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Statement createStatement(int resultSetType,
+				     int resultSetConcurrency,
+				     int resultSetHoldability)
+	throws SQLException {
+	if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
+	    throw new SQLException("not supported");
+	}
+	return createStatement(resultSetType, resultSetConcurrency);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+					      int resultSetConcurrency,
+					      int resultSetHoldability)
+	throws SQLException {
+	if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
+	    throw new SQLException("not supported");
+	}
+	return prepareStatement(sql, resultSetType, resultSetConcurrency);
+    }
+
+    public CallableStatement prepareCall(String sql, int x, int y, int z)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public PreparedStatement prepareStatement(String sql, int autokeys)
+	throws SQLException {
+	if (autokeys != Statement.NO_GENERATED_KEYS) {
+	    throw new SQLException("not supported");
+	}
+	return prepareStatement(sql);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int colIndexes[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public PreparedStatement prepareStatement(String sql, String columns[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+}
+
+class DatabaseX extends SQLite.Database {
+
+    static Object lock = new Object();
+
+    public DatabaseX() {
+	super();
+    }
+
+    void wait(int ms) {
+	try {
+	    synchronized (lock) {
+		lock.wait(ms);
+	    }
+	} catch (java.lang.Exception e) {
+	}
+    }
+
+    public void exec(String sql, SQLite.Callback cb)
+	throws SQLite.Exception {
+	super.exec(sql, cb);
+	synchronized (lock) {
+	    lock.notifyAll();
+	}
+    }
+
+    public void exec(String sql, SQLite.Callback cb, String args[])
+	throws SQLite.Exception {
+	super.exec(sql, cb, args);
+	synchronized (lock) {
+	    lock.notifyAll();
+	}
+    }
+
+    public SQLite.TableResult get_table(String sql, String args[])
+	throws SQLite.Exception {
+	SQLite.TableResult ret = super.get_table(sql, args);
+	synchronized (lock) {
+	    lock.notifyAll();
+	}
+	return ret;
+    }
+
+    public void get_table(String sql, String args[], SQLite.TableResult tbl)
+	throws SQLite.Exception {
+	super.get_table(sql, args, tbl);
+	synchronized (lock) {
+	    lock.notifyAll();
+	}
+    }
+
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java
new file mode 100644
index 0000000..8d76173
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java
@@ -0,0 +1,1648 @@
+package SQLite.JDBC2y;
+
+import java.sql.*;
+import java.util.Hashtable;
+
+public class JDBCDatabaseMetaData implements DatabaseMetaData {
+
+    private JDBCConnection conn;
+
+    public JDBCDatabaseMetaData(JDBCConnection conn) {
+	this.conn = conn;
+    }
+
+    public boolean allProceduresAreCallable() throws SQLException {
+	return false;
+    }
+
+    public boolean allTablesAreSelectable() throws SQLException {
+	return true;
+    }
+
+    public String getURL() throws SQLException {
+	return conn.url;
+    }
+
+    public String getUserName() throws SQLException {
+	return "";
+    }
+
+    public boolean isReadOnly() throws SQLException {
+	return false;
+    }
+
+    public boolean nullsAreSortedHigh() throws SQLException {
+	return false;
+    }
+
+    public boolean nullsAreSortedLow() throws SQLException {
+	return false;
+    }
+
+    public boolean nullsAreSortedAtStart() throws SQLException {
+	return false;
+    }
+
+    public boolean nullsAreSortedAtEnd() throws SQLException {
+	return false;
+    }
+
+    public String getDatabaseProductName() throws SQLException {
+	return "SQLite";
+    }
+
+    public String getDatabaseProductVersion() throws SQLException {
+	return SQLite.Database.version();
+    }
+
+    public String getDriverName() throws SQLException {
+	return "SQLite/JDBC";
+    }
+
+    public String getDriverVersion() throws SQLException {
+	return "" + SQLite.JDBCDriver.MAJORVERSION + "." +
+	    SQLite.Constants.drv_minor;
+    }
+
+    public int getDriverMajorVersion() {
+	return SQLite.JDBCDriver.MAJORVERSION;
+    }
+
+    public int getDriverMinorVersion() {
+	return SQLite.Constants.drv_minor;
+    }
+
+    public boolean usesLocalFiles() throws SQLException {
+	return true;
+    }
+
+    public boolean usesLocalFilePerTable() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsMixedCaseIdentifiers() throws SQLException {
+	return false;
+    }
+
+    public boolean storesUpperCaseIdentifiers() throws SQLException {
+	return false;
+    }
+
+    public boolean storesLowerCaseIdentifiers() throws SQLException {
+	return false;
+    }
+
+    public boolean storesMixedCaseIdentifiers() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+	return false;
+    }
+
+    public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+	return false;
+    }
+
+    public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+	return false;
+    }
+
+    public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+	return true;
+    }
+
+    public String getIdentifierQuoteString() throws SQLException {
+	return "\"";
+    }
+
+    public String getSQLKeywords() throws SQLException {
+	return "SELECT,UPDATE,CREATE,TABLE,VIEW,DELETE,FROM,WHERE" +
+	    ",COMMIT,ROLLBACK,TRIGGER";
+    }
+
+    public String getNumericFunctions() throws SQLException {
+	return ""; 
+    }
+
+    public String getStringFunctions() throws SQLException {
+	return "";
+    }
+
+    public String getSystemFunctions() throws SQLException {
+	return "";
+    }
+
+    public String getTimeDateFunctions() throws SQLException {
+	return "";
+    }
+
+    public String getSearchStringEscape() throws SQLException {
+	return "\\";
+    }
+
+    public String getExtraNameCharacters() throws SQLException {
+	return "";
+    }
+
+    public boolean supportsAlterTableWithAddColumn() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsAlterTableWithDropColumn() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsColumnAliasing() throws SQLException {
+	return true;
+    }
+
+    public boolean nullPlusNonNullIsNull() throws SQLException {
+	return false;
+    }
+    
+    public boolean supportsConvert() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsConvert(int fromType, int toType)
+	throws SQLException {
+	return false;
+    }
+
+    public boolean supportsTableCorrelationNames() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsDifferentTableCorrelationNames()
+	throws SQLException {
+	return false;
+    }
+
+    public boolean supportsExpressionsInOrderBy() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsOrderByUnrelated() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsGroupBy() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsGroupByUnrelated() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsGroupByBeyondSelect() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsLikeEscapeClause() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsMultipleResultSets() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsMultipleTransactions() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsNonNullableColumns() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsMinimumSQLGrammar() throws SQLException {
+	return true;
+    } 
+
+    public boolean supportsCoreSQLGrammar() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsExtendedSQLGrammar() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsANSI92IntermediateSQL() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsANSI92FullSQL() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsIntegrityEnhancementFacility()
+	throws SQLException {
+	return false;
+    }
+
+    public boolean supportsOuterJoins() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsFullOuterJoins() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsLimitedOuterJoins() throws SQLException {
+	return false;
+    }
+
+    public String getSchemaTerm() throws SQLException {
+	return "";
+    }
+
+    public String getProcedureTerm() throws SQLException {
+	return "";
+    }
+
+    public String getCatalogTerm() throws SQLException {
+	return "";
+    }
+
+    public boolean isCatalogAtStart() throws SQLException {
+	return false;
+    }
+
+    public String getCatalogSeparator() throws SQLException {
+	return "";
+    }
+
+    public boolean supportsSchemasInDataManipulation() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsSchemasInProcedureCalls() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsSchemasInTableDefinitions() throws SQLException {
+	return false;
+    }
+    
+    public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsSchemasInPrivilegeDefinitions()
+	throws SQLException {
+	return false;
+    }
+
+    public boolean supportsCatalogsInDataManipulation() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsCatalogsInPrivilegeDefinitions()
+	throws SQLException {
+	return false;
+    }
+
+    public boolean supportsPositionedDelete() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsPositionedUpdate() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsSelectForUpdate() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsStoredProcedures() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsSubqueriesInComparisons() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsSubqueriesInExists() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsSubqueriesInIns() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsCorrelatedSubqueries() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsUnion() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsUnionAll() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+	return false;
+    }
+
+    public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+	return false;
+    }
+
+    public int getMaxBinaryLiteralLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxCharLiteralLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxColumnNameLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxColumnsInGroupBy() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxColumnsInIndex() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxColumnsInOrderBy() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxColumnsInSelect() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxColumnsInTable() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxConnections() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxCursorNameLength() throws SQLException {
+	return 8;
+    }
+
+    public int getMaxIndexLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxSchemaNameLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxProcedureNameLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxCatalogNameLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxRowSize() throws SQLException {
+	return 0;
+    }
+
+    public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+	return true;
+    }
+
+    public int getMaxStatementLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxStatements() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxTableNameLength() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxTablesInSelect() throws SQLException {
+	return 0;
+    }
+
+    public int getMaxUserNameLength() throws SQLException {
+	return 0;
+    }
+
+    public int getDefaultTransactionIsolation() throws SQLException {
+	return Connection.TRANSACTION_SERIALIZABLE;
+    }
+
+    public boolean supportsTransactions() throws SQLException {
+	return true;
+    }
+
+    public boolean supportsTransactionIsolationLevel(int level)
+	throws SQLException {
+	return level == Connection.TRANSACTION_SERIALIZABLE;
+    }
+
+    public boolean supportsDataDefinitionAndDataManipulationTransactions()
+	throws SQLException {
+	return true;
+    }
+
+    public boolean supportsDataManipulationTransactionsOnly()
+	throws SQLException {
+	return false;
+    }
+
+    public boolean dataDefinitionCausesTransactionCommit()
+	throws SQLException {
+	return false;
+    }
+
+    public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+	return false;
+    }
+
+    public ResultSet getProcedures(String catalog, String schemaPattern,
+				   String procedureNamePattern)
+	throws SQLException {
+	return null;
+    }
+
+    public ResultSet getProcedureColumns(String catalog,
+					 String schemaPattern,
+					 String procedureNamePattern, 
+					 String columnNamePattern)
+	throws SQLException {
+	return null;
+    }
+
+    public ResultSet getTables(String catalog, String schemaPattern,
+			       String tableNamePattern, String types[])
+	throws SQLException {
+	JDBCStatement s = new JDBCStatement(conn);
+	StringBuffer sb = new StringBuffer();
+	sb.append("SELECT '' AS 'TABLE_CAT', " +
+		  "'' AS 'TABLE_SCHEM', " +
+		  "tbl_name AS 'TABLE_NAME', " +
+		  "upper(type) AS 'TABLE_TYPE', " +
+		  "'' AS REMARKS FROM sqlite_master " +
+		  "WHERE tbl_name like ");
+	if (tableNamePattern != null) {
+	    sb.append(SQLite.Shell.sql_quote(tableNamePattern));
+	} else {
+	    sb.append("'%'");
+	}
+	sb.append(" AND ");
+	if (types == null || types.length == 0) {
+	    sb.append("(type = 'table' or type = 'view')");
+	} else {
+	    sb.append("(");
+	    String sep = ""; 
+	    for (int i = 0; i < types.length; i++) {
+		sb.append(sep);
+		sb.append("type = ");
+		sb.append(SQLite.Shell.sql_quote(types[i].toLowerCase()));
+		sep = " or ";
+	    }
+	    sb.append(")");
+	}
+	ResultSet rs = null;
+	try {
+	    rs = s.executeQuery(sb.toString());
+	    s.close();
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s.close();
+	}
+	return rs;
+    }
+
+    public ResultSet getSchemas() throws SQLException {
+	String cols[] = { "TABLE_SCHEM" };
+	SQLite.TableResult tr = new SQLite.TableResult();
+	tr.columns(cols);
+	String row[] = { "" };
+	tr.newrow(row);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	return (ResultSet) rs;
+    }
+
+    public ResultSet getCatalogs() throws SQLException {
+	String cols[] = { "TABLE_CAT" };
+	SQLite.TableResult tr = new SQLite.TableResult();
+	tr.columns(cols);
+	String row[] = { "" };
+	tr.newrow(row);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	return (ResultSet) rs;
+    }
+
+    public ResultSet getTableTypes() throws SQLException {
+	String cols[] = { "TABLE_TYPE" };
+	SQLite.TableResult tr = new SQLite.TableResult();
+	tr.columns(cols);
+	String row[] = new String[1];
+	row[0] = "TABLE";
+	tr.newrow(row);
+	row = new String[1];
+	row[0] = "VIEW";
+	tr.newrow(row);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	return (ResultSet) rs;
+    }
+
+    public ResultSet getColumns(String catalog, String schemaPattern,
+				String tableNamePattern,
+				String columnNamePattern)
+	throws SQLException {
+	// BEGIN android-changed: add missing error check.
+	if (conn.db == null) {
+	    throw new SQLException("connection closed");
+	}
+	// END android-changed
+	JDBCStatement s = new JDBCStatement(conn);
+	JDBCResultSet rs0 = null;
+	try {
+	    try {
+		conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null);
+	    } catch (SQLite.Exception se) {
+		throw new SQLException("schema reload failed");
+	    }
+	    rs0 = (JDBCResultSet)
+		(s.executeQuery("PRAGMA table_info(" +
+				SQLite.Shell.sql_quote(tableNamePattern) +
+				")"));
+	    s.close();
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s.close();
+	}
+	if (rs0.tr.nrows < 1) {
+	    throw new SQLException("no such table: " + tableNamePattern);
+	}
+	String cols[] = {
+	    "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
+	    "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME",
+	    "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS",
+	    "NUM_PREC_RADIX", "NULLABLE", "REMARKS",
+	    "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB",
+	    "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.SMALLINT, Types.VARCHAR,
+	    Types.INTEGER, Types.INTEGER, Types.INTEGER,
+	    Types.INTEGER, Types.INTEGER, Types.VARCHAR,
+	    Types.VARCHAR, Types.INTEGER, Types.INTEGER,
+	    Types.INTEGER, Types.INTEGER, Types.VARCHAR
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
+	    Hashtable<String, Integer> h = new Hashtable<String, Integer>();
+	    for (int i = 0; i < rs0.tr.ncolumns; i++) {
+		h.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed
+	    }
+	    if (columnNamePattern != null &&
+		columnNamePattern.charAt(0) == '%') {
+		columnNamePattern = null;
+	    }
+	    for (int i = 0; i < rs0.tr.nrows; i++) {
+		String r0[] = (String [])(rs0.tr.rows.elementAt(i));
+		int col = ((Integer) h.get("name")).intValue();
+		if (columnNamePattern != null) {
+		    if (r0[col].compareTo(columnNamePattern) != 0) {
+			continue;
+		    }
+		}
+		String row[] = new String[cols.length];
+		row[0]  = "";
+		row[1]  = "";
+		row[2]  = tableNamePattern;
+		row[3]  = r0[col];
+		col = ((Integer) h.get("type")).intValue();
+		String typeStr = r0[col];
+		int type = mapSqlType(typeStr);
+		row[4]  = "" + type;
+		row[5]  = mapTypeName(type);
+		row[6]  = "" + getD(typeStr, type);
+		row[7]  = "" + getM(typeStr, type);
+		row[8]  = "10";
+		row[9]  = "0";
+		row[11] = null;
+		col = ((Integer) h.get("dflt_value")).intValue();
+		row[12] = r0[col];
+		row[13] = "0";
+		row[14] = "0";
+		row[15] = "65536";
+		col = ((Integer) h.get("cid")).intValue();
+		row[16] = Integer.toString(Integer.parseInt(r0[col]) + 1); // android-changed
+		col = ((Integer) h.get("notnull")).intValue();
+		row[17] = (r0[col].charAt(0) == '0') ? "YES" : "NO";
+		row[10] = (r0[col].charAt(0) == '0') ? "" + columnNullable :
+			  "" + columnNoNulls;
+		tr.newrow(row);
+	    }
+	}
+	return rs;
+    }
+
+    public ResultSet getColumnPrivileges(String catalog, String schema,
+					 String table,
+					 String columnNamePattern)
+	throws SQLException {
+	String cols[] = {
+	    "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
+	    "COLUMN_NAME", "GRANTOR", "GRANTEE",
+	    "PRIVILEGE", "IS_GRANTABLE"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	return rs;
+    }
+
+    public ResultSet getTablePrivileges(String catalog, String schemaPattern,
+					String tableNamePattern)
+	throws SQLException {
+	String cols[] = {
+	    "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
+	    "COLUMN_NAME", "GRANTOR", "GRANTEE",
+	    "PRIVILEGE", "IS_GRANTABLE"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	return rs;
+    }
+
+    public ResultSet getBestRowIdentifier(String catalog, String schema,
+					  String table, int scope,
+					  boolean nullable)
+	throws SQLException {
+	JDBCStatement s0 = new JDBCStatement(conn);
+	JDBCResultSet rs0 = null;
+	JDBCStatement s1 = new JDBCStatement(conn);
+	JDBCResultSet rs1 = null;
+	try {
+	    try {
+		conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null);
+	    } catch (SQLite.Exception se) {
+		throw new SQLException("schema reload failed");
+	    }
+	    rs0 = (JDBCResultSet)
+		(s0.executeQuery("PRAGMA index_list(" +
+				 SQLite.Shell.sql_quote(table) + ")"));
+	    rs1 = (JDBCResultSet)
+		(s1.executeQuery("PRAGMA table_info(" +
+				 SQLite.Shell.sql_quote(table) + ")"));
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s0.close();
+	    s1.close();
+	}
+	String cols[] = {
+	    "SCOPE", "COLUMN_NAME", "DATA_TYPE",
+	    "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH",
+	    "DECIMAL_DIGITS", "PSEUDO_COLUMN"
+	};
+	int types[] = {
+	    Types.SMALLINT, Types.VARCHAR, Types.SMALLINT,
+	    Types.VARCHAR, Types.INTEGER, Types.INTEGER,
+	    Types.SMALLINT, Types.SMALLINT
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0 &&
+	    rs1 != null && rs1.tr != null && rs1.tr.nrows > 0) {
+	    Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
+	    for (int i = 0; i < rs0.tr.ncolumns; i++) {
+		h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed
+	    }
+	    Hashtable<String, Integer> h1 = new Hashtable<String, Integer>();
+	    for (int i = 0; i < rs1.tr.ncolumns; i++) {
+		h1.put(rs1.tr.column[i], Integer.valueOf(i)); // android-changed
+	    }
+	    for (int i = 0; i < rs0.tr.nrows; i++) {
+		String r0[] = (String [])(rs0.tr.rows.elementAt(i));
+		int col = ((Integer) h0.get("unique")).intValue();
+		String uniq = r0[col];
+		col = ((Integer) h0.get("name")).intValue();
+		String iname = r0[col];
+		if (uniq.charAt(0) == '0') {
+		    continue;
+		}
+		JDBCStatement s2 = new JDBCStatement(conn);
+		JDBCResultSet rs2 = null;
+		try {
+		    rs2 = (JDBCResultSet)
+			(s2.executeQuery("PRAGMA index_info(" +
+					 SQLite.Shell.sql_quote(iname) + ")"));
+		} catch (SQLException e) {
+		} finally {
+		    s2.close();
+		}
+		if (rs2 == null || rs2.tr == null || rs2.tr.nrows <= 0) {
+		    continue;
+		}
+		Hashtable<String, Integer> h2 =
+		    new Hashtable<String, Integer>();
+		for (int k = 0; k < rs2.tr.ncolumns; k++) {
+		    h2.put(rs2.tr.column[k], Integer.valueOf(k)); // android-changed
+		}
+		for (int k = 0; k < rs2.tr.nrows; k++) {
+		    String r2[] = (String [])(rs2.tr.rows.elementAt(k));
+		    col = ((Integer) h2.get("name")).intValue();
+		    String cname = r2[col];
+		    for (int m = 0; m < rs1.tr.nrows; m++) {
+			String r1[] = (String [])(rs1.tr.rows.elementAt(m));
+			col = ((Integer) h1.get("name")).intValue();
+			if (cname.compareTo(r1[col]) == 0) {
+			    String row[] = new String[cols.length];
+			    row[0] = "" + scope;
+			    row[1] = cname;
+			    row[2] = "" + Types.VARCHAR;
+			    row[3] = "VARCHAR";
+			    row[4] = "65536";
+			    row[5] = "0";
+			    row[6] = "0";
+			    row[7] = "" + bestRowNotPseudo;
+			    tr.newrow(row);
+			}
+		    }
+		}
+	    }
+	}
+	if (tr.nrows <= 0) {
+	    String row[] = new String[cols.length];
+	    row[0] = "" + scope;
+	    row[1] = "_ROWID_";
+	    row[2] = "" + Types.INTEGER;
+	    row[3] = "INTEGER";
+	    row[4] = "10";
+	    row[5] = "0";
+	    row[6] = "0";
+	    row[7] = "" + bestRowPseudo;
+	    tr.newrow(row);
+	}
+	return rs;
+    }
+
+    public ResultSet getVersionColumns(String catalog, String schema,
+				       String table) throws SQLException {
+	String cols[] = {
+	    "SCOPE", "COLUMN_NAME", "DATA_TYPE",
+	    "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH",
+	    "DECIMAL_DIGITS", "PSEUDO_COLUMN"
+	};
+	int types[] = {
+	    Types.SMALLINT, Types.VARCHAR, Types.SMALLINT,
+	    Types.VARCHAR, Types.INTEGER, Types.INTEGER,
+	    Types.SMALLINT, Types.SMALLINT
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	return rs;
+    }
+
+    public ResultSet getPrimaryKeys(String catalog, String schema,
+				    String table) throws SQLException {
+	JDBCStatement s0 = new JDBCStatement(conn);
+	JDBCResultSet rs0 = null;
+	try {
+	    try {
+		conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null);
+	    } catch (SQLite.Exception se) {
+		throw new SQLException("schema reload failed");
+	    }
+	    rs0 = (JDBCResultSet)
+		(s0.executeQuery("PRAGMA index_list(" +
+				 SQLite.Shell.sql_quote(table) + ")"));
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s0.close();
+	}
+	String cols[] = {
+	    "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
+	    "COLUMN_NAME", "KEY_SEQ", "PK_NAME"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.SMALLINT, Types.VARCHAR
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
+	    Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
+	    for (int i = 0; i < rs0.tr.ncolumns; i++) {
+		h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed
+	    }
+	    for (int i = 0; i < rs0.tr.nrows; i++) {
+		String r0[] = (String [])(rs0.tr.rows.elementAt(i));
+		int col = ((Integer) h0.get("unique")).intValue();
+		String uniq = r0[col];
+		col = ((Integer) h0.get("name")).intValue();
+		String iname = r0[col];
+		if (uniq.charAt(0) == '0') {
+		    continue;
+		}
+		JDBCStatement s1 = new JDBCStatement(conn);
+		JDBCResultSet rs1 = null;
+		try {
+		    rs1 = (JDBCResultSet)
+			(s1.executeQuery("PRAGMA index_info(" +
+					 SQLite.Shell.sql_quote(iname) + ")"));
+		} catch (SQLException e) {
+		} finally {
+		    s1.close();
+		}
+		if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) {
+		    continue;
+		}
+		Hashtable<String, Integer> h1 =
+		    new Hashtable<String, Integer>();
+		for (int k = 0; k < rs1.tr.ncolumns; k++) {
+		    h1.put(rs1.tr.column[k], Integer.valueOf(k)); // android-changed
+		}
+		for (int k = 0; k < rs1.tr.nrows; k++) {
+		    String r1[] = (String [])(rs1.tr.rows.elementAt(k));
+		    String row[] = new String[cols.length];
+		    row[0]  = "";
+		    row[1]  = "";
+		    row[2]  = table;
+		    col = ((Integer) h1.get("name")).intValue();
+		    row[3] = r1[col];
+		    col = ((Integer) h1.get("seqno")).intValue();
+		    row[4]  = Integer.toString(Integer.parseInt(r1[col]) + 1); // android-changed: performance
+		    row[5]  = iname;
+		    tr.newrow(row);
+		}
+	    }
+	}
+	if (tr.nrows > 0) {
+	    return rs;
+	}
+	JDBCStatement s1 = new JDBCStatement(conn);
+	try {
+	    rs0 = (JDBCResultSet)
+		(s1.executeQuery("PRAGMA table_info(" +
+				 SQLite.Shell.sql_quote(table) + ")"));
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s1.close();
+	}
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
+	    Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
+	    for (int i = 0; i < rs0.tr.ncolumns; i++) {
+		h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed
+	    }
+	    for (int i = 0; i < rs0.tr.nrows; i++) {
+		String r0[] = (String [])(rs0.tr.rows.elementAt(i));
+		int col = ((Integer) h0.get("type")).intValue();
+		String type = r0[col];
+		if (!type.equalsIgnoreCase("integer")) {
+		    continue;
+		}
+		col = ((Integer) h0.get("pk")).intValue();
+		String pk = r0[col];
+		if (pk.charAt(0) == '0') {
+		    continue;
+		}
+		String row[] = new String[cols.length];
+		row[0]  = "";
+		row[1]  = "";
+		row[2]  = table;
+		col = ((Integer) h0.get("name")).intValue();
+		row[3] = r0[col];
+		col = ((Integer) h0.get("cid")).intValue();
+		row[4] = Integer.toString(Integer.parseInt(r0[col]) + 1); // android-changed: performance
+		row[5] = "";
+		tr.newrow(row);
+	    }
+	}
+	return rs;
+    }
+
+    private void internalImportedKeys(String table, String pktable,
+				      JDBCResultSet in, TableResultX out) {
+	Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
+	for (int i = 0; i < in.tr.ncolumns; i++) {
+	    h0.put(in.tr.column[i], Integer.valueOf(i)); // android-changed
+	}
+	for (int i = 0; i < in.tr.nrows; i++) {
+	    String r0[] = (String [])(in.tr.rows.elementAt(i));
+	    int col = ((Integer) h0.get("table")).intValue();
+	    String pktab = r0[col];
+	    if (pktable != null && !pktable.equalsIgnoreCase(pktab)) {
+		continue;
+	    }
+	    col = ((Integer) h0.get("from")).intValue();
+	    String fkcol = r0[col];
+	    col = ((Integer) h0.get("to")).intValue();
+	    String pkcol = r0[col];
+	    col = ((Integer) h0.get("seq")).intValue();
+	    String seq = r0[col];
+	    String row[] = new String[out.ncolumns];
+	    row[0]  = "";
+	    row[1]  = "";
+	    row[2]  = pktab;
+	    row[3]  = pkcol;
+	    row[4]  = "";
+	    row[5]  = "";
+	    row[6]  = table;
+	    row[7]  = fkcol == null ? pkcol : fkcol;
+	    row[8]  = Integer.toString(Integer.parseInt(seq) + 1); // android-changed: performance
+	    row[9]  =
+		"" + java.sql.DatabaseMetaData.importedKeyNoAction;
+	    row[10] =
+		"" + java.sql.DatabaseMetaData.importedKeyNoAction;
+	    row[11] = null;
+	    row[12] = null;
+	    row[13] =
+		"" + java.sql.DatabaseMetaData.importedKeyNotDeferrable;
+	    out.newrow(row);
+	}
+    }
+
+    public ResultSet getImportedKeys(String catalog, String schema,
+				     String table) throws SQLException {
+	JDBCStatement s0 = new JDBCStatement(conn);
+	JDBCResultSet rs0 = null;
+	try {
+	    try {
+		conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null);
+	    } catch (SQLite.Exception se) {
+		throw new SQLException("schema reload failed");
+	    }
+	    rs0 = (JDBCResultSet)
+		(s0.executeQuery("PRAGMA foreign_key_list(" +
+				 SQLite.Shell.sql_quote(table) + ")"));
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s0.close();
+	}
+	String cols[] = {
+	    "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
+	    "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
+	    "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
+	    "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
+	    "PK_NAME", "DEFERRABILITY"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.SMALLINT,
+	    Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
+	    Types.VARCHAR, Types.SMALLINT
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null);
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
+	    internalImportedKeys(table, null, rs0, tr);
+	}
+	return rs;
+    }
+
+    public ResultSet getExportedKeys(String catalog, String schema,
+				     String table) throws SQLException {
+	String cols[] = {
+	    "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
+	    "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
+	    "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
+	    "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
+	    "PK_NAME", "DEFERRABILITY"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.SMALLINT,
+	    Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
+	    Types.VARCHAR, Types.SMALLINT
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	return rs;
+    }
+
+    public ResultSet getCrossReference(String primaryCatalog,
+				       String primarySchema,
+				       String primaryTable,
+				       String foreignCatalog,
+				       String foreignSchema,
+				       String foreignTable)
+	throws SQLException {
+	JDBCResultSet rs0 = null;
+	if (foreignTable != null && foreignTable.charAt(0) != '%') {
+	    JDBCStatement s0 = new JDBCStatement(conn);
+	    try {
+		try {
+		    conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null);
+		} catch (SQLite.Exception se) {
+		    throw new SQLException("schema reload failed");
+		}
+		rs0 = (JDBCResultSet)
+		    (s0.executeQuery("PRAGMA foreign_key_list(" +
+				     SQLite.Shell.sql_quote(foreignTable) + ")"));
+	    } catch (SQLException e) {
+		throw e;
+	    } finally {
+		s0.close();
+	    }
+	}
+	String cols[] = {
+	    "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME",
+	    "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM",
+	    "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ",
+	    "UPDATE_RULE", "DELETE_RULE", "FK_NAME",
+	    "PK_NAME", "DEFERRABILITY"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.VARCHAR, Types.VARCHAR, Types.SMALLINT,
+	    Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
+	    Types.VARCHAR, Types.SMALLINT
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
+	    String pktable = null;
+	    if (primaryTable != null && primaryTable.charAt(0) != '%') {
+		pktable = primaryTable;
+	    }
+	    internalImportedKeys(foreignTable, pktable, rs0, tr);
+	}
+	return rs;
+    }
+
+    public ResultSet getTypeInfo() throws SQLException {
+	String cols[] = {
+	    "TYPE_NAME", "DATA_TYPE", "PRECISION",
+	    "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS",
+	    "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE",
+	    "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT",
+	    "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE",
+	    "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.SMALLINT, Types.INTEGER,
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.SMALLINT, Types.BIT, Types.SMALLINT,
+	    Types.BIT, Types.BIT, Types.BIT,
+	    Types.VARCHAR, Types.SMALLINT, Types.SMALLINT,
+	    Types.INTEGER, Types.INTEGER, Types.INTEGER
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	String row1[] = {
+	    "VARCHAR", "" + Types.VARCHAR, "65536",
+	    "'", "'", null,
+	    "" + typeNullable, "1", "" + typeSearchable,
+	    "0", "0", "0",
+	    null, "0", "0",
+	    "0", "0", "0"
+	};
+	tr.newrow(row1);
+	String row2[] = {
+	    "INTEGER", "" + Types.INTEGER, "32",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "2"
+	};
+	tr.newrow(row2);
+	String row3[] = {
+	    "DOUBLE", "" + Types.DOUBLE, "16",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "10"
+	};
+	tr.newrow(row3);
+	String row4[] = {
+	    "FLOAT", "" + Types.FLOAT, "7",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "10"
+	};
+	tr.newrow(row4);
+	String row5[] = {
+	    "SMALLINT", "" + Types.SMALLINT, "16",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "2"
+	};
+	tr.newrow(row5);
+	String row6[] = {
+	    "BIT", "" + Types.BIT, "1",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "2"
+	};
+	tr.newrow(row6);
+	String row7[] = {
+	    "TIMESTAMP", "" + Types.TIMESTAMP, "30",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "0"
+	};
+	tr.newrow(row7);
+	String row8[] = {
+	    "DATE", "" + Types.DATE, "10",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "0"
+	};
+	tr.newrow(row8);
+	String row9[] = {
+	    "TIME", "" + Types.TIME, "8",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "0"
+	};
+	tr.newrow(row9);
+	String row10[] = {
+	    "BINARY", "" + Types.BINARY, "65536",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "0"
+	};
+	tr.newrow(row10);
+	String row11[] = {
+	    "VARBINARY", "" + Types.VARBINARY, "65536",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "0"
+	};
+	tr.newrow(row11);
+	String row12[] = {
+	    "REAL", "" + Types.REAL, "16",
+	    null, null, null,
+	    "" + typeNullable, "0", "" + typeSearchable,
+	    "0", "0", "1",
+	    null, "0", "0",
+	    "0", "0", "10"
+	};
+	tr.newrow(row12);
+	return rs;
+    }
+
+    public ResultSet getIndexInfo(String catalog, String schema, String table,
+				  boolean unique, boolean approximate)
+	throws SQLException {
+	JDBCStatement s0 = new JDBCStatement(conn);
+	JDBCResultSet rs0 = null;
+	try {
+	    try {
+		conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null);
+	    } catch (SQLite.Exception se) {
+		throw new SQLException("schema reload failed");
+	    }
+	    rs0 = (JDBCResultSet)
+		(s0.executeQuery("PRAGMA index_list(" +
+				 SQLite.Shell.sql_quote(table) + ")"));
+	} catch (SQLException e) {
+	    throw e;
+	} finally {
+	    s0.close();
+	}
+	String cols[] = {
+	    "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME",
+	    "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME",
+	    "TYPE", "ORDINAL_POSITION", "COLUMN_NAME",
+	    "ASC_OR_DESC", "CARDINALITY", "PAGES",
+	    "FILTER_CONDITION"
+	};
+	int types[] = {
+	    Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
+	    Types.BIT, Types.VARCHAR, Types.VARCHAR,
+	    Types.SMALLINT, Types.SMALLINT, Types.VARCHAR,
+	    Types.VARCHAR, Types.INTEGER, Types.INTEGER,
+	    Types.VARCHAR
+	};
+	TableResultX tr = new TableResultX();
+	tr.columns(cols);
+	tr.sql_types(types);
+	JDBCResultSet rs = new JDBCResultSet(tr, null);
+	if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) {
+	    Hashtable<String, Integer> h0 = new Hashtable<String, Integer>();
+	    for (int i = 0; i < rs0.tr.ncolumns; i++) {
+		h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed
+	    }
+	    for (int i = 0; i < rs0.tr.nrows; i++) {
+		String r0[] = (String [])(rs0.tr.rows.elementAt(i));
+		int col = ((Integer) h0.get("unique")).intValue();
+		String uniq = r0[col];
+		col = ((Integer) h0.get("name")).intValue();
+		String iname = r0[col];
+		if (unique && uniq.charAt(0) == '0') {
+		    continue;
+		}
+		JDBCStatement s1 = new JDBCStatement(conn);
+		JDBCResultSet rs1 = null;
+		try {
+		    rs1 = (JDBCResultSet)
+			(s1.executeQuery("PRAGMA index_info(" +
+					 SQLite.Shell.sql_quote(iname) + ")"));
+		} catch (SQLException e) {
+		} finally {
+		    s1.close();
+		}
+		if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) {
+		    continue;
+		}
+		Hashtable<String, Integer> h1 =
+		    new Hashtable<String, Integer>();
+		for (int k = 0; k < rs1.tr.ncolumns; k++) {
+		    h1.put(rs1.tr.column[k], Integer.valueOf(k)); // android-changed
+		}
+		for (int k = 0; k < rs1.tr.nrows; k++) {
+		    String r1[] = (String [])(rs1.tr.rows.elementAt(k));
+		    String row[] = new String[cols.length];
+		    row[0]  = "";
+		    row[1]  = "";
+		    row[2]  = table;
+		    row[3]  = (uniq.charAt(0) != '0' ||
+			(iname.charAt(0) == '(' &&
+			 iname.indexOf(" autoindex ") > 0)) ? "0" : "1";
+		    row[4]  = "";
+		    row[5]  = iname;
+		    row[6]  = "" + tableIndexOther;
+		    col = ((Integer) h1.get("seqno")).intValue();
+		    row[7]  = Integer.toString(Integer.parseInt(r1[col]) + 1); // android-changed: performance
+		    col = ((Integer) h1.get("name")).intValue();
+		    row[8]  = r1[col];
+		    row[9]  = "A";
+		    row[10] = "0";
+		    row[11] = "0";
+		    row[12] = null;
+		    tr.newrow(row);
+		}
+	    }
+	}
+	return rs;
+    }
+
+    public boolean supportsResultSetType(int type) throws SQLException {
+	return type == ResultSet.TYPE_FORWARD_ONLY ||
+	    type == ResultSet.TYPE_SCROLL_INSENSITIVE ||
+	    type == ResultSet.TYPE_SCROLL_SENSITIVE;
+    }
+
+    public boolean supportsResultSetConcurrency(int type, int concurrency)
+	throws SQLException {
+	if (type == ResultSet.TYPE_FORWARD_ONLY ||
+	    type == ResultSet.TYPE_SCROLL_INSENSITIVE ||
+	    type == ResultSet.TYPE_SCROLL_SENSITIVE) {
+	    return concurrency == ResultSet.CONCUR_READ_ONLY ||
+		concurrency == ResultSet.CONCUR_UPDATABLE;
+	}
+	return false;
+    }
+
+    public boolean ownUpdatesAreVisible(int type) throws SQLException {
+	if (type == ResultSet.TYPE_FORWARD_ONLY ||
+	    type == ResultSet.TYPE_SCROLL_INSENSITIVE ||
+	    type == ResultSet.TYPE_SCROLL_SENSITIVE) {
+	    return true;
+	}
+	return false;
+    }
+
+    public boolean ownDeletesAreVisible(int type) throws SQLException {
+	if (type == ResultSet.TYPE_FORWARD_ONLY ||
+	    type == ResultSet.TYPE_SCROLL_INSENSITIVE ||
+	    type == ResultSet.TYPE_SCROLL_SENSITIVE) {
+	    return true;
+	}
+	return false;
+    }
+
+    public boolean ownInsertsAreVisible(int type) throws SQLException {
+	if (type == ResultSet.TYPE_FORWARD_ONLY ||
+	    type == ResultSet.TYPE_SCROLL_INSENSITIVE ||
+	    type == ResultSet.TYPE_SCROLL_SENSITIVE) {
+	    return true;
+	}
+	return false;
+    }
+
+    public boolean othersUpdatesAreVisible(int type) throws SQLException {
+	return false;
+    }
+
+    public boolean othersDeletesAreVisible(int type) throws SQLException {
+	return false;
+    }
+
+    public boolean othersInsertsAreVisible(int type) throws SQLException {
+	return false;
+    }
+
+    public boolean updatesAreDetected(int type) throws SQLException {
+	return false;
+    }
+
+    public boolean deletesAreDetected(int type) throws SQLException {
+	return false;
+    }
+
+    public boolean insertsAreDetected(int type) throws SQLException {
+	return false;
+    }
+
+    public boolean supportsBatchUpdates() throws SQLException {
+	return true;
+    }
+
+    public ResultSet getUDTs(String catalog, String schemaPattern, 
+		      String typeNamePattern, int[] types) 
+	throws SQLException {
+	return null;
+    }
+
+    public Connection getConnection() throws SQLException {
+	return conn;
+    }
+
+    static String mapTypeName(int type) {
+	switch (type) {
+	case Types.INTEGER:	return "integer";
+	case Types.SMALLINT:	return "smallint";
+	case Types.FLOAT:	return "float";
+	case Types.DOUBLE:	return "double";
+	case Types.TIMESTAMP:	return "timestamp";
+	case Types.DATE:	return "date";
+	case Types.TIME:	return "time";
+	case Types.BINARY:	return "binary";
+	case Types.VARBINARY:	return "varbinary";
+	case Types.REAL:	return "real";
+	}
+	return "varchar";
+    }
+
+    static int mapSqlType(String type) {
+	if (type == null) {
+	    return Types.VARCHAR;
+	}
+	type = type.toLowerCase();
+	if (type.startsWith("inter")) {
+	    return Types.VARCHAR;
+	}
+	if (type.startsWith("numeric") ||
+	    type.startsWith("int")) {
+	    return Types.INTEGER;
+	}
+	if (type.startsWith("tinyint") ||
+	    type.startsWith("smallint")) {
+	    return Types.SMALLINT;
+	}
+	if (type.startsWith("float")) {
+	    return Types.FLOAT;
+	}
+	if (type.startsWith("double")) {
+	    return Types.DOUBLE;
+	}
+	if (type.startsWith("datetime") ||
+	    type.startsWith("timestamp")) {
+	    return Types.TIMESTAMP;
+	}
+	if (type.startsWith("date")) {
+	    return Types.DATE;
+	}
+	if (type.startsWith("time")) {
+	    return Types.TIME;
+	}
+	if (type.startsWith("blob")) {
+	    return Types.BINARY;
+	}
+	if (type.startsWith("binary")) {
+	    return Types.BINARY;
+	}
+	if (type.startsWith("varbinary")) {
+	    return Types.VARBINARY;
+	}
+	if (type.startsWith("real")) {
+	    return Types.REAL;
+	}
+	return Types.VARCHAR;
+    }
+
+    static int getM(String typeStr, int type) {
+	int m = 65536;
+	switch (type) {
+	case Types.INTEGER:	m = 11; break;
+	case Types.SMALLINT:	m = 6;  break;
+	case Types.FLOAT:	m = 25; break;
+	case Types.REAL:
+	case Types.DOUBLE:	m = 54; break;
+	case Types.TIMESTAMP:	return 30;
+	case Types.DATE:	return 10;
+	case Types.TIME:	return 8;
+	}
+	typeStr = typeStr.toLowerCase();
+	int i1 = typeStr.indexOf('(');
+	if (i1 > 0) {
+	    ++i1;
+	    int i2 = typeStr.indexOf(',', i1);
+	    if (i2 < 0) {
+		i2 = typeStr.indexOf(')', i1);
+	    }
+	    if (i2 - i1 > 0) {
+		String num = typeStr.substring(i1, i2);
+		try {
+		    m = java.lang.Integer.parseInt(num, 10);
+		} catch (NumberFormatException e) {
+		}
+	    }
+	}
+	return m;
+    }
+
+    static int getD(String typeStr, int type) {
+	int d = 0;
+	switch (type) {
+	case Types.INTEGER:	d = 10; break;
+	case Types.SMALLINT:	d = 5;  break;
+	case Types.FLOAT:	d = 24; break;
+	case Types.REAL:
+	case Types.DOUBLE:	d = 53; break;
+	default:		return getM(typeStr, type);
+	}
+	typeStr = typeStr.toLowerCase();
+	int i1 = typeStr.indexOf('(');
+	if (i1 > 0) {
+	    ++i1;
+	    int i2 = typeStr.indexOf(',', i1);
+	    if (i2 < 0) {
+		return getM(typeStr, type);
+	    }
+	    i1 = i2;
+	    i2 = typeStr.indexOf(')', i1);
+	    if (i2 - i1 > 0) {
+		String num = typeStr.substring(i1, i2);
+		try {
+		    d = java.lang.Integer.parseInt(num, 10);
+		} catch (NumberFormatException e) {
+		}
+	    }
+	}
+	return d;
+    }
+
+    public boolean supportsSavepoints() {
+	return false;
+    }
+
+    public boolean supportsNamedParameters() {
+	return false;
+    }
+
+    public boolean supportsMultipleOpenResults() {
+	return false;
+    }
+
+    public boolean supportsGetGeneratedKeys() {
+	return false;
+    }
+
+    public boolean supportsResultSetHoldability(int x) {
+	return false;
+    }
+
+    public boolean supportsStatementPooling() {
+	return false;
+    }
+
+    public boolean locatorsUpdateCopy() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public ResultSet getSuperTypes(String catalog, String schemaPattern,
+			    String typeNamePattern)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public ResultSet getSuperTables(String catalog, String schemaPattern,
+				    String tableNamePattern)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public ResultSet getAttributes(String catalog, String schemaPattern,
+				   String typeNamePattern,
+				   String attributeNamePattern)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int getResultSetHoldability() throws SQLException {
+	return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+    }
+
+    public int getDatabaseMajorVersion() {
+	return SQLite.JDBCDriver.MAJORVERSION;
+    }
+
+    public int getDatabaseMinorVersion() {
+	return SQLite.Constants.drv_minor;
+    }
+
+    public int getJDBCMajorVersion() {
+	return 1;
+    }
+    
+    public int getJDBCMinorVersion() {
+	return 0;
+    }
+
+    public int getSQLStateType() throws SQLException {
+	return sqlStateXOpen;
+    }
+
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java
new file mode 100644
index 0000000..3d5b045
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java
@@ -0,0 +1,781 @@
+package SQLite.JDBC2y;
+
+import java.sql.*;
+import java.math.BigDecimal;
+import java.util.*;
+
+class BatchArg {
+    String arg;
+    boolean blob;
+
+    BatchArg(String arg, boolean blob) {
+	if (arg == null) {
+	    this.arg = null;
+	} else {
+	    this.arg = new String(arg);
+	}
+	this.blob = blob;
+    }
+}
+
+public class JDBCPreparedStatement extends JDBCStatement
+    implements java.sql.PreparedStatement {
+
+    private String sql;
+    private String args[];
+    private boolean blobs[];
+    private ArrayList<BatchArg> batch;
+    private static final boolean nullrepl =
+	SQLite.Database.version().compareTo("2.5.0") < 0;
+
+    public JDBCPreparedStatement(JDBCConnection conn, String sql) {
+	super(conn);
+	this.args = null;
+	this.blobs = null;
+	this.batch = null;
+	this.sql = fixup(sql);
+    }
+
+    private String fixup(String sql) {
+	StringBuffer sb = new StringBuffer();
+	boolean inq = false;
+	int nparm = 0;
+	for (int i = 0; i < sql.length(); i++) {
+	    char c = sql.charAt(i);
+	    if (c == '\'') {
+		if (inq) {
+                    char nextChar = 0;
+                    if(i + 1 < sql.length()) {
+                        nextChar = sql.charAt(i + 1);
+                    }
+		    if (nextChar == '\'') {
+                        sb.append(c);
+                        sb.append(nextChar);
+                        i++;
+                    } else {
+			inq = false;
+                        sb.append(c);
+                    }
+		} else {
+		    inq = true;
+                    sb.append(c);
+		}
+	    } else if (c == '?') {
+		if (inq) {
+		    sb.append(c);
+		} else {
+		    ++nparm;
+		    sb.append(nullrepl ? "'%q'" : "%Q");
+		}
+	    } else if (c == ';') {
+		if (!inq) {
+		    break;
+		}
+		sb.append(c);
+	    } else if (c == '%') {
+		sb.append("%%");
+	    } else {
+		sb.append(c);
+	    }
+	}
+	args = new String[nparm];
+	blobs = new boolean[nparm];
+	try {
+	    clearParameters();
+	} catch (SQLException e) {
+	}
+	return sb.toString();
+    }
+
+    private String fixup2(String sql) {
+	if (!conn.db.is3()) {
+	    return sql;
+	}
+	StringBuffer sb = new StringBuffer();
+	int parm = -1;
+	for (int i = 0; i < sql.length(); i++) {
+	    char c = sql.charAt(i);
+	    if (c == '%') {
+		sb.append(c);
+		++i;
+		c = sql.charAt(i);
+		if (c == 'Q') {
+		    parm++;
+		    if (blobs[parm]) {
+			c = 's';
+		    }
+		}
+	    }
+	    sb.append(c);
+	}
+	return sb.toString();
+    }
+
+    public ResultSet executeQuery() throws SQLException {
+	return executeQuery(fixup2(sql), args, false);
+    }
+
+    public int executeUpdate() throws SQLException {
+	executeQuery(fixup2(sql), args, true);
+	return updcnt;
+    }
+
+    public void setNull(int parameterIndex, int sqlType) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = nullrepl ? "" : null;
+	blobs[parameterIndex - 1] = false;
+    }
+    
+    public void setBoolean(int parameterIndex, boolean x)
+	throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = x ? "1" : "0";
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setByte(int parameterIndex, byte x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = "" + x;
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setShort(int parameterIndex, short x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = "" + x;
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setInt(int parameterIndex, int x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = "" + x;
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setLong(int parameterIndex, long x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = "" + x;
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setFloat(int parameterIndex, float x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = "" + x;
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setDouble(int parameterIndex, double x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	args[parameterIndex - 1] = "" + x;
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setBigDecimal(int parameterIndex, BigDecimal x)
+	throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    args[parameterIndex - 1] = "" + x;
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setString(int parameterIndex, String x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    args[parameterIndex - 1] = x;
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	blobs[parameterIndex - 1] = false;
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (conn.db.is3()) {
+		args[parameterIndex - 1] = SQLite.StringEncoder.encodeX(x);
+		blobs[parameterIndex - 1] = true;
+	    } else {
+		args[parameterIndex - 1] = SQLite.StringEncoder.encode(x);
+	    }
+	}
+    }
+
+    public void setDate(int parameterIndex, java.sql.Date x)
+	throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (conn.useJulian) {
+		args[parameterIndex - 1] = java.lang.Double.toString(SQLite.Database.julian_from_long(x.getTime()));
+	    } else {
+		args[parameterIndex - 1] = x.toString();
+	    }
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setTime(int parameterIndex, java.sql.Time x) 
+	throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (conn.useJulian) {
+		args[parameterIndex - 1] = java.lang.Double.toString(SQLite.Database.julian_from_long(x.getTime()));
+	    } else {
+		args[parameterIndex - 1] = x.toString();
+	    }
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setTimestamp(int parameterIndex, java.sql.Timestamp x)
+	throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (conn.useJulian) {
+		args[parameterIndex - 1] = java.lang.Double.toString(SQLite.Database.julian_from_long(x.getTime()));
+	    } else {
+		args[parameterIndex - 1] = x.toString();
+	    }
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setAsciiStream(int parameterIndex, java.io.InputStream x,
+			       int length) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    @Deprecated
+    public void setUnicodeStream(int parameterIndex, java.io.InputStream x, 
+				 int length) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setBinaryStream(int parameterIndex, java.io.InputStream x,
+				int length) throws SQLException {
+	try {
+	    byte[] data = new byte[length];
+	    x.read(data, 0, length);
+	    setBytes(parameterIndex, data);
+	} catch (java.io.IOException e) {
+	    throw new SQLException("I/O failed");
+	}
+    }
+
+    public void clearParameters() throws SQLException {
+	for (int i = 0; i < args.length; i++) {
+	    args[i] = nullrepl ? "" : null;
+	    blobs[i] = false;
+	}
+    }
+
+    public void setObject(int parameterIndex, Object x, int targetSqlType,
+			  int scale) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (x instanceof byte[]) {
+		byte[] bx = (byte[]) x;
+		if (conn.db.is3()) {
+		    args[parameterIndex - 1] =
+			  SQLite.StringEncoder.encodeX(bx);
+		    blobs[parameterIndex - 1] = true;
+		    return;
+		}
+		args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx);
+	    } else {
+		args[parameterIndex - 1] = x.toString();
+	    }
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setObject(int parameterIndex, Object x, int targetSqlType)
+	throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (x instanceof byte[]) {
+		byte[] bx = (byte[]) x;
+		if (conn.db.is3()) {
+		    args[parameterIndex - 1] =
+			SQLite.StringEncoder.encodeX(bx);
+		    blobs[parameterIndex - 1] = true;
+		    return;
+		}
+		args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx);
+	    } else {
+		args[parameterIndex - 1] = x.toString();
+	    }
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public void setObject(int parameterIndex, Object x) throws SQLException {
+	if (parameterIndex < 1 || parameterIndex > args.length) {
+	    throw new SQLException("bad parameter index");
+	}
+	if (x == null) {
+	    args[parameterIndex - 1] = nullrepl ? "" : null;
+	} else {
+	    if (x instanceof byte[]) {
+		byte[] bx = (byte[]) x;
+		if (conn.db.is3()) {
+		    args[parameterIndex - 1] =
+			SQLite.StringEncoder.encodeX(bx);
+		    blobs[parameterIndex - 1] = true;
+		    return;
+		}
+		args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx);
+	    } else {
+		args[parameterIndex - 1] = x.toString();
+	    }
+	}
+	blobs[parameterIndex - 1] = false;
+    }
+
+    public boolean execute() throws SQLException {
+	return executeQuery(fixup2(sql), args, false) != null;
+    }
+
+    public void addBatch() throws SQLException {
+	if (batch == null) {
+	    batch = new ArrayList<BatchArg>(args.length);
+	}
+	for (int i = 0; i < args.length; i++) {
+	    batch.add(new BatchArg(args[i], blobs[i]));
+	}
+    }
+
+    public int[] executeBatch() throws SQLException {
+	if (batch == null) {
+	    return new int[0];
+	}
+	int[] ret = new int[batch.size() / args.length];
+	for (int i = 0; i < ret.length; i++) {
+	    ret[i] = EXECUTE_FAILED;
+	}
+	int errs = 0;
+	int index = 0;
+	for (int i = 0; i < ret.length; i++) {
+	    for (int k = 0; k < args.length; k++) {
+		BatchArg b = (BatchArg) batch.get(index++);
+
+		args[k] = b.arg;
+		blobs[k] = b.blob;
+	    }
+	    try {
+		ret[i] = executeUpdate();
+	    } catch (SQLException e) {
+		++errs;
+	    }
+	}
+	if (errs > 0) {
+	    throw new BatchUpdateException("batch failed", ret);
+	}
+	return ret;
+    }
+
+    public void clearBatch() throws SQLException {
+	if (batch != null) {
+	    batch.clear();
+	    batch = null;
+	}
+    }
+
+    public void close() throws SQLException {
+    	clearBatch();
+	super.close();
+    }
+
+    public void setCharacterStream(int parameterIndex,
+				   java.io.Reader reader,
+				   int length) throws SQLException {
+	try {
+	    char[] data = new char[length];
+	    reader.read(data);
+	    setString(parameterIndex, new String(data));
+	} catch (java.io.IOException e) {
+	    throw new SQLException("I/O failed");
+	}
+    }
+
+    public void setRef(int i, Ref x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setBlob(int i, Blob x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setClob(int i, Clob x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setArray(int i, Array x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public ResultSetMetaData getMetaData() throws SQLException {
+	return rs.getMetaData();
+    }
+
+    public void setDate(int parameterIndex, java.sql.Date x, Calendar cal)
+	throws SQLException {
+	setDate(parameterIndex, x);
+    }
+
+    public void setTime(int parameterIndex, java.sql.Time x, Calendar cal)
+	throws SQLException {
+	setTime(parameterIndex, x);
+    }
+
+    public void setTimestamp(int parameterIndex, java.sql.Timestamp x,
+			     Calendar cal) throws SQLException {
+	setTimestamp(parameterIndex, x);
+    }
+
+    public void setNull(int parameterIndex, int sqlType, String typeName)
+	throws SQLException {
+	setNull(parameterIndex, sqlType);
+    }
+
+    public ParameterMetaData getParameterMetaData() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void registerOutputParameter(String parameterName, int sqlType)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void registerOutputParameter(String parameterName, int sqlType,
+					int scale)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void registerOutputParameter(String parameterName, int sqlType,
+					String typeName)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.net.URL getURL(int parameterIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setURL(int parameterIndex, java.net.URL url)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setNull(String parameterName, int sqlType)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setBoolean(String parameterName, boolean val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setByte(String parameterName, byte val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setShort(String parameterName, short val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setInt(String parameterName, int val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setLong(String parameterName, long val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setFloat(String parameterName, float val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setDouble(String parameterName, double val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setBigDecimal(String parameterName, BigDecimal val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setString(String parameterName, String val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setBytes(String parameterName, byte val[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setDate(String parameterName, java.sql.Date val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setTime(String parameterName, java.sql.Time val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setTimestamp(String parameterName, java.sql.Timestamp val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setAsciiStream(String parameterName,
+			       java.io.InputStream s, int length)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setBinaryStream(String parameterName,
+				java.io.InputStream s, int length)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setObject(String parameterName, Object val, int targetSqlType,
+			  int scale)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setObject(String parameterName, Object val, int targetSqlType)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setObject(String parameterName, Object val)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setCharacterStream(String parameterName,
+				   java.io.Reader r, int length)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setDate(String parameterName, java.sql.Date val,
+			Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setTime(String parameterName, java.sql.Time val,
+			Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setTimestamp(String parameterName, java.sql.Timestamp val,
+			     Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setNull(String parameterName, int sqlType, String typeName)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public String getString(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public boolean getBoolean(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public byte getByte(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public short getShort(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int getInt(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public long getLong(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public float getFloat(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public double getDouble(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public byte[] getBytes(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Date getDate(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Time getTime(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Timestamp getTimestamp(String parameterName)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Object getObject(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Object getObject(int parameterIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Object getObject(String parameterName, Map map)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Object getObject(int parameterIndex, Map map)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Ref getRef(int parameterIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Ref getRef(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Blob getBlob(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Blob getBlob(int parameterIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Clob getClob(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Clob getClob(int parameterIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Array getArray(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Array getArray(int parameterIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Date getDate(String parameterName, Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Date getDate(int parameterIndex, Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Time getTime(String parameterName, Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Time getTime(int parameterIndex, Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Timestamp getTimestamp(int parameterIndex, Calendar cal)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.net.URL getURL(String parameterName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java
new file mode 100644
index 0000000..24e110f
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java
@@ -0,0 +1,1314 @@
+package SQLite.JDBC2y;
+
+import java.sql.*;
+import java.math.BigDecimal;
+
+public class JDBCResultSet implements java.sql.ResultSet {
+
+    /**
+     * Current row to be retrieved.
+     */
+    private int row;
+
+    /**
+     * Table returned by Database.get_table()
+     */
+    protected SQLite.TableResult tr;
+
+    /**
+     * Statement from which result set was produced.
+     */
+    private JDBCStatement s;
+
+    /**
+     * Meta data for result set or null.
+     */
+    private JDBCResultSetMetaData md;
+
+    /**
+     * Last result cell retrieved or null.
+     */
+    private String lastg;
+
+    /**
+     * Updatability of this result set.
+     */
+    private int updatable;
+
+    /**
+     * When updatable this is the table name.
+     */
+    private String uptable;
+
+    /**
+     * When updatable these are the PK column names of uptable.
+     */
+    private String pkcols[];
+
+    /**
+     * When updatable these are the PK column indices (0-based) of uptable.
+     */
+    private int pkcoli[];
+
+    /*
+     * Constants to reflect updateability.
+     */
+    private final static int UPD_UNKNOWN = -1;
+    private final static int UPD_NO = 0;
+    private final static int UPD_INS = 1;
+    private final static int UPD_INSUPDDEL = 2;
+
+    /**
+     * Flag for cursor being (not) on insert row.
+     */
+    private boolean oninsrow;
+
+    /**
+     * Row buffer for insert/update row.
+     */
+    private String rowbuf[];
+
+    private static final boolean nullrepl =
+        SQLite.Database.version().compareTo("2.5.0") < 0;
+
+    public JDBCResultSet(SQLite.TableResult tr, JDBCStatement s) {
+	this.tr = tr;
+	this.s = s;
+	this.md = null;
+	this.lastg = null;
+	this.row = -1;
+	this.updatable = UPD_UNKNOWN;
+	this.oninsrow = false;
+	this.rowbuf = null;
+    }
+
+    public boolean isUpdatable() throws SQLException {
+	if (updatable == UPD_UNKNOWN) {
+	    try {
+		JDBCResultSetMetaData m =
+		    (JDBCResultSetMetaData) getMetaData();
+		java.util.HashSet<String> h = new java.util.HashSet<String>();
+		String lastt = null;
+		for (int i = 1; i <= tr.ncolumns; i++) {
+		    lastt = m.getTableName(i);
+		    h.add(lastt);
+		}
+		if (h.size() > 1 || lastt == null) {
+		    updatable = UPD_NO;
+		    throw new SQLException("view or join");
+		}
+		updatable = UPD_INS;
+		uptable = lastt;
+		JDBCResultSet pk = (JDBCResultSet)
+		    s.conn.getMetaData().getPrimaryKeys(null, null, uptable);
+		if (pk.tr.nrows > 0) {
+		    boolean colnotfound = false;
+		    pkcols = new String[pk.tr.nrows];
+		    pkcoli = new int[pk.tr.nrows];
+		    for (int i = 0; i < pk.tr.nrows; i++) {
+			String rd[] = (String []) pk.tr.rows.elementAt(i);
+			pkcols[i] = rd[3];
+			try {
+			    pkcoli[i] = findColumn(pkcols[i]) - 1;
+			} catch (SQLException ee) {
+			    colnotfound = true;
+			}
+		    }
+		    if (!colnotfound) {
+			updatable = UPD_INSUPDDEL;
+		    }
+		}
+		pk.close();
+	    } catch (SQLException e) {
+		updatable = UPD_NO;
+	    }
+	}
+	if (updatable < UPD_INS) {
+	    throw new SQLException("result set not updatable");
+	}
+	return true;
+    }
+
+    public void fillRowbuf() throws SQLException {
+	if (rowbuf == null) {
+	    if (row < 0) {
+		throw new SQLException("cursor outside of result set");
+	    }
+	    rowbuf = new String[tr.ncolumns];
+	    System.arraycopy((String []) tr.rows.elementAt(row), 0,
+			     rowbuf, 0, tr.ncolumns);
+	}
+    }
+
+    public boolean next() throws SQLException {
+	if (tr == null) {
+	    return false;
+	}
+	row++;
+	return row < tr.nrows;
+    }
+
+    public int findColumn(String columnName) throws SQLException {
+	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
+	return m.findColByName(columnName);
+    }
+  
+    public int getRow() throws SQLException {
+	if (tr == null) {
+	    throw new SQLException("no rows");
+	}
+	return row + 1;
+    }
+
+    public boolean previous() throws SQLException {
+	if (tr == null) {
+	    // BEGIN android-changed: throw rather than return false.
+	    throw new SQLException("ResultSet already closed");
+	    // END android-changed
+	}
+	if (row >= 0) {
+	    row--;
+	}
+	return row >= 0;
+    }
+
+    public boolean absolute(int row) throws SQLException {
+	if (tr == null) {
+	    return false;
+	}
+	if (row < 0) {
+	    row = tr.nrows + 1 + row;
+	}
+	row--;
+	if (row < 0 || row > tr.nrows) {
+	    return false;
+	}
+	this.row = row;
+	return true;
+    }
+
+    public boolean relative(int row) throws SQLException {
+	if (tr == null) {
+	    return false;
+	}
+	if (this.row + row < 0 || this.row + row >= tr.nrows) {
+	    return false;
+	}
+	this.row += row;
+	return true;
+    }
+
+    public void setFetchDirection(int dir) throws SQLException {
+	if (dir != ResultSet.FETCH_FORWARD) {
+	    throw new SQLException("not supported");
+	}
+    }
+
+    public int getFetchDirection() throws SQLException {
+	return ResultSet.FETCH_FORWARD;
+    }
+
+    public void setFetchSize(int fsize) throws SQLException {
+	if (fsize != 1) {
+	    throw new SQLException("not supported");
+	}
+    }
+
+    public int getFetchSize() throws SQLException {
+	return 1;
+    }
+
+    public String getString(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	return lastg;
+    }
+
+    public String getString(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getString(col);
+    }
+
+    public int getInt(int columnIndex) throws SQLException {
+	Integer i = internalGetInt(columnIndex);
+	if (i != null) {
+	    return i.intValue();
+	}
+	return 0;
+    }
+
+    private Integer internalGetInt(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    return Integer.valueOf(lastg);
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public int getInt(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getInt(col);
+    }
+
+    public boolean getBoolean(int columnIndex) throws SQLException {
+	return getInt(columnIndex) == 1 ||
+	    Boolean.parseBoolean(getString(columnIndex)); // android-changed: performance
+    }
+
+    public boolean getBoolean(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getBoolean(col);
+    }
+
+    public ResultSetMetaData getMetaData() throws SQLException {
+	if (md == null) {
+	    md = new JDBCResultSetMetaData(this);
+	}
+	return md;
+    }
+
+    public short getShort(int columnIndex) throws SQLException {
+	Short sh = internalGetShort(columnIndex);
+	if (sh != null) {
+	    return sh.shortValue();
+	}
+	return 0;
+    }
+
+    private Short internalGetShort(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    return Short.valueOf(lastg);
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public short getShort(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getShort(col);
+    }
+
+    public java.sql.Time getTime(int columnIndex) throws SQLException {
+	return internalGetTime(columnIndex, null);
+    }
+
+    private java.sql.Time internalGetTime(int columnIndex,
+					  java.util.Calendar cal)
+	throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    if (s.conn.useJulian) {
+		try {
+		    return new java.sql.Time(SQLite.Database.long_from_julian(lastg));
+		} catch (java.lang.Exception ee) {
+		    return java.sql.Time.valueOf(lastg);
+		}
+	    } else {
+		try {
+		    return java.sql.Time.valueOf(lastg);
+		} catch (java.lang.Exception ee) {
+		    return new java.sql.Time(SQLite.Database.long_from_julian(lastg));
+		}
+	    }
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public java.sql.Time getTime(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getTime(col);
+    }
+
+    public java.sql.Time getTime(int columnIndex, java.util.Calendar cal)
+	throws SQLException {
+	return internalGetTime(columnIndex, cal);
+    }
+
+    public java.sql.Time getTime(String columnName, java.util.Calendar cal)
+	throws SQLException{
+	int col = findColumn(columnName);
+	return getTime(col, cal);
+    }
+
+    public java.sql.Timestamp getTimestamp(int columnIndex)
+	throws SQLException{
+	return internalGetTimestamp(columnIndex, null);
+    }
+
+    private java.sql.Timestamp internalGetTimestamp(int columnIndex,
+						    java.util.Calendar cal)
+	throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    if (s.conn.useJulian) {
+		try {
+		    return new java.sql.Timestamp(SQLite.Database.long_from_julian(lastg));
+		} catch (java.lang.Exception ee) {
+		    return java.sql.Timestamp.valueOf(lastg);
+		}
+	    } else {
+		try {
+		    return java.sql.Timestamp.valueOf(lastg);
+		} catch (java.lang.Exception ee) {
+		    return new java.sql.Timestamp(SQLite.Database.long_from_julian(lastg));
+		}
+	    }
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public java.sql.Timestamp getTimestamp(String columnName)
+	throws SQLException{
+	int col = findColumn(columnName);
+	return getTimestamp(col);
+    }
+
+    public java.sql.Timestamp getTimestamp(int columnIndex,
+					   java.util.Calendar cal)
+	throws SQLException {
+	return internalGetTimestamp(columnIndex, cal);
+    }
+
+    public java.sql.Timestamp getTimestamp(String columnName,
+					   java.util.Calendar cal)
+	throws SQLException {
+	int col = findColumn(columnName);
+	return getTimestamp(col, cal);
+    }
+
+    public java.sql.Date getDate(int columnIndex) throws SQLException {
+	return internalGetDate(columnIndex, null);
+    }
+
+    private java.sql.Date internalGetDate(int columnIndex,
+					  java.util.Calendar cal)
+	throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    if (s.conn.useJulian) {
+		try {
+		    return new java.sql.Date(SQLite.Database.long_from_julian(lastg));
+		} catch (java.lang.Exception ee) {
+		    return java.sql.Date.valueOf(lastg);
+		}
+	    } else {
+		try {
+		    return java.sql.Date.valueOf(lastg);
+		} catch (java.lang.Exception ee) {
+		    return new java.sql.Date(SQLite.Database.long_from_julian(lastg));
+		}
+	    }
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public java.sql.Date getDate(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getDate(col);
+    }
+
+    public java.sql.Date getDate(int columnIndex, java.util.Calendar cal)
+	throws SQLException{
+	return internalGetDate(columnIndex, cal);
+    }
+
+    public java.sql.Date getDate(String columnName, java.util.Calendar cal)
+	throws SQLException{
+	int col = findColumn(columnName);
+	return getDate(col, cal);
+    }
+
+    public double getDouble(int columnIndex) throws SQLException {
+	Double d = internalGetDouble(columnIndex);
+	if (d != null) {
+	    return d.doubleValue();
+	}
+	return 0;
+    }
+
+    private Double internalGetDouble(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    return Double.valueOf(lastg);
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+    
+    public double getDouble(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getDouble(col);
+    }
+
+    public float getFloat(int columnIndex) throws SQLException {
+	Float f = internalGetFloat(columnIndex);
+	if (f != null) {
+	    return f.floatValue();
+	}
+	return 0;
+    }
+
+    private Float internalGetFloat(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    return Float.valueOf(lastg);
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public float getFloat(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getFloat(col);
+    }
+
+    public long getLong(int columnIndex) throws SQLException {
+	Long l = internalGetLong(columnIndex);
+	if (l != null) {
+	    return l.longValue();
+	}
+	return 0;
+    }
+
+    private Long internalGetLong(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	try {
+	    return Long.valueOf(lastg);
+	} catch (java.lang.Exception e) {
+	    lastg = null;
+	}
+	return null;
+    }
+
+    public long getLong(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getLong(col);
+    }
+
+    @Deprecated
+    public java.io.InputStream getUnicodeStream(int columnIndex)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    @Deprecated
+    public java.io.InputStream getUnicodeStream(String columnName)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.io.InputStream getAsciiStream(String columnName)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.io.InputStream getAsciiStream(int columnIndex)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public BigDecimal getBigDecimal(String columnName)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    @Deprecated
+    public BigDecimal getBigDecimal(String columnName, int scale)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    @Deprecated
+    public BigDecimal getBigDecimal(int columnIndex, int scale)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.io.InputStream getBinaryStream(int columnIndex)
+	throws SQLException {
+	byte data[] = getBytes(columnIndex);
+	if (data != null) {
+	    return new java.io.ByteArrayInputStream(data);
+	}
+	return null;
+    }
+
+    public java.io.InputStream getBinaryStream(String columnName)
+	throws SQLException {
+	byte data[] = getBytes(columnName);
+	if (data != null) {
+	    return new java.io.ByteArrayInputStream(data);
+	}
+	return null;
+    }
+
+    public byte getByte(int columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public byte getByte(String columnName) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public byte[] getBytes(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	byte ret[] = null;
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	if (lastg != null) {
+	    ret = SQLite.StringEncoder.decode(lastg);
+	}
+	return ret;
+    }
+
+    public byte[] getBytes(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getBytes(col);
+    }
+
+    public String getCursorName() throws SQLException {
+	return null;
+    }
+
+    public Object getObject(int columnIndex) throws SQLException {
+	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
+	    throw new SQLException("column " + columnIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[columnIndex - 1];
+	Object ret = lastg;
+	if (tr instanceof TableResultX) {
+	    switch (((TableResultX) tr).sql_type[columnIndex - 1]) {
+	    case Types.SMALLINT:
+		ret = internalGetShort(columnIndex);
+		break;
+	    case Types.INTEGER:
+		ret = internalGetInt(columnIndex);
+		break;
+	    case Types.DOUBLE:
+		ret = internalGetDouble(columnIndex);
+		break;
+	    case Types.FLOAT:
+		ret = internalGetFloat(columnIndex);
+		break;
+	    case Types.BIGINT:
+		ret = internalGetLong(columnIndex);
+		break;
+	    case Types.BINARY:
+	    case Types.VARBINARY:
+	    case Types.LONGVARBINARY:
+		ret = getBytes(columnIndex);
+		break;
+	    case Types.NULL:
+		ret = null;
+		break;
+	    /* defaults to String below */
+	    }
+	}
+	return ret;
+    }
+
+    public Object getObject(String columnName) throws SQLException {
+	int col = findColumn(columnName);
+	return getObject(col);
+    }
+
+    public Object getObject(int columnIndex, java.util.Map map) 
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public Object getObject(String columnIndex, java.util.Map map)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Ref getRef(int columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Ref getRef(String columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Blob getBlob(int columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Blob getBlob(String columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Clob getClob(int columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Clob getClob(String columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Array getArray(int columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.sql.Array getArray(String columnIndex) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public java.io.Reader getCharacterStream(int columnIndex)
+	throws SQLException {
+	String data = getString(columnIndex);
+	if (data != null) {
+	    char[] cdata = data.toCharArray();
+	    return new java.io.CharArrayReader(cdata);
+	}
+	return null;
+    }
+
+    public java.io.Reader getCharacterStream(String columnName)
+	throws SQLException {
+	String data = getString(columnName);
+	if (data != null) {
+	    char[] cdata = data.toCharArray();
+	    return new java.io.CharArrayReader(cdata);
+	}
+	return null;
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public boolean wasNull() throws SQLException {
+	return lastg == null;
+    }
+	
+    public void clearWarnings() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public boolean isFirst() throws SQLException {
+	if (tr == null) {
+	    return true;
+	}
+	return row == 0;
+    }
+
+    public boolean isBeforeFirst() throws SQLException {
+	if (tr == null || tr.nrows <= 0) {
+	    return false;
+	}
+	return row < 0;
+    }
+
+    public void beforeFirst() throws SQLException {
+	if (tr == null) {
+	    return;
+	}
+	row = -1;
+    }
+
+    public boolean first() throws SQLException {
+	if (tr == null || tr.nrows <= 0) {
+	    return false;
+	}
+	row = 0;
+	return true;
+    }
+
+    public boolean isAfterLast() throws SQLException {
+	if (tr == null || tr.nrows <= 0) {
+	    return false;
+	}
+	return row >= tr.nrows;
+    }
+
+    public void afterLast() throws SQLException {
+	if (tr == null) {
+	    return;
+	}
+	row = tr.nrows;
+    }
+
+    public boolean isLast() throws SQLException {
+	if (tr == null) {
+	    return true;
+	}
+	return row == tr.nrows - 1;
+    }
+
+    public boolean last() throws SQLException {
+	if (tr == null || tr.nrows <= 0) {
+	    return false;
+	}
+	row = tr.nrows -1;
+	return true;
+    }
+
+    public int getType() throws SQLException {
+	return TYPE_SCROLL_SENSITIVE;
+    }
+
+    public int getConcurrency() throws SQLException {
+	return CONCUR_UPDATABLE;
+    }
+
+    public boolean rowUpdated() throws SQLException {
+	return false;
+    }
+
+    public boolean rowInserted() throws SQLException {
+	return false;
+    }
+
+    public boolean rowDeleted() throws SQLException {
+	return false;
+    }
+
+    public void insertRow() throws SQLException {
+	isUpdatable();
+	if (!oninsrow || rowbuf == null) {
+	    throw new SQLException("no insert data provided");
+	}
+	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
+	StringBuffer sb = new StringBuffer();
+	sb.append("INSERT INTO ");
+	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
+	sb.append("(");
+	for (int i = 0; i < tr.ncolumns; i++) {
+	    sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1)));
+	    if (i < tr.ncolumns - 1) {
+		sb.append(",");
+	    }
+	}
+	sb.append(") VALUES(");
+	for (int i = 0; i < tr.ncolumns; i++) {
+	    sb.append(nullrepl ? "'%q'" : "%Q");
+	    if (i < tr.ncolumns - 1) {
+		sb.append(",");
+	    }
+	}
+	sb.append(")");
+	try {
+	    this.s.conn.db.exec(sb.toString(), null, rowbuf);
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.getMessage());
+	}
+	tr.newrow(rowbuf);
+	rowbuf = null;
+	oninsrow = false;
+	last();
+    }
+
+    public void updateRow() throws SQLException {
+	isUpdatable();
+	if (rowbuf == null) {
+	    throw new SQLException("no update data provided");
+	}
+	if (oninsrow) {
+	    throw new SQLException("cursor on insert row");
+	}
+	if (updatable < UPD_INSUPDDEL) {
+	    throw new SQLException("no primary key on table defined");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
+	String args[] = new String[tr.ncolumns + pkcols.length];
+	StringBuffer sb = new StringBuffer();
+	sb.append("UPDATE ");
+	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
+	sb.append(" SET ");
+	int i;
+	for (i = 0; i < tr.ncolumns; i++) {
+	    sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1)));
+	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
+	    if (i < tr.ncolumns - 1) {
+		sb.append(",");
+	    }
+	    args[i] = rowbuf[i];
+	}
+	sb. append(" WHERE ");
+	for (int k = 0; k < pkcols.length; k++, i++) {
+	    sb.append(SQLite.Shell.sql_quote_dbl(pkcols[k]));
+	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
+	    if (k < pkcols.length - 1) {
+		sb.append(" AND ");
+	    }
+	    args[i] = rd[pkcoli[k]];
+	}
+	try {
+	    this.s.conn.db.exec(sb.toString(), null, args);
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.getMessage());
+	}
+	System.arraycopy(rowbuf, 0, rd, 0, rowbuf.length);
+	rowbuf = null;
+    }
+
+    public void deleteRow() throws SQLException {
+	isUpdatable();
+	if (oninsrow) {
+	    throw new SQLException("cursor on insert row");
+	}
+	if (updatable < UPD_INSUPDDEL) {
+	    throw new SQLException("no primary key on table defined");
+	}
+	fillRowbuf();
+	StringBuffer sb = new StringBuffer();
+	sb.append("DELETE FROM ");
+	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
+	sb.append(" WHERE ");
+	String args[] = new String[pkcols.length];
+	for (int i = 0; i < pkcols.length; i++) {
+	    sb.append(SQLite.Shell.sql_quote_dbl(pkcols[i]));
+	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
+	    if (i < pkcols.length - 1) {
+		sb.append(" AND ");
+	    }
+	    args[i] = rowbuf[pkcoli[i]];
+	}
+	try {
+	    this.s.conn.db.exec(sb.toString(), null, args);
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.getMessage());
+	}
+	rowbuf = null;
+    }
+
+    public void refreshRow() throws SQLException {
+	isUpdatable();
+	if (oninsrow) {
+	    throw new SQLException("cursor on insert row");
+	}
+	if (updatable < UPD_INSUPDDEL) {
+	    throw new SQLException("no primary key on table defined");
+	}
+	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
+	String rd[] = (String []) tr.rows.elementAt(row);
+	StringBuffer sb = new StringBuffer();
+	sb.append("SELECT ");
+	for (int i = 0; i < tr.ncolumns; i++) {
+	    sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1)));
+	    if (i < tr.ncolumns - 1) {
+		sb.append(",");
+	    }
+	}
+	sb.append(" FROM ");
+	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
+	sb.append(" WHERE ");
+	String args[] = new String[pkcols.length];
+	for (int i = 0; i < pkcols.length; i++) {
+	    sb.append(SQLite.Shell.sql_quote_dbl(pkcols[i]));
+	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
+	    if (i < pkcols.length - 1) {
+		sb.append(" AND ");
+	    }
+	    args[i] = rd[pkcoli[i]];
+	}
+	SQLite.TableResult trnew = null;
+	try {
+	    trnew = this.s.conn.db.get_table(sb.toString(), args);
+	} catch (SQLite.Exception e) {
+	    throw new SQLException(e.getMessage());
+	}
+	if (trnew.nrows != 1) {
+	    throw new SQLException("wrong size of result set");
+	}
+	rowbuf = null;
+	tr.rows.setElementAt(trnew.rows.elementAt(0), row);
+    }
+
+    public void cancelRowUpdates() throws SQLException {
+	rowbuf = null;
+    }
+
+    public void moveToInsertRow() throws SQLException {
+	isUpdatable();
+	if (!oninsrow) {
+	    oninsrow = true;
+	    rowbuf = new String[tr.nrows];
+	}
+    }
+
+    public void moveToCurrentRow() throws SQLException {
+	if (oninsrow) {
+	    oninsrow = false;
+	    rowbuf = null;
+	}
+    }
+
+    public void updateNull(int colIndex) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = null;
+    }
+
+    public void updateBoolean(int colIndex, boolean b) throws SQLException {
+	updateString(colIndex, b ? "1" : "0");
+    }
+
+    public void updateByte(int colIndex, byte b) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateShort(int colIndex, short b) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = Short.toString(b);
+    }
+
+    public void updateInt(int colIndex, int b) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = Integer.toString(b);
+    }
+
+    public void updateLong(int colIndex, long b) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = Long.toString(b);
+    }
+
+    public void updateFloat(int colIndex, float f) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = Float.toString(f);
+    }
+
+    public void updateDouble(int colIndex, double f) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = Double.toString(f);
+    }
+
+    public void updateBigDecimal(int colIndex, BigDecimal f)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateString(int colIndex, String s) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = s;
+    }
+
+    public void updateBytes(int colIndex, byte[] s) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	if (this.s.conn.db.is3()) {
+	    rowbuf[colIndex - 1] = SQLite.StringEncoder.encodeX(s);
+	} else {
+	    rowbuf[colIndex - 1] = SQLite.StringEncoder.encode(s);
+	}
+    }
+
+    public void updateDate(int colIndex, java.sql.Date d) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = d.toString();
+    }
+
+    public void updateTime(int colIndex, java.sql.Time t) throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = t.toString();
+    }
+
+    public void updateTimestamp(int colIndex, java.sql.Timestamp t)
+	throws SQLException {
+	isUpdatable();
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	fillRowbuf();
+	rowbuf[colIndex - 1] = t.toString();
+    }
+
+    public void updateAsciiStream(int colIndex, java.io.InputStream in, int s)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateBinaryStream(int colIndex, java.io.InputStream in, int s)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateCharacterStream(int colIndex, java.io.Reader in, int s)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateObject(int colIndex, Object obj) throws SQLException {
+	updateString(colIndex, obj.toString());
+    }
+
+    public void updateObject(int colIndex, Object obj, int s)
+	throws SQLException {
+	updateString(colIndex, obj.toString());
+    }
+
+    public void updateNull(String colName) throws SQLException {
+	int col = findColumn(colName);
+	updateNull(col);
+    }
+
+    public void updateBoolean(String colName, boolean b) throws SQLException {
+	int col = findColumn(colName);
+	updateBoolean(col, b);
+    }
+
+    public void updateByte(String colName, byte b) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateShort(String colName, short b) throws SQLException {
+	int col = findColumn(colName);
+	updateShort(col, b);
+    }
+
+    public void updateInt(String colName, int b) throws SQLException {
+	int col = findColumn(colName);
+	updateInt(col, b);
+    }
+
+    public void updateLong(String colName, long b) throws SQLException {
+	int col = findColumn(colName);
+	updateLong(col, b);
+    }
+
+    public void updateFloat(String colName, float f) throws SQLException {
+	int col = findColumn(colName);
+	updateFloat(col, f);
+    }
+
+    public void updateDouble(String colName, double f) throws SQLException {
+	int col = findColumn(colName);
+	updateDouble(col, f);
+    }
+
+    public void updateBigDecimal(String colName, BigDecimal f)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateString(String colName, String s) throws SQLException {
+	int col = findColumn(colName);
+	updateString(col, s);
+    }
+
+    public void updateBytes(String colName, byte[] s) throws SQLException {
+	int col = findColumn(colName);
+	updateBytes(col, s);
+    }
+
+    public void updateDate(String colName, java.sql.Date d)
+	throws SQLException {
+	int col = findColumn(colName);
+	updateDate(col, d);
+    }
+
+    public void updateTime(String colName, java.sql.Time t)
+	throws SQLException {
+	int col = findColumn(colName);
+	updateTime(col, t);
+    }
+
+    public void updateTimestamp(String colName, java.sql.Timestamp t)
+	throws SQLException {
+	int col = findColumn(colName);
+	updateTimestamp(col, t);
+    }
+
+    public void updateAsciiStream(String colName, java.io.InputStream in,
+				  int s)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateBinaryStream(String colName, java.io.InputStream in,
+				   int s)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateCharacterStream(String colName, java.io.Reader in,
+				      int s)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateObject(String colName, Object obj)
+	throws SQLException {
+	int col = findColumn(colName);
+	updateObject(col, obj);
+    }
+
+    public void updateObject(String colName, Object obj, int s)
+	throws SQLException {
+	int col = findColumn(colName);
+	updateObject(col, obj, s);
+    }
+
+    public Statement getStatement() throws SQLException {
+	if (s == null) {
+	    throw new SQLException("stale result set");
+	}
+	return s;
+    }
+
+    public void close() throws SQLException {
+	s = null;
+	tr = null;
+	lastg = null;
+	oninsrow = false;
+	rowbuf = null;
+	row = -1;
+    }
+
+    public java.net.URL getURL(int colIndex) throws SQLException {
+	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
+	    throw new SQLException("column " + colIndex + " not found");
+	}
+	String rd[] = (String []) tr.rows.elementAt(row);
+	lastg = rd[colIndex - 1];
+	java.net.URL url = null;
+	if (lastg == null) {
+	    return url;
+	}
+	try {
+	    url = new java.net.URL(lastg);
+	} catch (java.lang.Exception e) {
+	    url = null;
+	}
+	return url;
+    }
+
+    public java.net.URL getURL(String colName) throws SQLException {
+	int col = findColumn(colName);
+	return getURL(col);
+    }
+
+    public void updateRef(int colIndex, java.sql.Ref x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateRef(String colName, java.sql.Ref x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateBlob(int colIndex, java.sql.Blob x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateBlob(String colName, java.sql.Blob x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateClob(int colIndex, java.sql.Clob x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateClob(String colName, java.sql.Clob x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateArray(int colIndex, java.sql.Array x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void updateArray(String colName, java.sql.Array x)
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java
new file mode 100644
index 0000000..40be126
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java
@@ -0,0 +1,214 @@
+package SQLite.JDBC2y;
+
+import java.sql.*;
+
+public class JDBCResultSetMetaData implements java.sql.ResultSetMetaData {
+
+    private JDBCResultSet r;
+	
+    public JDBCResultSetMetaData(JDBCResultSet r) {
+	this.r = r;
+    }
+ 
+    public String getCatalogName(int column) throws java.sql.SQLException {
+	return null;
+    }
+
+    public String getColumnClassName(int column) throws java.sql.SQLException {
+	column--;
+	if (r != null && r.tr != null) {
+	    if (column < 0 || column >= r.tr.ncolumns) {
+		return null;
+	    }
+	    if (r.tr instanceof TableResultX) {
+		switch (((TableResultX) r.tr).sql_type[column]) {
+		case Types.SMALLINT:	return "java.lang.Short";
+		case Types.INTEGER:	return "java.lang.Integer";
+		case Types.REAL:
+		case Types.DOUBLE:	return "java.lang.Double";
+		case Types.FLOAT:	return "java.lang.Float";
+		case Types.BIGINT:	return "java.lang.Long";
+		case Types.DATE:	return "java.sql.Date";
+		case Types.TIME:	return "java.sql.Time";
+		case Types.TIMESTAMP:	return "java.sql.Timestamp";
+		case Types.BINARY:
+		case Types.VARBINARY:	return "[B";
+		/* defaults to varchar below */
+		}
+	    }
+	    return "java.lang.String";
+	}
+	return null;
+    }
+
+    public int getColumnCount() throws java.sql.SQLException {
+	if (r != null && r.tr != null) {
+	    return r.tr.ncolumns;
+	}
+	return 0;
+    }
+
+    public int getColumnDisplaySize(int column) throws java.sql.SQLException {
+	return 0;
+    }
+
+    public String getColumnLabel(int column) throws java.sql.SQLException {
+	column--;
+	String c = null;
+	if (r != null && r.tr != null) {
+	    if (column < 0 || column >= r.tr.ncolumns) {
+		return c;
+	    }
+	    c = r.tr.column[column];
+	}
+	return c;
+    }
+
+    public String getColumnName(int column) throws java.sql.SQLException {
+	column--;
+	String c = null;
+	if (r != null && r.tr != null) {
+	    if (column < 0 || column >= r.tr.ncolumns) {
+		return c;
+	    }
+	    c = r.tr.column[column];
+	    if (c != null) {
+		int i = c.indexOf('.');
+		if (i > 0) {
+		    return c.substring(i + 1);
+		}
+	    }
+	}
+	return c;
+    }
+
+    public int getColumnType(int column) throws java.sql.SQLException {
+	column--;
+	if (r != null && r.tr != null) {
+	    if (column >= 0 && column < r.tr.ncolumns) {
+		if (r.tr instanceof TableResultX) {
+		    return ((TableResultX) r.tr).sql_type[column];
+		}
+		return Types.VARCHAR;
+	    }
+	}
+	throw new SQLException("bad column index");
+    }
+
+    public String getColumnTypeName(int column) throws java.sql.SQLException {
+	column--;
+	if (r != null && r.tr != null) {
+	    if (column >= 0 && column < r.tr.ncolumns) {
+		if (r.tr instanceof TableResultX) {
+		    switch (((TableResultX) r.tr).sql_type[column]) {
+		    case Types.SMALLINT:	return "smallint";
+		    case Types.INTEGER:		return "integer";
+		    case Types.DOUBLE:		return "double";
+		    case Types.FLOAT:		return "float";
+		    case Types.BIGINT:		return "bigint";
+		    case Types.DATE:		return "date";
+		    case Types.TIME:		return "time";
+		    case Types.TIMESTAMP:	return "timestamp";
+		    case Types.BINARY:		return "binary";
+		    case Types.VARBINARY:	return "varbinary";
+		    case Types.REAL:		return "real";
+		    /* defaults to varchar below */
+		    }
+		}
+		return "varchar";
+	    }
+	}
+	throw new SQLException("bad column index");
+    }
+
+    public int getPrecision(int column) throws java.sql.SQLException {
+	return 0;
+    }
+
+    public int getScale(int column) throws java.sql.SQLException {
+	return 0;
+    }
+
+    public String getSchemaName(int column) throws java.sql.SQLException {
+	return null;
+    }
+
+    public String getTableName(int column) throws java.sql.SQLException {
+	column--;
+	String c = null;
+	if (r != null && r.tr != null) {
+	    if (column < 0 || column >= r.tr.ncolumns) {
+		return c;
+	    }
+	    c = r.tr.column[column];
+	    if (c != null) {
+		int i = c.indexOf('.');
+		if (i > 0) {
+		    return c.substring(0, i);
+		}
+		c = null;
+	    }
+	}
+	return c;
+    }
+
+    public boolean isAutoIncrement(int column) throws java.sql.SQLException {
+	return false;
+    }
+
+    public boolean isCaseSensitive(int column) throws java.sql.SQLException {
+	return false;
+    }
+
+    public boolean isCurrency(int column) throws java.sql.SQLException {
+	return false;
+    }
+
+    public boolean isDefinitelyWritable(int column) 
+	throws java.sql.SQLException {
+	return true;
+    }
+
+    public int isNullable(int column) throws java.sql.SQLException {
+	return columnNullableUnknown;
+    }
+
+    public boolean isReadOnly(int column) throws java.sql.SQLException {
+	return false;
+    }
+
+    public boolean isSearchable(int column) throws java.sql.SQLException {
+	return true;
+    }
+
+    public boolean isSigned(int column) throws java.sql.SQLException {
+	return false;
+    }
+
+    public boolean isWritable(int column) throws java.sql.SQLException {
+	return true;
+    }
+
+    int findColByName(String columnName) throws java.sql.SQLException {
+	String c = null;
+	if (r != null && r.tr != null) {
+	    for (int i = 0; i < r.tr.ncolumns; i++) {
+		c = r.tr.column[i];
+		if (c != null) {
+		    if (c.compareToIgnoreCase(columnName) == 0) {
+			return i + 1;
+		    }
+		    int k = c.indexOf('.');
+		    if (k > 0) {
+			c = c.substring(k + 1);
+			if (c.compareToIgnoreCase(columnName) == 0) {
+			    return i + 1;
+			}
+		    }
+		}
+		c = null;
+	    }
+	}
+	throw new SQLException("column " + columnName + " not found");
+    }
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java
new file mode 100644
index 0000000..0b5b26f
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java
@@ -0,0 +1,293 @@
+package SQLite.JDBC2y;
+
+import java.sql.*;
+import java.util.*;
+
+public class JDBCStatement implements java.sql.Statement {
+
+    protected JDBCConnection conn;
+    protected JDBCResultSet rs;
+    protected int updcnt;
+    protected int maxrows = 0;
+    private ArrayList<String> batch;
+
+    public JDBCStatement(JDBCConnection conn) {
+	this.conn = conn;
+	this.updcnt = 0;
+	this.rs = null;
+	this.batch = null;	
+    }
+
+    public void setFetchSize(int fetchSize) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int getFetchSize() throws SQLException {
+	return 1;
+    }
+
+    public int getMaxRows() throws SQLException {
+	return maxrows;
+    }
+
+    public void setMaxRows(int max) throws SQLException {
+        // BEGIN android-added: missing error checking.
+        if (max < 0) {
+            throw new SQLException("max must be >= 0 (was " + max + ")");
+        }
+        // END android-added
+	maxrows = max;
+    }
+
+    public void setFetchDirection(int fetchDirection) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int getFetchDirection() throws SQLException {
+	return ResultSet.FETCH_UNKNOWN;
+    }
+
+    public int getResultSetConcurrency() throws SQLException {
+	return ResultSet.CONCUR_READ_ONLY;
+    }
+
+    public int getResultSetType() throws SQLException {
+	return ResultSet.TYPE_SCROLL_INSENSITIVE;
+    }
+
+    public void setQueryTimeout(int seconds) throws SQLException {
+	conn.timeout = seconds * 1000;
+	if (conn.timeout < 0) {
+	    conn.timeout = 120000;
+	} else if (conn.timeout < 1000) {
+	    conn.timeout = 5000;
+	}
+    }
+
+    public int getQueryTimeout() throws SQLException {
+	return conn.timeout;
+    }
+
+    public ResultSet getResultSet() throws SQLException {
+	return rs;
+    }
+
+    ResultSet executeQuery(String sql, String args[], boolean updonly)
+	throws SQLException {
+	SQLite.TableResult tr = null;
+	if (rs != null) {
+	    rs.close();
+	    rs = null;
+	}
+	updcnt = -1;
+	if (conn == null || conn.db == null) {
+	    throw new SQLException("stale connection");
+	}
+	int busy = 0;
+	boolean starttrans = !conn.autocommit && !conn.intrans;
+	while (true) {
+	    try {
+		if (starttrans) {
+		    conn.db.exec("BEGIN TRANSACTION", null);
+		    conn.intrans = true;
+		}
+		if (args == null) {
+		    if (updonly) {
+			conn.db.exec(sql, null);
+		    } else {
+			tr = conn.db.get_table(sql, maxrows);
+		    }
+		} else {
+		    if (updonly) {
+			conn.db.exec(sql, null, args);
+		    } else {
+			tr = conn.db.get_table(sql, maxrows, args);
+		    }
+		}
+		updcnt = (int) conn.db.changes();
+	    } catch (SQLite.Exception e) {
+		if (conn.db.is3() &&
+		    conn.db.last_error() == SQLite.Constants.SQLITE_BUSY &&
+		    conn.busy3(conn.db, ++busy)) {
+		    try {
+			if (starttrans && conn.intrans) {
+			    conn.db.exec("ROLLBACK", null);
+			    conn.intrans = false;
+			}
+		    } catch (SQLite.Exception ee) {
+		    }
+		    try {
+			int ms = 20 + busy * 10;
+			if (ms > 1000) {
+			    ms = 1000;
+			}
+			synchronized (this) {
+			    this.wait(ms);
+			}
+		    } catch (java.lang.Exception eee) {
+		    }
+		    continue;
+		}
+		throw new SQLException(e.toString());
+	    }
+	    break;
+	}
+	if (!updonly && tr == null) {
+	    throw new SQLException("no result set produced");
+	}
+	if (!updonly && tr != null) {
+	    rs = new JDBCResultSet(new TableResultX(tr), this);
+	}
+	return rs;
+    }
+
+    public ResultSet executeQuery(String sql) throws SQLException {
+	return executeQuery(sql, null, false);
+    }
+
+    public boolean execute(String sql) throws SQLException {
+	return executeQuery(sql) != null;
+    }
+
+    public void cancel() throws SQLException {
+	if (conn == null || conn.db == null) {
+	    throw new SQLException("stale connection");
+	}
+	conn.db.interrupt();
+    }
+
+    public void clearWarnings() throws SQLException {
+    }
+
+    public Connection getConnection() throws SQLException {
+	return conn;
+    }
+
+    public void addBatch(String sql) throws SQLException {
+	if (batch == null) {
+	    batch = new ArrayList<String>(1);
+	}
+	batch.add(sql);
+    }
+
+    public int[] executeBatch() throws SQLException {
+	if (batch == null) {
+	    return new int[0];
+	}
+	int[] ret = new int[batch.size()];
+	for (int i = 0; i < ret.length; i++) {
+	    ret[i] = EXECUTE_FAILED;
+	}
+	int errs = 0;
+	for (int i = 0; i < ret.length; i++) {
+	    try {
+		execute((String) batch.get(i));
+		ret[i] = updcnt;
+	    } catch (SQLException e) {
+		++errs;
+	    }
+	}
+	if (errs > 0) {
+	    throw new BatchUpdateException("batch failed", ret);
+	}
+	return ret;
+    }
+
+    public void clearBatch() throws SQLException {
+	if (batch != null) {
+	    batch.clear();
+	    batch = null;
+	}
+    }
+
+    public void close() throws SQLException {
+	clearBatch();
+	conn = null;
+    }
+
+    public int executeUpdate(String sql) throws SQLException {
+	executeQuery(sql, null, true);
+	return updcnt;
+    }
+
+    public int getMaxFieldSize() throws SQLException {
+	return 0;
+    }
+
+    public boolean getMoreResults() throws SQLException {
+	if (rs != null) {
+	    rs.close();
+	    rs = null;
+	}
+	return false;
+    }
+
+    public int getUpdateCount() throws SQLException {
+	return updcnt;
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+	return null;
+    }
+
+    public void setCursorName(String name) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public void setMaxFieldSize(int max) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public boolean getMoreResults(int x) throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public ResultSet getGeneratedKeys() throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int executeUpdate(String sql, int autokeys)
+	throws SQLException {
+	if (autokeys != Statement.NO_GENERATED_KEYS) {
+	    throw new SQLException("not supported");
+	}
+	return executeUpdate(sql);
+    }
+
+    public int executeUpdate(String sql, int colIndexes[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int executeUpdate(String sql, String colIndexes[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public boolean execute(String sql, int autokeys)
+	throws SQLException {
+	if (autokeys != Statement.NO_GENERATED_KEYS) {
+	    throw new SQLException("not supported");
+	}
+	return execute(sql);
+    }
+
+    public boolean execute(String sql, int colIndexes[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public boolean execute(String sql, String colIndexes[])
+	throws SQLException {
+	throw new SQLException("not supported");
+    }
+
+    public int getResultSetHoldability() throws SQLException {
+	return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+    }
+
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java
new file mode 100644
index 0000000..1414fc0
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java
@@ -0,0 +1,46 @@
+package SQLite.JDBC2y;
+
+import java.sql.Types;
+import java.util.Vector;
+
+public class TableResultX extends SQLite.TableResult {
+    public int sql_type[];
+
+    public TableResultX() {
+	super();
+	sql_type = new int[this.ncolumns];
+	for (int i = 0; i < this.ncolumns; i++) {
+	    sql_type[i] = Types.VARCHAR;
+	}
+    }
+
+    public TableResultX(int maxrows) {
+	super(maxrows);
+	sql_type = new int[this.ncolumns];
+	for (int i = 0; i < this.ncolumns; i++) {
+	    sql_type[i] = Types.VARCHAR;
+	}
+    }
+
+    public TableResultX(SQLite.TableResult tr) {
+	this.column = tr.column;
+	this.rows = tr.rows;
+	this.ncolumns = tr.ncolumns;
+	this.nrows = tr.nrows;
+	this.types = tr.types;
+	this.maxrows = tr.maxrows;
+	sql_type = new int[tr.ncolumns];
+	for (int i = 0; i < this.ncolumns; i++) {
+	    sql_type[i] = Types.VARCHAR;
+	}
+	if (tr.types != null) {
+	    for (int i = 0; i < tr.types.length; i++) {
+		sql_type[i] = JDBCDatabaseMetaData.mapSqlType(tr.types[i]);
+	    }
+	}	
+    }
+
+    void sql_types(int types[]) {
+	sql_type = types;
+    } 
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java b/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java
new file mode 100644
index 0000000..c90035d
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java
@@ -0,0 +1,144 @@
+package SQLite;
+
+import java.sql.*;
+import java.util.Properties;
+
+public class JDBCDriver implements java.sql.Driver {
+
+    public static final int MAJORVERSION = 1;
+
+    public static boolean sharedCache = false;
+
+    public static String vfs = null;
+
+    private static java.lang.reflect.Constructor makeConn = null;
+
+    protected Connection conn;
+
+    static {
+	try {
+	    Class connClass = null;
+	    Class args[] = new Class[5];
+	    args[0] = Class.forName("java.lang.String");
+	    args[1] = args[0];
+	    args[2] = args[0];
+	    args[3] = args[0];
+	    args[4] = args[0];
+	    String jvers = java.lang.System.getProperty("java.version");
+	    String cvers;
+	    if (jvers == null || jvers.startsWith("1.0")) {
+		throw new java.lang.Exception("unsupported java version");
+	    } else if (jvers.startsWith("1.1")) {
+		cvers = "SQLite.JDBC1.JDBCConnection";
+	    } else if (jvers.startsWith("1.2") || jvers.startsWith("1.3")) {
+		cvers = "SQLite.JDBC2.JDBCConnection";
+	    } else if (jvers.startsWith("1.4")) {
+		cvers = "SQLite.JDBC2x.JDBCConnection";
+	    } else if (jvers.startsWith("1.5")) {
+		cvers = "SQLite.JDBC2y.JDBCConnection";
+		try {
+		    Class.forName(cvers);
+		} catch (java.lang.Exception e) {
+		    cvers = "SQLite.JDBC2x.JDBCConnection";
+		}
+	    } else {
+		cvers = "SQLite.JDBC2z.JDBCConnection";
+		try {
+		    Class.forName(cvers);
+		} catch (java.lang.Exception e) {
+		    cvers = "SQLite.JDBC2y.JDBCConnection";
+		    try {
+			Class.forName(cvers);
+		    } catch (java.lang.Exception ee) {
+			cvers = "SQLite.JDBC2x.JDBCConnection";
+		    }
+		}
+	    }
+	    connClass = Class.forName(cvers);
+	    makeConn = connClass.getConstructor(args);
+	    java.sql.DriverManager.registerDriver(new JDBCDriver());
+	    try {
+		String shcache =
+		    java.lang.System.getProperty("SQLite.sharedcache");
+		if (shcache != null &&
+		    (shcache.startsWith("y") || shcache.startsWith("Y"))) {
+		    sharedCache = SQLite.Database._enable_shared_cache(true);
+		}
+	    } catch (java.lang.Exception e) {
+	    }
+	    try {
+		String tvfs = 
+		    java.lang.System.getProperty("SQLite.vfs");
+		if (tvfs != null) {
+		    vfs = tvfs;
+		}
+	    } catch (java.lang.Exception e) {
+	    }
+	} catch (java.lang.Exception e) {
+	    System.err.println(e);
+	}
+    }
+
+    public JDBCDriver() {
+    }
+	
+    public boolean acceptsURL(String url) throws SQLException {
+	return url.startsWith("sqlite:/") ||
+	    url.startsWith("jdbc:sqlite:/");
+    }
+
+    public Connection connect(String url, Properties info)
+	throws SQLException {
+	if (!acceptsURL(url)) {
+	    return null;
+	}
+	Object args[] = new Object[5];
+	args[0] = url;
+	if (info != null) {
+	    args[1] = info.getProperty("encoding");
+	    args[2] = info.getProperty("password");
+	    args[3] = info.getProperty("daterepr");
+	    args[4] = info.getProperty("vfs");
+	}
+	if (args[1] == null) {
+	    args[1] = java.lang.System.getProperty("SQLite.encoding");
+	}
+	if (args[4] == null) {
+	    args[4] = vfs;
+	}
+	try {
+	    conn = (Connection) makeConn.newInstance(args);
+	} catch (java.lang.reflect.InvocationTargetException ie) {
+	    throw new SQLException(ie.getTargetException().toString());
+	} catch (java.lang.Exception e) {
+	    throw new SQLException(e.toString());
+	}
+	return conn;
+    }
+
+    public int getMajorVersion() {
+	return MAJORVERSION;
+    }
+
+    public int getMinorVersion() {
+	return Constants.drv_minor;
+    }
+
+    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
+	throws SQLException {
+	DriverPropertyInfo p[] = new DriverPropertyInfo[4];
+	DriverPropertyInfo pp = new DriverPropertyInfo("encoding", "");
+	p[0] = pp;
+	pp = new DriverPropertyInfo("password", "");
+	p[1] = pp;
+	pp = new DriverPropertyInfo("daterepr", "normal");
+	p[2] = pp;
+	pp = new DriverPropertyInfo("vfs", vfs);
+	p[3] = pp;
+	return p;
+    }
+
+    public boolean jdbcCompliant() {
+	return false;
+    }
+}
diff --git a/sql/src/main/java/SQLite/ProgressHandler.java b/sqlite-jdbc/src/main/java/SQLite/ProgressHandler.java
similarity index 100%
rename from sql/src/main/java/SQLite/ProgressHandler.java
rename to sqlite-jdbc/src/main/java/SQLite/ProgressHandler.java
diff --git a/sqlite-jdbc/src/main/java/SQLite/Shell.java b/sqlite-jdbc/src/main/java/SQLite/Shell.java
new file mode 100644
index 0000000..b25e8ca
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/Shell.java
@@ -0,0 +1,694 @@
+package SQLite;
+
+import SQLite.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * SQLite command line shell. This is a partial reimplementaion
+ * of sqlite/src/shell.c and can be invoked by:<P>
+ *
+ * <verb>
+ *     java SQLite.Shell [OPTIONS] database [SHELLCMD]
+ * or
+ *     java -jar sqlite.jar [OPTIONS] database [SHELLCMD]
+ * </verb>
+ */
+
+public class Shell implements Callback {
+    Database db;
+    boolean echo;
+    int count;
+    int mode;
+    boolean showHeader;
+    String tableName;
+    String sep;
+    String cols[];
+    int colwidth[];
+    String destTable;
+    PrintWriter pw;
+    PrintWriter err;
+
+    static final int MODE_Line = 0;
+    static final int MODE_Column = 1;
+    static final int MODE_List = 2;
+    static final int MODE_Semi = 3;
+    static final int MODE_Html = 4;
+    static final int MODE_Insert = 5;
+    static final int MODE_Insert2 = 6;
+
+    public Shell(PrintWriter pw, PrintWriter err) {
+	this.pw = pw;
+	this.err = err;
+    }
+
+    public Shell(PrintStream ps, PrintStream errs) {
+	pw = new PrintWriter(ps);
+	err = new PrintWriter(errs);
+    }
+
+    protected Object clone() {
+        Shell s = new Shell(this.pw, this.err);
+	s.db = db;
+	s.echo = echo;
+	s.mode = mode;
+	s.count = 0;
+	s.showHeader = showHeader;
+	s.tableName = tableName;
+	s.sep = sep;
+	s.colwidth = colwidth;
+	return s;
+    }
+
+    static public String sql_quote_dbl(String str) {
+	if (str == null) {
+	    return "NULL";
+	}
+	int i, single = 0, dbl = 0;
+	for (i = 0; i < str.length(); i++) {
+	    if (str.charAt(i) == '\'') {
+		single++;
+	    } else if (str.charAt(i) == '"') {
+		dbl++;
+	    }
+	}
+	if (dbl == 0) {
+	    return "\"" + str + "\"";
+	}
+	StringBuffer sb = new StringBuffer("\"");
+	for (i = 0; i < str.length(); i++) {
+	    char c = str.charAt(i);
+	    if (c == '"') {
+		sb.append("\"\"");
+	    } else {
+		sb.append(c);
+	    }
+	}
+	return sb.toString();
+    }
+
+    static public String sql_quote(String str) {
+	if (str == null) {
+	    return "NULL";
+	}
+	int i, single = 0, dbl = 0;
+	for (i = 0; i < str.length(); i++) {
+	    if (str.charAt(i) == '\'') {
+		single++;
+	    } else if (str.charAt(i) == '"') {
+		dbl++;
+	    }
+	}
+	if (single == 0) {
+	    return "'" + str + "'";
+	}
+	if (dbl == 0) {
+	    return "\"" + str + "\"";
+	}
+	StringBuffer sb = new StringBuffer("'");
+	for (i = 0; i < str.length(); i++) {
+	    char c = str.charAt(i);
+	    if (c == '\'') {
+		sb.append("''");
+	    } else {
+		sb.append(c);
+	    }
+	}
+	return sb.toString();
+    }
+
+    static String html_quote(String str) {
+	if (str == null) {
+	    return "NULL";
+	}
+	StringBuffer sb = new StringBuffer();
+	for (int i = 0; i < str.length(); i++) {
+	    char c = str.charAt(i);
+	    if (c == '<') {
+		sb.append("&lt;");
+	    } else if (c == '>') {
+		sb.append("&gt;");
+	    } else if (c == '&') {
+		sb.append("&amp;");
+	    } else {
+		int x = c;
+		if (x < 32 || x > 127) {
+		    sb.append("&#" + x + ";");
+		} else {
+		    sb.append(c);
+		}
+	    }
+	}
+	return sb.toString();
+    }
+
+    static boolean is_numeric(String str) {
+	try {
+	    Double d = Double.valueOf(str);
+	} catch (java.lang.Exception e) {
+	    return false;
+	}
+	return true;
+    }
+
+    void set_table_name(String str) {
+	if (str == null) {
+	    tableName = "";
+	    return;
+	}
+	if (db.is3()) {
+	    tableName = Shell.sql_quote_dbl(str);
+	} else {
+	    tableName = Shell.sql_quote(str);
+	}
+    }
+
+    public void columns(String args[]) {
+	cols = args;
+    }
+
+    public void types(String args[]) {
+	/* Empty body to satisfy SQLite.Callback interface. */
+    }
+
+    public boolean newrow(String args[]) {
+	int i;
+	String tname;
+	switch (mode) {
+	case Shell.MODE_Line:
+	    if (args.length == 0) {
+		break;
+	    }
+	    if (count++ > 0) {
+		pw.println("");
+	    }
+	    for (i = 0; i < args.length; i++) {
+		pw.println(cols[i] + " = " +
+			   args[i] == null ? "NULL" : args[i]);
+	    }
+	    break;
+	case Shell.MODE_Column:
+	    String csep = "";
+	    if (count++ == 0) {
+		colwidth = new int[args.length];
+		for (i = 0; i < args.length; i++) {
+		    int w, n;
+		    w = cols[i].length();
+		    if (w < 10) {
+			w = 10;
+		    }
+		    colwidth[i] = w;
+		    if (showHeader) {
+			pw.print(csep + cols[i]);
+			csep = " ";
+		    }
+		}
+		if (showHeader) {
+		    pw.println("");
+		}
+	    }
+	    if (args.length == 0) {
+		break;
+	    }
+	    csep = "";
+	    for (i = 0; i < args.length; i++) {
+		pw.print(csep + (args[i] == null ? "NULL" : args[i]));
+		csep = " ";
+	    }
+	    pw.println("");
+	    break;
+	case Shell.MODE_Semi:
+	case Shell.MODE_List:
+	    if (count++ == 0 && showHeader) {
+		for (i = 0; i < args.length; i++) {
+		    pw.print(cols[i] +
+			     (i == args.length - 1 ? "\n" : sep));
+		}
+	    }
+	    if (args.length == 0) {
+		break;
+	    }
+	    for (i = 0; i < args.length; i++) {
+		pw.print(args[i] == null ? "NULL" : args[i]);
+		if (mode == Shell.MODE_Semi) {
+		    pw.print(";");
+		} else if (i < args.length - 1) {
+		    pw.print(sep);
+		}
+	    }
+	    pw.println("");
+	    break;
+	case MODE_Html:
+	    if (count++ == 0 && showHeader) {
+		pw.print("<TR>");
+		for (i = 0; i < args.length; i++) {
+		    pw.print("<TH>" + html_quote(cols[i]) + "</TH>");
+		}
+		pw.println("</TR>");
+	    }
+	    if (args.length == 0) {
+		break;
+	    }
+	    pw.print("<TR>");
+	    for (i = 0; i < args.length; i++) {
+		pw.print("<TD>" + html_quote(args[i]) + "</TD>");
+	    }
+	    pw.println("</TR>");
+	    break;
+	case MODE_Insert:
+	    if (args.length == 0) {
+		break;
+	    }
+	    tname = tableName;
+	    if (destTable != null) {
+	        tname = destTable;
+	    }
+	    pw.print("INSERT INTO " + tname + " VALUES(");
+	    for (i = 0; i < args.length; i++) {
+	        String tsep = i > 0 ? "," : "";
+		if (args[i] == null) {
+		    pw.print(tsep + "NULL");
+		} else if (is_numeric(args[i])) {
+		    pw.print(tsep + args[i]);
+		} else {
+		    pw.print(tsep + sql_quote(args[i]));
+		}
+	    }
+	    pw.println(");");
+	    break;
+	case MODE_Insert2:
+	    if (args.length == 0) {
+		break;
+	    }
+	    tname = tableName;
+	    if (destTable != null) {
+	        tname = destTable;
+	    }
+	    pw.print("INSERT INTO " + tname + " VALUES(");
+	    for (i = 0; i < args.length; i++) {
+	        String tsep = i > 0 ? "," : "";
+		pw.print(tsep + args[i]);
+	    }
+	    pw.println(");");
+	    break;
+	}
+	return false;
+    }
+
+    void do_meta(String line) {
+        StringTokenizer st = new StringTokenizer(line.toLowerCase());
+	int n = st.countTokens();
+	if (n <= 0) {
+	    return;
+	}
+	String cmd = st.nextToken();
+	String args[] = new String[n - 1];
+	int i = 0;
+	while (st.hasMoreTokens()) {
+	    args[i] = st.nextToken();
+	    ++i;
+	}
+	if (cmd.compareTo(".dump") == 0) {
+	    new DBDump(this, args);
+	    return;
+	}
+	if (cmd.compareTo(".echo") == 0) {
+	    if (args.length > 0 &&
+		(args[0].startsWith("y") || args[0].startsWith("on"))) {
+		echo = true;
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".exit") == 0) {
+	    try {
+		db.close();
+	    } catch (Exception e) {
+	    }
+	    System.exit(0);
+	}
+	if (cmd.compareTo(".header") == 0) {
+	    if (args.length > 0 &&
+		(args[0].startsWith("y") || args[0].startsWith("on"))) {
+		showHeader = true;
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".help") == 0) {
+	    pw.println(".dump ?TABLE? ...  Dump database in text fmt");
+	    pw.println(".echo ON|OFF       Command echo on or off");
+	    pw.println(".enc ?NAME?        Change encoding");
+	    pw.println(".exit              Exit program");
+	    pw.println(".header ON|OFF     Display headers on or off");
+	    pw.println(".help              This message");
+	    pw.println(".mode MODE         Set output mode to\n" +
+		       "                   line, column, insert\n" +
+		       "                   list, or html");
+	    pw.println(".mode insert TABLE Generate SQL insert stmts");
+	    pw.println(".schema ?PATTERN?  List table schema");
+	    pw.println(".separator STRING  Set separator string");
+	    pw.println(".tables ?PATTERN?  List table names");
+	    return;
+	}
+	if (cmd.compareTo(".mode") == 0) {
+	    if (args.length > 0) {
+		if (args[0].compareTo("line") == 0) {
+		    mode = Shell.MODE_Line;
+		} else if (args[0].compareTo("column") == 0) {
+		    mode = Shell.MODE_Column;
+		} else if (args[0].compareTo("list") == 0) {
+		    mode = Shell.MODE_List;
+		} else if (args[0].compareTo("html") == 0) {
+		    mode = Shell.MODE_Html;
+		} else if (args[0].compareTo("insert") == 0) {
+		    mode = Shell.MODE_Insert;
+		    if (args.length > 1) {
+			destTable = args[1];
+		    }
+		}
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".separator") == 0) {
+	    if (args.length > 0) {
+		sep = args[0];
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".tables") == 0) {
+	    TableResult t = null;
+	    if (args.length > 0) {
+		try {
+		    String qarg[] = new String[1];
+		    qarg[0] = args[0];
+		    t = db.get_table("SELECT name FROM sqlite_master " +
+				     "WHERE type='table' AND " +
+				     "name LIKE '%%%q%%' " +
+				     "ORDER BY name", qarg);
+		} catch (Exception e) {
+		    err.println("SQL Error: " + e);
+		    err.flush();
+		}
+	    } else {
+		try {
+		    t = db.get_table("SELECT name FROM sqlite_master " +
+				     "WHERE type='table' ORDER BY name");
+		} catch (Exception e) {
+		    err.println("SQL Error: " + e);
+		    err.flush();
+		}
+	    }
+	    if (t != null) {
+		for (i = 0; i < t.nrows; i++) {
+		    String tab = ((String[]) t.rows.elementAt(i))[0];
+		    if (tab != null) {
+			pw.println(tab);
+		    }
+		}
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".schema") == 0) {
+	    if (args.length > 0) {
+		try {
+		    String qarg[] = new String[1];
+		    qarg[0] = args[0];
+		    db.exec("SELECT sql FROM sqlite_master " +
+			    "WHERE type!='meta' AND " +
+			    "name LIKE '%%%q%%' AND " +
+			    "sql NOTNULL " +
+			    "ORDER BY type DESC, name",
+			    this, qarg);
+		} catch (Exception e) {
+		    err.println("SQL Error: " + e);
+		    err.flush();
+		}
+	    } else {
+		try {
+		    db.exec("SELECT sql FROM sqlite_master " +
+			    "WHERE type!='meta' AND " +
+			    "sql NOTNULL " +
+			    "ORDER BY tbl_name, type DESC, name",
+			    this);
+		} catch (Exception e) {
+		    err.println("SQL Error: " + e);
+		    err.flush();
+		}
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".enc") == 0) {
+	    try {
+		db.set_encoding(args.length > 0 ? args[0] : null);
+	    } catch (Exception e) {
+		err.println("" + e);
+		err.flush();
+	    }
+	    return;
+	}
+	if (cmd.compareTo(".rekey") == 0) {
+	    try {
+		db.rekey(args.length > 0 ? args[0] : null);
+	    } catch (Exception e) {
+		err.println("" + e);
+		err.flush();
+	    }
+	    return;
+	}
+	err.println("Unknown command '" + cmd + "'");
+	err.flush();
+    }
+
+    String read_line(BufferedReader is, String prompt) {
+	try {
+	    if (prompt != null) {
+		pw.print(prompt);
+		pw.flush();
+	    }
+	    String line = is.readLine();
+	    return line;
+	} catch (IOException e) {
+	    return null;
+	}
+    }
+
+    void do_input(BufferedReader is) {
+	String line, sql = null;
+	String prompt = "SQLITE> ";
+	while ((line = read_line(is, prompt)) != null) {
+	    if (echo) {
+		pw.println(line);
+	    }
+	    if (line.length() > 0 && line.charAt(0) == '.') {
+	        do_meta(line);
+	    } else {
+		if (sql == null) {
+		    sql = line;
+		} else {
+		    sql = sql + " " + line;
+		}
+		if (Database.complete(sql)) {
+		    try {
+			db.exec(sql, this);
+		    } catch (Exception e) {
+			if (!echo) {
+			    err.println(sql);
+			}
+			err.println("SQL Error: " + e);
+			err.flush();
+		    }
+		    sql = null;
+		    prompt = "SQLITE> ";
+		} else {
+		    prompt = "SQLITE? ";
+		}
+	    }
+	    pw.flush();
+	}
+	if (sql != null) {
+	    err.println("Incomplete SQL: " + sql);
+	    err.flush();
+	}
+    }
+
+    void do_cmd(String sql) {
+        if (db == null) {
+	    return;
+	}
+        if (sql.length() > 0 && sql.charAt(0) == '.') {
+	    do_meta(sql);
+	} else {
+	    try {
+	        db.exec(sql, this);
+	    } catch (Exception e) {
+		err.println("SQL Error: " + e);
+		err.flush();
+	    }
+	}
+    }
+
+    public static void main(String args[]) {
+	String key = null;
+	Shell s = new Shell(System.out, System.err);
+	s.mode = Shell.MODE_List;
+	s.sep = "|";
+	s.showHeader = false;
+	s.db = new Database();
+	String dbname = null, sql = null;
+	for (int i = 0; i < args.length; i++) {
+	    if(args[i].compareTo("-html") ==0) {
+		s.mode = Shell.MODE_Html;
+	    } else if (args[i].compareTo("-list") == 0) {
+		s.mode = Shell.MODE_List;
+	    } else if (args[i].compareTo("-line") == 0) {
+		s.mode = Shell.MODE_Line;
+	    } else if (i < args.length - 1 &&
+		       args[i].compareTo("-separator") == 0) {
+		++i;
+		s.sep = args[i];
+	    } else if (args[i].compareTo("-header") == 0) {
+		s.showHeader = true;
+	    } else if (args[i].compareTo("-noheader") == 0) {
+		s.showHeader = false;
+	    } else if (args[i].compareTo("-echo") == 0) {
+		s.echo = true;
+	    } else if (args[i].compareTo("-key") == 0) {
+		++i;
+		key = args[i];
+	    } else if (dbname == null) {
+		dbname = args[i];
+	    } else if (sql == null) {
+		sql = args[i];
+	    } else {
+		System.err.println("Arguments: ?OPTIONS? FILENAME ?SQL?");
+		System.exit(1);
+	    }
+	}
+	if (dbname == null) {
+	    System.err.println("No database file given");
+	    System.exit(1);
+	}
+	try {
+	    s.db.open(dbname, 0);
+	} catch (Exception e) {
+	    System.err.println("Unable to open database: " + e);
+	    System.exit(1);
+	}
+	if (key != null) {
+	    try {
+		s.db.key(key);
+	    } catch (Exception e) {
+		System.err.println("Unable to set key: " + e);
+		System.exit(1);
+	    }
+	}
+	if (sql != null) {
+	    s.do_cmd(sql);
+	    s.pw.flush();
+	} else {
+	    BufferedReader is =
+		new BufferedReader(new InputStreamReader(System.in));
+	    s.do_input(is);
+	    s.pw.flush();
+	}
+	try {
+	    s.db.close();
+	} catch (Exception ee) {
+	}
+    }
+}
+
+/**
+ * Internal class for dumping an entire database.
+ * It contains a special callback interface to traverse the
+ * tables of the current database and output create SQL statements
+ * and for the data insert SQL statements.
+ */
+
+class DBDump implements Callback {
+    Shell s;
+
+    DBDump(Shell s, String tables[]) {
+        this.s = s;
+	s.pw.println("BEGIN TRANSACTION;");
+        if (tables == null || tables.length == 0) {
+	    try {
+	        s.db.exec("SELECT name, type, sql FROM sqlite_master " +
+			  "WHERE type!='meta' AND sql NOT NULL " +
+			  "ORDER BY substr(type,2,1), name", this);
+	    } catch (Exception e) {
+	        s.err.println("SQL Error: " + e);
+		s.err.flush();
+	    }
+	} else {
+	    String arg[] = new String[1];
+	    for (int i = 0; i < tables.length; i++) {
+	        arg[0] = tables[i];
+		try {
+		    s.db.exec("SELECT name, type, sql FROM sqlite_master " +
+			      "WHERE tbl_name LIKE '%q' AND type!='meta' " +
+			      " AND sql NOT NULL " +
+			      " ORDER BY substr(type,2,1), name",
+			      this, arg);
+		} catch (Exception e) {
+		    s.err.println("SQL Error: " + e);
+		    s.err.flush();
+		}
+	    }
+	}
+	s.pw.println("COMMIT;");
+    }
+
+    public void columns(String col[]) {
+	/* Empty body to satisfy SQLite.Callback interface. */
+    }
+
+    public void types(String args[]) {
+	/* Empty body to satisfy SQLite.Callback interface. */
+    }
+
+    public boolean newrow(String args[]) {
+        if (args.length != 3) {
+	    return true;
+	}
+	s.pw.println(args[2] + ";");
+	if (args[1].compareTo("table") == 0) {
+	    Shell s2 = (Shell) s.clone();
+	    s2.mode = Shell.MODE_Insert;
+	    s2.set_table_name(args[0]);
+	    String qargs[] = new String[1];
+	    qargs[0] = args[0];
+	    try {
+	        if (s2.db.is3()) {
+		    TableResult t = null;
+		    t = s2.db.get_table("PRAGMA table_info('%q')", qargs);
+		    String query;
+		    if (t != null) {
+		        StringBuffer sb = new StringBuffer();
+			String sep = "";
+
+			sb.append("SELECT ");
+			for (int i = 0; i < t.nrows; i++) {
+			    String col = ((String[]) t.rows.elementAt(i))[1];
+			    sb.append(sep + "quote(" +
+				      Shell.sql_quote_dbl(col) + ")");
+			    sep = ",";
+			}
+			sb.append(" from '%q'");
+			query = sb.toString();
+			s2.mode = Shell.MODE_Insert2;
+		    } else {
+		        query = "SELECT * from '%q'";
+		    }
+		    s2.db.exec(query, s2, qargs);
+		} else {
+		    s2.db.exec("SELECT * from '%q'", s2, qargs);
+		}
+	    } catch (Exception e) {
+	        s.err.println("SQL Error: " + e);
+		s.err.flush();
+		return true;
+	    }
+	}
+	return false;
+    }
+}
diff --git a/sql/src/main/java/SQLite/Stmt.java b/sqlite-jdbc/src/main/java/SQLite/Stmt.java
similarity index 94%
rename from sql/src/main/java/SQLite/Stmt.java
rename to sqlite-jdbc/src/main/java/SQLite/Stmt.java
index c4f72ed..f959ed2 100644
--- a/sql/src/main/java/SQLite/Stmt.java
+++ b/sqlite-jdbc/src/main/java/SQLite/Stmt.java
@@ -141,7 +141,7 @@
      */
 
     public native void bind_zeroblob(int pos, int length)
-    throws SQLite.Exception;
+	throws SQLite.Exception;
 
     /**
      * Return number of parameters in compiled SQLite3 statement.
@@ -165,7 +165,7 @@
      */
 
     public native int bind_parameter_index(String name)
-    throws SQLite.Exception;
+	throws SQLite.Exception;
 
 
     /**
@@ -226,16 +226,16 @@
 
     public Object column(int col) throws SQLite.Exception {
         switch (column_type(col)) {
-    case Constants.SQLITE_INTEGER:
-        return new Long(column_long(col));
-    case Constants.SQLITE_FLOAT:
-        return new Double(column_double(col));
-    case Constants.SQLITE_BLOB:
-        return column_bytes(col);
-    case Constants.SQLITE3_TEXT:
-        return column_string(col);
-    }
-    return null;
+	case Constants.SQLITE_INTEGER:
+            return Long.valueOf(column_long(col)); // android-changed: performance
+	case Constants.SQLITE_FLOAT:
+	    return new Double(column_double(col));
+	case Constants.SQLITE_BLOB:
+	    return column_bytes(col);
+	case Constants.SQLITE3_TEXT:
+	    return column_string(col);
+	}
+	return null;
     }
 
     /**
@@ -283,6 +283,6 @@
     private static native void internal_init();
 
     static {
-    internal_init();
+	internal_init();
     }
 }
diff --git a/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java b/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java
new file mode 100644
index 0000000..f02e77b
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java
@@ -0,0 +1,244 @@
+package SQLite;
+
+/**
+ * String encoder/decoder for SQLite.
+ *
+ * This module was kindly donated by Eric van der Maarel of Nedap N.V.
+ *
+ * This encoder was implemented based on an original idea from an anonymous
+ * author in the source code of the SQLite distribution.
+ * I feel obliged to provide a quote from the original C-source code:
+ *
+ * "The author disclaims copyright to this source code.  In place of
+ *  a legal notice, here is a blessing:
+ *
+ *     May you do good and not evil.
+ *     May you find forgiveness for yourself and forgive others.
+ *     May you share freely, never taking more than you give."
+ *
+ */
+
+public class StringEncoder {
+
+    /**
+     * Encodes the given byte array into a string that can be used by
+     * the SQLite database. The database cannot handle null (0x00) and
+     * the character '\'' (0x27). The encoding consists of escaping
+     * these characters with a reserved character (0x01). The escaping
+     * is applied after determining and applying a shift that minimizes
+     * the number of escapes required.
+     * With this encoding the data of original size n is increased to a
+     * maximum of 1+(n*257)/254.
+     * For sufficiently large n the overhead is thus less than 1.2%.
+     * @param a the byte array to be encoded. A null reference is handled as
+     *     an empty array.
+     * @return the encoded bytes as a string. When an empty array is
+     *     provided a string of length 1 is returned, the value of
+     *     which is bogus.
+     *     When decoded with this class' <code>decode</code> method
+     *     a string of size 1 will return an empty byte array.
+     */
+
+    public static String encode(byte[] a) {
+	// check input
+	if (a == null || a.length == 0) {
+	    // bogus shift, no data
+	    return "x";
+	}
+	// determine count
+	int[] cnt = new int[256];
+	for (int i = 0 ; i < a.length; i++) {
+	    cnt[a[i] & 0xff]++;
+	}
+	// determine shift for minimum number of escapes
+	int shift = 1;
+	int nEscapes = a.length;
+	for (int i = 1; i < 256; i++) {
+	    if (i == '\'') {
+		continue;
+	    }
+	    int sum = cnt[i] + cnt[(i + 1) & 0xff] + cnt[(i + '\'') & 0xff];
+	    if (sum < nEscapes) {
+		nEscapes = sum;
+		shift = i;
+		if (nEscapes == 0) {
+		    // cannot become smaller
+		    break;
+		}
+	    }
+	}
+	// construct encoded output
+	int outLen = a.length + nEscapes + 1;
+	StringBuffer out = new StringBuffer(outLen);
+	out.append((char)shift);
+	for (int i = 0; i < a.length; i++) {
+	    // apply shift
+	    char c = (char)((a[i] - shift)&0xff);
+	    // insert escapes
+	    if (c == 0) { // forbidden
+		out.append((char)1);
+		out.append((char)1);
+	    } else if (c == 1) { // escape character
+		out.append((char)1);
+		out.append((char)2);
+	    } else if (c == '\'') { // forbidden
+		out.append((char)1);
+		out.append((char)3);
+	    } else {
+		out.append(c);
+	    }
+	}
+	return out.toString();
+    }
+
+    /**
+     * Decodes the given string that is assumed to be a valid encoding
+     * of a byte array. Typically the given string is generated by
+     * this class' <code>encode</code> method.
+     * @param s the given string encoding.
+     * @return the byte array obtained from the decoding.
+     * @throws IllegalArgumentException when the string given is not
+     *    a valid encoded string for this encoder.
+     */
+
+    public static byte[] decode(String s) {
+	char[] a = s.toCharArray();
+	if (a.length > 2 && a[0] == 'X' &&
+	    a[1] == '\'' && a[a.length-1] == '\'') {
+	    // SQLite3 BLOB syntax
+	    byte[] result = new byte[(a.length-3)/2];
+	    for (int i = 2, k = 0; i < a.length - 1; i += 2, k++) {
+		byte tmp;
+		switch (a[i]) {
+		case '0': tmp = 0; break;
+		case '1': tmp = 1; break;
+		case '2': tmp = 2; break;
+		case '3': tmp = 3; break;
+		case '4': tmp = 4; break;
+		case '5': tmp = 5; break;
+		case '6': tmp = 6; break;
+		case '7': tmp = 7; break;
+		case '8': tmp = 8; break;
+		case '9': tmp = 9; break;
+		case 'A':
+		case 'a': tmp = 10; break;
+		case 'B':
+		case 'b': tmp = 11; break;
+		case 'C':
+		case 'c': tmp = 12; break;
+		case 'D':
+		case 'd': tmp = 13; break;
+		case 'E':
+		case 'e': tmp = 14; break;
+		case 'F':
+		case 'f': tmp = 15; break;
+		default:  tmp = 0; break;
+		}
+		result[k] = (byte) (tmp << 4);
+		switch (a[i+1]) {
+		case '0': tmp = 0; break;
+		case '1': tmp = 1; break;
+		case '2': tmp = 2; break;
+		case '3': tmp = 3; break;
+		case '4': tmp = 4; break;
+		case '5': tmp = 5; break;
+		case '6': tmp = 6; break;
+		case '7': tmp = 7; break;
+		case '8': tmp = 8; break;
+		case '9': tmp = 9; break;
+		case 'A':
+		case 'a': tmp = 10; break;
+		case 'B':
+		case 'b': tmp = 11; break;
+		case 'C':
+		case 'c': tmp = 12; break;
+		case 'D':
+		case 'd': tmp = 13; break;
+		case 'E':
+		case 'e': tmp = 14; break;
+		case 'F':
+		case 'f': tmp = 15; break;
+		default:  tmp = 0; break;
+		}
+		result[k] |= tmp;
+	    }
+	    return result;
+	}
+	// first element is the shift
+	byte[] result = new byte[a.length-1];
+	int i = 0;
+	int shift = s.charAt(i++);
+	int j = 0;
+	while (i < s.length()) {
+	    int c;
+	    if ((c = s.charAt(i++)) == 1) { // escape character found
+		if ((c = s.charAt(i++)) == 1) {
+		    c = 0;
+		} else if (c == 2) {
+		    c = 1;
+		} else if (c == 3) {
+		    c = '\'';
+		} else {
+		    throw new IllegalArgumentException(
+			"invalid string passed to decoder: " + j);
+		}
+	    }
+	    // do shift
+	    result[j++] = (byte)((c + shift) & 0xff);
+	}
+	int outLen = j;
+	// provide array of correct length
+	if (result.length != outLen) {
+	    result = byteCopy(result, 0, outLen, new byte[outLen]);
+	}
+	return result;
+    }
+
+    /**
+     * Copies count elements from source, starting at element with
+     * index offset, to the given target.
+     * @param source the source.
+     * @param offset the offset.
+     * @param count the number of elements to be copied.
+     * @param target the target to be returned.
+     * @return the target being copied to.
+     */
+
+    private static byte[] byteCopy(byte[] source, int offset,
+				   int count, byte[] target) {
+	for (int i = offset, j = 0; i < offset + count; i++, j++) {
+	    target[j] = source[i];
+	}
+	return target;
+    }
+
+
+    static final char[] xdigits = {
+	'0', '1', '2', '3', '4', '5', '6', '7',
+	'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+
+    /**
+     * Encodes the given byte array into SQLite3 blob notation, ie X'..'
+     * @param a the byte array to be encoded. A null reference is handled as
+     *     an empty array.
+     * @return the encoded bytes as a string.
+     */
+
+    public static String encodeX(byte[] a) {
+	// check input
+	if (a == null || a.length == 0) {
+	    return "X''";
+	}
+	int outLen = a.length * 2 + 3;
+	StringBuffer out = new StringBuffer(outLen);
+	out.append('X');
+	out.append('\'');
+	for (int i = 0; i < a.length; i++) {
+	    out.append(xdigits[(a[i] >> 4) & 0x0F]);
+	    out.append(xdigits[a[i] & 0x0F]);
+	}
+	out.append('\'');
+	return out.toString();
+    }
+}
diff --git a/sqlite-jdbc/src/main/java/SQLite/TableResult.java b/sqlite-jdbc/src/main/java/SQLite/TableResult.java
new file mode 100644
index 0000000..14337aa
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/TableResult.java
@@ -0,0 +1,159 @@
+package SQLite;
+
+import java.util.Vector;
+
+/**
+ * Class representing an SQLite result set as
+ * returned by the
+ * <A HREF="Database.html#get_table(java.lang.String)">Database.get_table</A>
+ * convenience method.
+ * <BR><BR>
+ * Example:<BR>
+ *
+ * <PRE>
+ *   ...
+ *   SQLite.Database db = new SQLite.Database();
+ *   db.open("db", 0);
+ *   System.out.print(db.get_table("select * from TEST"));
+ *   ...
+ * </PRE>
+ * Example output:<BR>
+ *
+ * <PRE>
+ *   id|firstname|lastname|
+ *   0|John|Doe|
+ *   1|Speedy|Gonzales|
+ *   ...
+ * </PRE>
+ */
+
+public class TableResult implements Callback {
+
+    /**
+     * Number of columns in the result set.
+     */
+
+    public int ncolumns;
+
+    /**
+     * Number of rows in the result set.
+     */
+
+    public int nrows;
+
+    /**
+     * Column names of the result set.
+     */
+
+    public String column[];
+
+    /**
+     * Types of columns of the result set or null.
+     */
+
+    public String types[];
+
+    /**
+     * Rows of the result set. Each row is stored as a String array.
+     */
+
+    public Vector rows;
+
+    /**
+     * Maximum number of rows to hold in the table.
+     */
+
+    public int maxrows = 0;
+
+    /**
+     * Flag to indicate Maximum number of rows condition.
+     */
+
+    public boolean atmaxrows;
+
+    /**
+     * Create an empty result set.
+     */
+
+    public TableResult() {
+	clear();
+    }
+
+    /**
+     * Create an empty result set with maximum number of rows.
+     */
+
+    public TableResult(int maxrows) {
+	this.maxrows = maxrows;
+	clear();
+    }
+
+    /**
+     * Clear result set.
+     */
+
+    public void clear() {
+	column = new String[0];
+	types = null;
+	rows = new Vector();
+	ncolumns = nrows = 0;
+	atmaxrows = false;
+    }
+
+    /**
+     * Callback method used while the query is executed.
+     */
+
+    public void columns(String coldata[]) {
+	column = coldata;
+	ncolumns = column.length;
+    }
+
+    /**
+     * Callback method used while the query is executed.
+     */
+
+    public void types(String types[]) {
+	this.types = types;
+    }
+
+    /**
+     * Callback method used while the query is executed.
+     */
+
+    public boolean newrow(String rowdata[]) {
+	if (rowdata != null) {
+	    if (maxrows > 0 && nrows >= maxrows) {
+		atmaxrows = true;
+		return true;
+	    }
+	    rows.addElement(rowdata);
+	    nrows++;
+	}
+	return false;
+    }
+
+    /**
+     * Make String representation of result set.
+     */
+
+    public String toString() {
+	StringBuffer sb = new StringBuffer();
+	int i;
+	for (i = 0; i < ncolumns; i++) {
+	    sb.append(column[i] == null ? "NULL" : column[i]);
+	    sb.append('|');
+	}
+	sb.append('\n');
+	for (i = 0; i < nrows; i++) {
+	    int k;
+	    String row[] = (String[]) rows.elementAt(i);
+	    for (k = 0; k < ncolumns; k++) {
+		sb.append(row[k] == null ? "NULL" : row[k]);
+		sb.append('|');
+	    }
+	    sb.append('\n');
+	}
+	return sb.toString();
+    }
+}
diff --git a/sql/src/main/java/SQLite/Trace.java b/sqlite-jdbc/src/main/java/SQLite/Trace.java
similarity index 100%
rename from sql/src/main/java/SQLite/Trace.java
rename to sqlite-jdbc/src/main/java/SQLite/Trace.java
diff --git a/sql/src/main/java/SQLite/Vm.java b/sqlite-jdbc/src/main/java/SQLite/Vm.java
similarity index 98%
rename from sql/src/main/java/SQLite/Vm.java
rename to sqlite-jdbc/src/main/java/SQLite/Vm.java
index 9856ed0..f47e12f 100644
--- a/sql/src/main/java/SQLite/Vm.java
+++ b/sqlite-jdbc/src/main/java/SQLite/Vm.java
@@ -73,6 +73,6 @@
     private static native void internal_init();
 
     static {
-    internal_init();
+	internal_init();
     }
 }
diff --git a/sql/src/main/native/sqlite_jni.c b/sqlite-jdbc/src/main/native/sqlite_jni.c
similarity index 91%
rename from sql/src/main/native/sqlite_jni.c
rename to sqlite-jdbc/src/main/native/sqlite_jni.c
index 341ef2e..bb5e2da 100644
--- a/sql/src/main/native/sqlite_jni.c
+++ b/sqlite-jdbc/src/main/native/sqlite_jni.c
@@ -1,11 +1,10 @@
 #include "JNIHelp.h"
+#include "sqlite_jni_defs.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
-#include "sqlite_jni_defs.h"
-
 #if HAVE_SQLITE2
 #include "sqlite.h"
 #endif
@@ -31,7 +30,9 @@
 #define HAVE_BOTH_SQLITE 1
 #endif
 
-#define CANT_PASS_VALIST_AS_CHARPTR
+#ifndef HAVE_SQLITE3_SHARED_CACHE
+#define HAVE_SQLITE3_SHARED_CACHE 0
+#endif
 
 #include "sqlite_jni.h"
 
@@ -182,7 +183,7 @@
     int len = 0;
 
     if (jstr) {
-        while (*jstr++) {
+	while (*jstr++) {
 	    len++;
 	}
     }
@@ -278,13 +279,23 @@
 static void
 throwex(JNIEnv *env, const char *msg)
 {
-    jniThrowException(env, "SQLite/Exception", msg);
+    jclass except = (*env)->FindClass(env, "SQLite/Exception");
+
+    (*env)->ExceptionClear(env);
+    if (except) {
+	(*env)->ThrowNew(env, except, msg);
+    }
 }
 
 static void
 throwoom(JNIEnv *env, const char *msg)
 {
-    jniThrowException(env, "java/lang/OutOfMemoryError", msg);
+    jclass except = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
+
+    (*env)->ExceptionClear(env);
+    if (except) {
+	(*env)->ThrowNew(env, except, msg);
+    }
 }
 
 static void
@@ -297,7 +308,12 @@
 static void
 throwioex(JNIEnv *env, const char *msg)
 {
-    jniThrowException(env, "java/io/IOException", msg);
+    jclass except = (*env)->FindClass(env, "java/io/IOException");
+
+    (*env)->ExceptionClear(env);
+    if (except) {
+	(*env)->ThrowNew(env, except, msg);
+    }
 }
 #endif
 
@@ -318,6 +334,7 @@
     dest->result = 0;
     dest->tofree = 0;
     if (haveutf) {
+        // BEGIN android-changed: leak/error reporting/simplification/performance.
         const jsize utfLength = (*env)->GetStringUTFLength(env, src);
         dest->result = dest->tofree = malloc(utfLength + 1);
         if (!dest->tofree) {
@@ -326,6 +343,7 @@
         }
         (*env)->GetStringUTFRegion(env, src, 0, utfLength, dest->result);
         return dest->result;
+        // END android-changed
     }
     if (enc) {
 	bytes = (*env)->CallObjectMethod(env, src,
@@ -403,7 +421,7 @@
 					    "(Ljava/lang/String;I)Z");
 
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return ret;
 	}
 	trans2utf(env, h->haveutf, h->enc, table, &tabstr);
@@ -411,7 +429,7 @@
 					(jint) count)
 	      != JNI_FALSE;
 	(*env)->DeleteLocalRef(env, tabstr.jstr);
-	(*env)->DeleteLocalRef(env, cls);
+	(*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
     }
     return ret;
 }
@@ -431,12 +449,12 @@
 					    "(Ljava/lang/String;I)Z");
 
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return ret;
 	}
 	ret = (*env)->CallBooleanMethod(env, h->bh, mid, 0, (jint) count)
 	    != JNI_FALSE;
-	(*env)->DeleteLocalRef(env, cls);
+	(*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
     }
     return ret;
 }
@@ -454,11 +472,11 @@
 	jmethodID mid = (*env)->GetMethodID(env, cls, "progress", "()Z");
 
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return ret;
 	}
 	ret = (*env)->CallBooleanMethod(env, h->ph, mid) != JNI_TRUE;
-	(*env)->DeleteLocalRef(env, cls);
+	(*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
     }
     return ret;
 }
@@ -676,41 +694,39 @@
 #endif
 #endif
 	}
-	mid = (*env)->GetMethodID(env, cls, "newrow",
-				  "([Ljava/lang/String;)Z");
-	if (mid) {
-	    jboolean rc;
+	if (data) {
+	    mid = (*env)->GetMethodID(env, cls, "newrow",
+				      "([Ljava/lang/String;)Z");
+	    if (mid) {
+		jboolean rc;
 
-	    if (data) {
 		arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0);
-	    } else {
-		arr = 0;
-	    }
-	    for (i = 0; arr && i < ncol; i++) {
-		if (data[i]) {
-		    transstr dats;
+		for (i = 0; arr && i < ncol; i++) {
+		    if (data[i]) {
+			transstr dats;
 
-		    trans2utf(env, h->haveutf, h->enc, data[i], &dats);
-		    (*env)->SetObjectArrayElement(env, arr, i, dats.jstr);
-		    exc = (*env)->ExceptionOccurred(env);
-		    if (exc) {
-			(*env)->DeleteLocalRef(env, exc);
-			return 1;
+			trans2utf(env, h->haveutf, h->enc, data[i], &dats);
+			(*env)->SetObjectArrayElement(env, arr, i, dats.jstr);
+			exc = (*env)->ExceptionOccurred(env);
+			if (exc) {
+			    (*env)->DeleteLocalRef(env, exc);
+			    return 1;
+			}
+			(*env)->DeleteLocalRef(env, dats.jstr);
 		    }
-		    (*env)->DeleteLocalRef(env, dats.jstr);
 		}
+		rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr);
+		exc = (*env)->ExceptionOccurred(env);
+		if (exc) {
+		    (*env)->DeleteLocalRef(env, exc);
+		    return 1;
+		}
+		if (arr) {
+		    (*env)->DeleteLocalRef(env, arr);
+		}
+		(*env)->DeleteLocalRef(env, cls);
+		return rc != JNI_FALSE;
 	    }
-	    rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr);
-	    exc = (*env)->ExceptionOccurred(env);
-	    if (exc) {
-		(*env)->DeleteLocalRef(env, exc);
-		return 1;
-	    }
-	    if (arr) {
-		(*env)->DeleteLocalRef(env, arr);
-	    }
-	    (*env)->DeleteLocalRef(env, cls);
-	    return rc != JNI_FALSE;
 	}
     }
     return 0;
@@ -789,7 +805,7 @@
 	    bl->next = 0;
 	    bl->h = 0;
 	    if (bl->blob) {
-	        sqlite3_blob_close(bl->blob);
+		sqlite3_blob_close(bl->blob);
 	    }
 	    bl->blob = 0;
 	}
@@ -982,13 +998,21 @@
 }
 
 JNIEXPORT void JNICALL
-Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode)
+Java_SQLite_Database__1open4(JNIEnv *env, jobject obj, jstring file, jint mode,
+			     jstring vfs, jboolean ver2)
 {
     handle *h = gethandle(env, obj);
     jthrowable exc;
     char *err = 0;
     transstr filename;
     int maj, min, lev;
+#if HAVE_SQLITE3_OPEN_V2
+    transstr vfsname;
+
+    vfsname.result = 0;
+    vfsname.tofree = 0;
+    vfsname.jstr = 0;
+#endif
 
     if (h) {
 	if (h->sqlite) {
@@ -1052,6 +1076,17 @@
 	(*env)->DeleteLocalRef(env, exc);
 	return;
     }
+#if HAVE_SQLITE3_OPEN_V2
+    if (vfs) {
+	trans2iso(env, 1, h->enc, vfs, &vfsname);
+	exc = (*env)->ExceptionOccurred(env);
+	if (exc) {
+	    transfree(&filename);
+	    (*env)->DeleteLocalRef(env, exc);
+	    return;
+	}
+    }
+#endif
 #if HAVE_BOTH_SQLITE
     {
 	FILE *f = fopen(filename.result, "rb");
@@ -1061,8 +1096,13 @@
 	    c_0 = fgetc(f);
 	    fclose(f);
 	}
-	if (c_0 != '*') {
+	if (c_0 != '*' && ver2 == JNI_FALSE) {
+#if HAVE_SQLITE3_OPEN_V2
+	    int rc = sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite,
+				     (int) mode, vfsname.result);
+#else
 	    int rc = sqlite3_open(filename.result, (sqlite3 **) &h->sqlite);
+#endif
 
 	    if (rc == SQLITE_OK) {
 		h->is3 = 1;
@@ -1080,7 +1120,13 @@
     h->sqlite = (void *) sqlite_open(filename.result, (int) mode, &err);
 #endif
 #if HAVE_SQLITE3
-    if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK) {
+#if HAVE_SQLITE3_OPEN_V2
+    if (sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite,
+			(int) mode, vfsname.result) != SQLITE_OK)
+#else
+    if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK)
+#endif
+    {
         if (h->sqlite) {
 	    sqlite3_close((sqlite3 *) h->sqlite);
 	    h->sqlite = 0;
@@ -1089,6 +1135,9 @@
 #endif
 #endif
     transfree(&filename);
+#if HAVE_SQLITE3_OPEN_V2
+    transfree(&vfsname);
+#endif
     exc = (*env)->ExceptionOccurred(env);
     if (exc) {
 	(*env)->DeleteLocalRef(env, exc);
@@ -1131,6 +1180,9 @@
 #if HAVE_BOTH_SQLITE
 	if (h->is3) {
 	    sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
+#if HAVE_SQLITE3_LOAD_EXTENSION
+	    sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1);
+#endif
 	} else {
 	    sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev);
 	}
@@ -1140,6 +1192,9 @@
 #endif
 #if HAVE_SQLITE3
 	sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev);
+#if HAVE_SQLITE3_LOAD_EXTENSION
+	sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1);
+#endif
 #endif
 #endif
 	h->ver = ((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (lev & 0xFF);
@@ -1154,6 +1209,12 @@
 }
 
 JNIEXPORT void JNICALL
+Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode)
+{
+    Java_SQLite_Database__1open4(env, obj, file, mode, 0, 0);
+}
+
+JNIEXPORT void JNICALL
 Java_SQLite_Database__1open_1aux_1file(JNIEnv *env, jobject obj, jstring file)
 {
     handle *h = gethandle(env, obj);
@@ -1325,7 +1386,7 @@
 	    jthrowable exc;
 	    int rc = SQLITE_ERROR, nargs, i;
 	    char *err = 0, *p;
-	    const char *str = (*env)->GetStringUTFChars(env, sql, NULL);
+	    const char *str = (*env)->GetStringUTFChars(env, sql, NULL); // android-changed: unused variable
 	    transstr sqlstr;
 	    struct args {
 		char *arg;
@@ -1601,7 +1662,7 @@
 	int i;
 
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return;
 	}
 	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
@@ -1650,7 +1711,7 @@
 	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
 					    "(LSQLite/FunctionContext;)V");
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return;
 	}
 	f->sf = sf;
@@ -1677,7 +1738,7 @@
 	int i;
 
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return;
 	}
 	arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0);
@@ -1727,7 +1788,7 @@
 	jmethodID mid = (*env)->GetMethodID(env, cls, "last_step",
 					    "(LSQLite/FunctionContext;)V");
 	if (mid == 0) {
-	    (*env)->DeleteLocalRef(env, cls);
+	    (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak
 	    return;
 	}
 	f->sf = sf;
@@ -2506,7 +2567,8 @@
 
     if (v && v->vm && v->h) {
 	jthrowable exc;
-	int ret, ncol = 0;
+	int ret, tmp;
+	long ncol = 0;
 #if HAVE_SQLITE3
 	freemem *freeproc = 0;
 	const char **blob = 0;
@@ -2517,7 +2579,29 @@
 #if HAVE_BOTH_SQLITE
 	if (v->is3) {
 	    ret = sqlite3_step((sqlite3_stmt *) v->vm);
-	    if (ret == SQLITE_ROW) {
+	    if (ret == SQLITE_DONE && v->hh.row1) {
+		ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
+		if (ncol > 0) {
+		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
+		    if (data) {
+			data[0] = (const char *) ncol;
+			++data;
+			cols = data + ncol + 1;
+			blob = cols + ncol + 1;
+			freeproc = free_tab;
+		    } else {
+			ret = SQLITE_NOMEM;
+		    }
+		}
+		if (ret != SQLITE_NOMEM) {
+		    int i;
+
+		    for (i = 0; i < ncol; i++) {
+			cols[i] =
+			    sqlite3_column_name((sqlite3_stmt *) v->vm, i);
+		    }
+		}
+	    } else if (ret == SQLITE_ROW) {
 		ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
 		if (ncol > 0) {
 		    data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
@@ -2570,15 +2654,41 @@
 		}
 	    }
 	} else {
-	    ret = sqlite_step((sqlite_vm *) v->vm, &ncol, &data, &cols);
+	    tmp = 0;
+	    ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols);
+	    ncol = tmp;
 	}
 #else
 #if HAVE_SQLITE2
-	ret = sqlite_step((sqlite_vm *) v->vm, &ncol, &data, &cols);
+	tmp = 0;
+	ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols);
+	ncol = tmp;
 #endif
 #if HAVE_SQLITE3
 	ret = sqlite3_step((sqlite3_stmt *) v->vm);
-	if (ret == SQLITE_ROW) {
+	if (ret == SQLITE_DONE && v->hh.row1) {
+	    ncol = sqlite3_column_count((sqlite3_stmt *) v->vm);
+	    if (ncol > 0) {
+		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
+		if (data) {
+		    data[0] = (const char *) ncol;
+		    ++data;
+		    cols = data + ncol + 1;
+		    blob = cols + ncol + 1;
+		    freeproc = free_tab;
+		} else {
+		    ret = SQLITE_NOMEM;
+		}
+	    }
+	    if (ret != SQLITE_NOMEM) {
+		int i;
+
+		for (i = 0; i < ncol; i++) {
+		    cols[i] =
+			sqlite3_column_name((sqlite3_stmt *) v->vm, i);
+		}
+	    }
+	} else if (ret == SQLITE_ROW) {
 	    ncol = sqlite3_data_count((sqlite3_stmt *) v->vm);
 	    if (ncol > 0) {
 		data = calloc(ncol * 3 + 3 + 1, sizeof (char *));
@@ -2656,6 +2766,29 @@
 	    return JNI_TRUE;
 	} else if (ret == SQLITE_DONE) {
 dofin:
+	    if (v->hh.row1 && cols) {
+		v->hh.cb = cb;
+		v->hh.env = env;
+#if HAVE_BOTH_SQLITE
+		if (v->is3) {
+		    v->hh.stmt = (sqlite3_stmt *) v->vm;
+		}
+#else
+#if HAVE_SQLITE3
+		v->hh.stmt = (sqlite3_stmt *) v->vm;
+#endif
+#endif
+		callback((void *) &v->hh, ncol, (char **) 0, (char **) cols);
+#if HAVE_SQLITE3
+		if (data && freeproc) {
+		    freeproc((void *) data);
+		}
+#endif
+		exc = (*env)->ExceptionOccurred(env);
+		if (exc) {
+		    (*env)->DeleteLocalRef(env, exc);
+		}
+	    }
 #if HAVE_BOTH_SQLITE
 	    if (v->is3) {
 		sqlite3_finalize((sqlite3_stmt *) v->vm);
@@ -2706,6 +2839,9 @@
     hvm *v = gethvm(env, obj);
     void *svm = 0;
     char *err = 0;
+#ifdef HAVE_SQLITE2
+    char *errfr = 0;
+#endif
     const char *tail;
     int ret;
 
@@ -2745,11 +2881,13 @@
 		    sqlite3_finalize((sqlite3_stmt *) svm);
 		    svm = 0;
 		}
+		err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite);
 	    }
 	} else {
 	    ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
-				 &tail, (sqlite_vm **) &svm, &err);
+				 &tail, (sqlite_vm **) &svm, &errfr);
 	    if (ret != SQLITE_OK) {
+		err = errfr;
 		if (svm) {
 		    sqlite_finalize((sqlite_vm *) svm, 0);
 		    svm = 0;
@@ -2759,8 +2897,9 @@
 #else
 #if HAVE_SQLITE2
 	ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail,
-			     &tail, (sqlite_vm **) &svm, &err);
+			     &tail, (sqlite_vm **) &svm, &errfr);
 	if (ret != SQLITE_OK) {
+	    err = errfr;
 	    if (svm) {
 		sqlite_finalize((sqlite_vm *) svm, 0);
 		svm = 0;
@@ -2780,6 +2919,7 @@
 		sqlite3_finalize((sqlite3_stmt *) svm);
 		svm = 0;
 	    }
+	    err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite);
 	}
 #endif
 #endif
@@ -2788,15 +2928,15 @@
 	    v->tail = 0;
 	    throwex(env, err ? err : "error in compile/prepare");
 #if HAVE_SQLITE2
-	    if (err) {
-		sqlite_freemem(err);
+	    if (errfr) {
+		sqlite_freemem(errfr);
 	    }
 #endif
 	    return JNI_FALSE;
 	}
 #if HAVE_SQLITE2
-	if (err) {
-	    sqlite_freemem(err);
+	if (errfr) {
+	    sqlite_freemem(errfr);
 	}
 #endif
 	if (!svm) {
@@ -2824,6 +2964,9 @@
     void *svm = 0;
     hvm *v;
     char *err = 0;
+#if HAVE_SQLITE2
+    char *errfr = 0;
+#endif
     const char *tail;
     transstr tr;
     jvalue vv;
@@ -2863,11 +3006,13 @@
 		sqlite3_finalize((sqlite3_stmt *) svm);
 		svm = 0;
 	    }
+	    err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite);
 	}
     } else {
 	ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
-			     (sqlite_vm **) &svm, &err);
+			     (sqlite_vm **) &svm, &errfr);
 	if (ret != SQLITE_OK) {
+	    err = errfr;
 	    if (svm) {
 		sqlite_finalize((sqlite_vm *) svm, 0);
 	    }
@@ -2876,8 +3021,9 @@
 #else
 #if HAVE_SQLITE2
     ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail,
-			 (sqlite_vm **) &svm, &err);
+			 (sqlite_vm **) &svm, &errfr);
     if (ret != SQLITE_OK) {
+	err = errfr;
 	if (svm) {
 	    sqlite_finalize((sqlite_vm *) svm, 0);
 	    svm = 0;
@@ -2897,6 +3043,7 @@
 	    sqlite3_finalize((sqlite3_stmt *) svm);
 	    svm = 0;
 	}
+	err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite);
     }
 #endif
 #endif
@@ -2905,15 +3052,15 @@
 	setvmerr(env, vm, ret);
 	throwex(env, err ? err : "error in prepare/compile");
 #if HAVE_SQLITE2
-	if (err) {
-	    sqlite_freemem(err);
+	if (errfr) {
+	    sqlite_freemem(errfr);
 	}
 #endif
 	return;
     }
 #if HAVE_SQLITE2
-    if (err) {
-	sqlite_freemem(err);
+    if (errfr) {
+	sqlite_freemem(errfr);
     }
 #endif
     if (!svm) {
@@ -3005,7 +3152,7 @@
 	jthrowable exc;
 	int rc = SQLITE_ERROR, nargs, i;
 	char *p;
-	const char *str = (*env)->GetStringUTFChars(env, sql, NULL);
+	const char *str = (*env)->GetStringUTFChars(env, sql, NULL); // android-changed: unused variable
 	const char *tail;
 	transstr sqlstr;
 	struct args {
@@ -3394,7 +3541,7 @@
 	return;
     }
     len16 = len16 + sizeof (jchar) - ((char *) tail - (char *) sql16);
-    if (len16 < (jsize) sizeof (jchar)) {
+    if (len16 < (jsize) sizeof (jchar)) { // android-changed: signed/unsigned comparison
         len16 = sizeof (jchar);
     }
     v = malloc(sizeof (hvm) + len16);
@@ -3667,6 +3814,7 @@
 	    return;
 	}
 	if (val) {
+	    // BEGIN android-changed: simplification/performance.
 	    const jsize charCount = (*env)->GetStringLength(env, val);
 	    len = charCount * sizeof(jchar);
 	    if (len > 0) {
@@ -3683,6 +3831,7 @@
 	        ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm, pos, "", 0,
 					  SQLITE_STATIC);
 	    }
+	    // END android-changed
 	} else {
 	    ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos);
 	}
@@ -4298,6 +4447,108 @@
 #endif
 }
 
+JNIEXPORT void
+JNICALL Java_SQLite_Database__1key(JNIEnv *env, jobject obj, jbyteArray key)
+{
+    jsize len;
+    jbyte *data;
+#if HAVE_SQLITE3_KEY
+    handle *h = gethandle(env, obj);
+#endif
+
+    len = (*env)->GetArrayLength(env, key);
+    data = (*env)->GetByteArrayElements(env, key, 0);
+    if (len == 0) {
+	data = 0;
+    }
+    if (!data) {
+	len = 0;
+    }
+#if HAVE_SQLITE3_KEY
+    if (h && h->sqlite) {
+#if HAVE_BOTH_SQLITE
+	if (!h->is3) {
+	    if (data) {
+		memset(data, 0, len);
+	    }
+	    throwex(env, "unsupported");
+	}
+#endif
+	sqlite3_key((sqlite3 *) h->sqlite, data, len);
+	if (data) {
+	    memset(data, 0, len);
+	}
+    } else {
+	if (data) {
+	    memset(data, 0, len);
+	}
+	throwclosed(env);
+    }
+#else
+    if (data) {
+	memset(data, 0, len);
+    }
+    /* no error */
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_SQLite_Database__1rekey(JNIEnv *env, jobject obj, jbyteArray key)
+{
+    jsize len;
+    jbyte *data;
+#if HAVE_SQLITE3_KEY
+    handle *h = gethandle(env, obj);
+#endif
+
+    len = (*env)->GetArrayLength(env, key);
+    data = (*env)->GetByteArrayElements(env, key, 0);
+    if (len == 0) {
+	data = 0;
+    }
+    if (!data) {
+	len = 0;
+    }
+#if HAVE_SQLITE3_KEY
+    if (h && h->sqlite) {
+#if HAVE_BOTH_SQLITE
+	if (!h->is3) {
+	    if (data) {
+		memset(data, 0, len);
+	    }
+	    throwex(env, "unsupported");
+	}
+#endif
+	sqlite3_rekey((sqlite3 *) h->sqlite, data, len);
+	if (data) {
+	    memset(data, 0, len);
+	}
+    } else {
+	if (data) {
+	    memset(data, 0, len);
+	}
+	throwclosed(env);
+    }
+#else
+    if (data) {
+	memset(data, 0, len);
+    }
+    throwex(env, "unsupported");
+#endif
+}
+
+JNIEXPORT jboolean JNICALL
+Java_SQLite_Database__1enable_1shared_1cache(JNIEnv *env, jclass cls,
+					     jboolean onoff)
+{
+#if HAVE_SQLITE3_SHARED_CACHE
+    return (sqlite3_enable_shared_cache(onoff == JNI_TRUE) == SQLITE_OK) ?
+	   JNI_TRUE : JNI_FALSE;
+#else
+    return JNI_FALSE;
+#endif
+}
+
 JNIEXPORT void JNICALL
 Java_SQLite_Stmt_internal_1init(JNIEnv *env, jclass cls)
 {
@@ -4328,11 +4579,13 @@
 JNIEXPORT void JNICALL
 Java_SQLite_Database_internal_1init(JNIEnv *env, jclass cls)
 {
-//#ifndef JNI_VERSION_1_2
-    jclass jls = (*env)->FindClass(env, "java/lang/String");
+#if defined(DONT_USE_JNI_ONLOAD) || !defined(JNI_VERSION_1_2)
+    while (C_java_lang_String == 0) {
+	jclass jls = (*env)->FindClass(env, "java/lang/String");
 
-    C_java_lang_String = (*env)->NewGlobalRef(env, jls);
-//#endif
+	C_java_lang_String = (*env)->NewGlobalRef(env, jls);
+    }
+#endif
     F_SQLite_Database_handle =
 	(*env)->GetFieldID(env, cls, "handle", "J");
     F_SQLite_Database_error_code =
@@ -4349,7 +4602,7 @@
 			    "([BLjava/lang/String;)V");
 }
 
-#ifdef JNI_VERSION_1_2
+#if !defined(DONT_USE_JNI_ONLOAD) && defined(JNI_VERSION_1_2)
 JNIEXPORT jint JNICALL
 JNI_OnLoad(JavaVM *vm, void *reserved)
 {
@@ -4370,7 +4623,7 @@
     if (!cls) {
 	return JNI_ERR;
     }
-    C_java_lang_String = (*env)->NewWeakGlobalRef(env, cls);
+    C_java_lang_String = (*env)->NewGlobalRef(env, cls); // android-changed: bug
     return JNI_VERSION_1_2;
 }
 
@@ -4383,7 +4636,7 @@
 	return;
     }
     if (C_java_lang_String) {
-	(*env)->DeleteWeakGlobalRef(env, C_java_lang_String);
+	(*env)->DeleteGlobalRef(env, C_java_lang_String); // android-changed: bug
 	C_java_lang_String = 0;
     }
 }
diff --git a/sql/src/main/native/sqlite_jni.h b/sqlite-jdbc/src/main/native/sqlite_jni.h
similarity index 100%
rename from sql/src/main/native/sqlite_jni.h
rename to sqlite-jdbc/src/main/native/sqlite_jni.h
diff --git a/sql/src/main/native/sqlite_jni_defs.h b/sqlite-jdbc/src/main/native/sqlite_jni_defs.h
similarity index 97%
rename from sql/src/main/native/sqlite_jni_defs.h
rename to sqlite-jdbc/src/main/native/sqlite_jni_defs.h
index 91b2378..d21bf16 100644
--- a/sql/src/main/native/sqlite_jni_defs.h
+++ b/sqlite-jdbc/src/main/native/sqlite_jni_defs.h
@@ -36,4 +36,4 @@
 #define HAVE_SQLITE3_RESULT_ZEROBLOB 0
 #define HAVE_SQLITE3_INCRBLOBIO 0
 
-
+#define CANT_PASS_VALIST_AS_CHARPTR
diff --git a/suncompat/src/main/java/sun/misc/Unsafe.java b/suncompat/src/main/java/sun/misc/Unsafe.java
index 6ae572f..5c6aa01 100644
--- a/suncompat/src/main/java/sun/misc/Unsafe.java
+++ b/suncompat/src/main/java/sun/misc/Unsafe.java
@@ -17,11 +17,9 @@
 package sun.misc;
 
 import dalvik.system.VMStack;
-
-import org.apache.harmony.kernel.vm.LangAccess;
-
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import org.apache.harmony.kernel.vm.LangAccess;
 
 /**
  * The package name notwithstanding, this class is the quasi-standard
@@ -106,7 +104,6 @@
      * Helper for {@link #arrayBaseOffset}, which does all the work,
      * assuming the parameter is deemed valid.
      * 
-     * @param field non-null; the instance field
      * @return the offset to the field
      */
     private static native int arrayBaseOffset0(Class clazz);
@@ -130,7 +127,6 @@
      * Helper for {@link #arrayIndexScale}, which does all the work,
      * assuming the parameter is deemed valid.
      * 
-     * @param field non-null; the instance field
      * @return the offset to the field
      */
     private static native int arrayIndexScale0(Class clazz);
@@ -258,7 +254,15 @@
      * @param newValue the value to store 
      */
     public native void putInt(Object obj, long offset, int newValue);
-    
+
+    /**
+     * Lazy set an int field.
+     */
+    public void putOrderedInt(Object obj, long offset, int newValue) {
+        // TODO: this should be an intrinsic that executes a store fence followed by a write
+        putIntVolatile(obj, offset, newValue);
+    }
+
     /**
      * Gets a <code>long</code> field from the given object.
      * 
@@ -278,6 +282,14 @@
     public native void putLong(Object obj, long offset, long newValue);
 
     /**
+     * Lazy set a long field.
+     */
+    public void putOrderedLong(Object obj, long offset, long newValue) {
+        // TODO: this should be an intrinsic that executes a store fence followed by a write
+        putLongVolatile(obj, offset, newValue);
+    }
+
+    /**
      * Gets an <code>Object</code> field from the given object.
      * 
      * @param obj non-null; object containing the field
@@ -296,6 +308,14 @@
     public native void putObject(Object obj, long offset, Object newValue);
 
     /**
+     * Lazy set an object field.
+     */
+    public void putOrderedObject(Object obj, long offset, Object newValue) {
+        // TODO: this should be an intrinsic that executes a store fence followed by a write
+        putObjectVolatile(obj, offset, newValue);
+    }
+
+    /**
      * Parks the calling thread for the specified amount of time,
      * unless the "permit" for the thread is already available (due to
      * a previous call to {@link #unpark}. This method may also return
@@ -333,6 +353,4 @@
             throw new IllegalArgumentException("valid for Threads only");
         }
     }
-
-    // TODO(danfuzz): Stuff goes here.
 }
diff --git a/suncompat/src/test/java/sun/misc/AllTests.java b/suncompat/src/test/java/sun/misc/AllTests.java
index 8ea3bcf..f2c4277 100644
--- a/suncompat/src/test/java/sun/misc/AllTests.java
+++ b/suncompat/src/test/java/sun/misc/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Test for sun.misc");
+        TestSuite suite = new TestSuite("Test for sun.misc");
 
         // $JUnit-BEGIN$
 
diff --git a/suncompat/src/test/java/sun/misc/UnsafeTest.java b/suncompat/src/test/java/sun/misc/UnsafeTest.java
index 338055b..462d39d 100644
--- a/suncompat/src/test/java/sun/misc/UnsafeTest.java
+++ b/suncompat/src/test/java/sun/misc/UnsafeTest.java
@@ -16,23 +16,13 @@
 
 package sun.misc;
 
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
 import junit.framework.TestCase;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 
-@TestTargetClass(Unsafe.class)
 public class UnsafeTest extends TestCase {
 
-    @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "",
-            method = "getUnsafe",
-            args = {}
-    )
     public void test_getUnsafeForbidden() {
         try {
             Unsafe.getUnsafe();
@@ -45,12 +35,6 @@
      * Regression for 2053217. We used to look one level higher than necessary
      * on the stack.
      */
-    @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "",
-            method = "getUnsafe",
-            args = {}
-    )
     public void test_getUnsafeForbiddenWithSystemCaller() throws Exception {
         Callable<Object> callable = Executors.callable(new Runnable() {
             public void run() {
diff --git a/suncompat/src/test/java/tests/suncompat/AllTests.java b/suncompat/src/test/java/tests/suncompat/AllTests.java
index 0884517..e86889c 100644
--- a/suncompat/src/test/java/tests/suncompat/AllTests.java
+++ b/suncompat/src/test/java/tests/suncompat/AllTests.java
@@ -23,13 +23,8 @@
  * Test suite that includes all tests for the suncompat project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All suncompat test suites");
+        TestSuite suite = new TestSuite("All suncompat test suites");
         // $JUnit-BEGIN$
         suite.addTest(sun.misc.AllTests.suite());
         // $JUnit-END$
diff --git a/support/src/test/java/tests/support/Support_TestWebServer.java b/support/src/test/java/tests/support/Support_TestWebServer.java
index 7d20237..4d6b0d1 100644
--- a/support/src/test/java/tests/support/Support_TestWebServer.java
+++ b/support/src/test/java/tests/support/Support_TestWebServer.java
@@ -46,9 +46,6 @@
     /* timeout on client connections */
     int timeout = 0;
 
-    /* Default port for this server to listen on */
-    final static int DEFAULT_PORT = 8080;
-
     /* Default socket timeout value */
     final static int DEFAULT_TIMEOUT = 5000;
 
@@ -100,49 +97,51 @@
      * Initialize a new server with default port and timeout.
      * @param log Set true if you want trace output
      */
-    public void initServer(boolean log) throws Exception {
-        initServer(DEFAULT_PORT, DEFAULT_TIMEOUT, log);
+    public int initServer(boolean log) throws Exception {
+        return initServer(0, DEFAULT_TIMEOUT, log);
     }
 
     /**
      * Initialize a new server with default timeout.
-     * @param port Sets the server to listen on this port
+     * @param port Sets the server to listen on this port, or 0 to let the OS choose.
+     *             Hard-coding ports is evil, so always pass 0.
      * @param log Set true if you want trace output
      */
-    public void initServer(int port, boolean log) throws Exception {
-        initServer(port, DEFAULT_TIMEOUT, log);
+    public int initServer(int port, boolean log) throws Exception {
+        return initServer(port, DEFAULT_TIMEOUT, log);
     }
 
     /**
      * Initialize a new server with default timeout and disabled log.
-     * @param port Sets the server to listen on this port
+     * @param port Sets the server to listen on this port, or 0 to let the OS choose.
+     *             Hard-coding ports is evil, so always pass 0.
      * @param servePath the path to the dynamic web test data
      * @param contentType the type of the dynamic web test data
      */
-    public void initServer(int port, String servePath, String contentType)
+    public int initServer(int port, String servePath, String contentType)
             throws Exception {
         Support_TestWebData.initDynamicTestWebData(servePath, contentType);
-        initServer(port, DEFAULT_TIMEOUT, false);
+        return initServer(port, DEFAULT_TIMEOUT, false);
     }
 
     /**
      * Initialize a new server with default port and timeout.
-     * @param port Sets the server to listen on this port
+     * @param port Sets the server to listen on this port, or 0 to let the OS choose.
+     *             Hard-coding ports is evil, so always pass 0.
      * @param timeout Indicates the period of time to wait until a socket is
      *                closed
      * @param log Set true if you want trace output
      */
-    public void initServer(int port, int timeout, boolean log) throws Exception {
-        mPort = port;
+    public int initServer(int port, int timeout, boolean log) throws Exception {
         mTimeout = timeout;
         mLog = log;
         keepAlive = true;
-
         if (acceptT == null) {
             acceptT = new AcceptThread();
-            acceptT.init();
+            mPort = acceptT.init(port);
             acceptT.start();
         }
+        return mPort;
     }
 
     /**
@@ -226,6 +225,10 @@
         return pathToRequest;
     }
 
+    public int getNumAcceptedConnections() {
+        return acceptedConnections;
+    }
+
     /**
      * Cause the thread accepting connections on the server socket to close
      */
@@ -246,27 +249,15 @@
         ServerSocket ss = null;
         boolean running = false;
 
-        public void init() {
-            // Networking code doesn't support ServerSocket(port) yet
-            InetSocketAddress ia = new InetSocketAddress(mPort);
-            while (true) {
-                try {
-                    ss = new ServerSocket();
-                    // Socket timeout functionality is not available yet
-                    //ss.setSoTimeout(5000);
-                    ss.setReuseAddress(true);
-                    ss.bind(ia);
-                    break;
-                } catch (IOException e) {
-                    log("IOException in AcceptThread.init()");                    
-                    // wait and retry
-                    try {
-                        Thread.sleep(1000);
-                    } catch (InterruptedException e1) {
-                        e1.printStackTrace();
-                    }
-                }
-            }
+        /**
+         * @param port the port to use, or 0 to let the OS choose.
+         * Hard-coding ports is evil, so always pass 0!
+         */
+        public int init(int port) throws IOException {
+            ss = new ServerSocket(port);
+            ss.setSoTimeout(5000);
+            ss.setReuseAddress(true);
+            return ss.getLocalPort();
         }
 
         /**
@@ -274,23 +265,19 @@
          */
         public synchronized void run() {
             running = true;
-            try {
-                while (running) {
-                    // Log.d(LOGTAG, "TestWebServer run() calling accept()");
+            while (running) {
+                try {
                     Socket s = ss.accept();
                     acceptedConnections++;
                     if (acceptedConnections >= acceptLimit) {
                         running = false;
                     }
-
                     new Thread(new Worker(s), "additional worker").start();
+                } catch (SocketException e) {
+                    log(e.getMessage());
+                } catch (IOException e) {
+                    log(e.getMessage());
                 }
-            } catch (SocketException e) {
-                log("SocketException in AcceptThread: probably closed during accept");
-                running = false;
-            } catch (IOException e) {
-                log("IOException in AcceptThread");
-                running = false;
             }
             log("AcceptThread terminated" + this);
         }
diff --git a/text/src/main/java/java/text/AttributedCharacterIterator.java b/text/src/main/java/java/text/AttributedCharacterIterator.java
index 4f260ec..968a589 100644
--- a/text/src/main/java/java/text/AttributedCharacterIterator.java
+++ b/text/src/main/java/java/text/AttributedCharacterIterator.java
@@ -22,8 +22,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * Extends the
  * {@link CharacterIterator} interface, adding support for iterating over
@@ -48,14 +46,13 @@
          * The value objects are of the type {@code Annotation} which contain
          * {@code null}.
          */
-        public static final Attribute INPUT_METHOD_SEGMENT = new Attribute(
-                "input_method_segment"); //$NON-NLS-1$
+        public static final Attribute INPUT_METHOD_SEGMENT = new Attribute("input_method_segment");
 
         /**
          * The attribute describing the language of a character. The value
          * objects are of type {@code Locale} or a subtype of it.
          */
-        public static final Attribute LANGUAGE = new Attribute("language"); //$NON-NLS-1$
+        public static final Attribute LANGUAGE = new Attribute("language");
 
         /**
          * For languages that have different reading directions of text (like
@@ -63,7 +60,7 @@
          * used. The value objects are of type {@code Annotation} which
          * contain a {@code String}.
          */
-        public static final Attribute READING = new Attribute("reading"); //$NON-NLS-1$
+        public static final Attribute READING = new Attribute("reading");
 
         private String name;
 
@@ -123,11 +120,8 @@
          */
         protected Object readResolve() throws InvalidObjectException {
             if (this.getClass() != Attribute.class) {
-                // text.0C=cannot resolve subclasses
-                throw new InvalidObjectException(Messages.getString("text.0C")); //$NON-NLS-1$
+                throw new InvalidObjectException("cannot resolve subclasses");
             }
-            // BEGIN android-changed
-            // call getName() only once
             String name = this.getName();
             if (name.equals(INPUT_METHOD_SEGMENT.getName())) {
                 return INPUT_METHOD_SEGMENT;
@@ -138,9 +132,7 @@
             if (name.equals(READING.getName())) {
                 return READING;
             }
-            // END android-changed
-            // text.02=Unknown attribute
-            throw new InvalidObjectException(Messages.getString("text.02")); //$NON-NLS-1$
+            throw new InvalidObjectException("Unknown attribute");
         }
 
         /**
diff --git a/text/src/main/java/java/text/AttributedString.java b/text/src/main/java/java/text/AttributedString.java
index fe7aa0c..7295198 100644
--- a/text/src/main/java/java/text/AttributedString.java
+++ b/text/src/main/java/java/text/AttributedString.java
@@ -28,8 +28,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * Holds a string with attributes describing the characters of
  * this string.
@@ -389,8 +387,7 @@
      */
     public AttributedString(AttributedCharacterIterator iterator) {
         if (iterator.getBeginIndex() > iterator.getEndIndex()) {
-            // text.0A=Invalid substring range
-            throw new IllegalArgumentException(Messages.getString("text.0A")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Invalid substring range");
         }
         StringBuilder buffer = new StringBuilder();
         for (int i = iterator.getBeginIndex(); i < iterator.getEndIndex(); i++) {
@@ -554,8 +551,7 @@
             throw new NullPointerException();
         }
         if (value.length() == 0 && !attributes.isEmpty()) {
-            // text.0B=Cannot add attributes to empty string
-            throw new IllegalArgumentException(Messages.getString("text.0B")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Cannot add attributes to empty string");
         }
         text = value;
         attributeMap = new HashMap<Attribute, List<Range>>(
diff --git a/text/src/main/java/java/text/Bidi.java b/text/src/main/java/java/text/Bidi.java
index 7939dea..92ca7ac 100644
--- a/text/src/main/java/java/text/Bidi.java
+++ b/text/src/main/java/java/text/Bidi.java
@@ -15,22 +15,14 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// changed from icu.text.Bidi to BidiWrapper
-// END android-note
-
 package java.text;
 
-// BEGIN android-added
 import java.awt.font.NumericShaper;
 import java.awt.font.TextAttribute;
 import java.util.Arrays;
 import java.util.LinkedList;
-
 import org.apache.harmony.text.BidiRun;
 import org.apache.harmony.text.BidiWrapper;
-// END android-added
-import org.apache.harmony.text.internal.nls.Messages;
 
 /**
  * Provides the Unicode Bidirectional Algorithm. The algorithm is
@@ -110,16 +102,14 @@
      * @param paragraph
      *            the String containing the paragraph text to perform the
      *            algorithm.
-     * @throws IllegalArgumentException
-     *             if {@code paragraph} is {@code null}.
+     * @throws IllegalArgumentException if {@code paragraph == null}
      * @see java.awt.font.TextAttribute#BIDI_EMBEDDING
      * @see java.awt.font.TextAttribute#NUMERIC_SHAPING
      * @see java.awt.font.TextAttribute#RUN_DIRECTION
      */
     public Bidi(AttributedCharacterIterator paragraph) {
         if (paragraph == null) {
-            // text.14=paragraph is null
-            throw new IllegalArgumentException(Messages.getString("text.14")); //$NON-NLS-1$
+            throw new IllegalArgumentException("paragraph is null");
         }
 
         // BEGIN android-added
@@ -231,19 +221,13 @@
         }
 
         if (textStart < 0) {
-            // text.0D=Negative textStart value {0}
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.0D", textStart)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Negative textStart value " + textStart);
         }
         if (embStart < 0) {
-            // text.10=Negative embStart value {0}
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.10", embStart)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Negative embStart value " + embStart);
         }
         if (paragraphLength < 0) {
-            // text.11=Negative paragraph length {0}
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.11", paragraphLength)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Negative paragraph length " + paragraphLength);
         }
         
         // BEGIN android-changed
@@ -395,17 +379,11 @@
      *             than the length of this object's paragraph text.
      */
     public Bidi createLineBidi(int lineStart, int lineLimit) {
-        // BEGIN android-removed
-        // int length = icuBidi.getLength();
-        // END android-removed
-        if (lineStart < 0 || lineLimit < 0 || lineLimit > length
-                || lineStart > lineLimit) {
-            // text.12=Invalid ranges (start={0}, limit={1}, length={2})
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.12", new Object[] { lineStart, lineLimit, length })); //$NON-NLS-1$
+        if (lineStart < 0 || lineLimit < 0 || lineLimit > length || lineStart > lineLimit) {
+            throw new IllegalArgumentException("Invalid ranges (start=" + lineStart + ", " +
+                    "limit=" + lineLimit + ", length=" + length + ")");
         }
-        
-        // BEGIN android-changed
+
         char[] text = new char[this.length];
         Arrays.fill(text, 'a');
         byte[] embeddings = new byte[this.length];
@@ -413,17 +391,31 @@
             embeddings[i] = (byte) -this.offsetLevel[i];
         }
 
-        int dir = this.baseIsLeftToRight() ? Bidi.DIRECTION_LEFT_TO_RIGHT
+        int dir = this.baseIsLeftToRight()
+                ? Bidi.DIRECTION_LEFT_TO_RIGHT
                 : Bidi.DIRECTION_RIGHT_TO_LEFT;
+        long parent = 0;
+        try {
+            parent = createUBiDi(text, 0, embeddings, 0, this.length, dir);
+            if (lineStart == lineLimit) {
+                return createEmptyLineBidi(parent);
+            }
+            return new Bidi(BidiWrapper.ubidi_setLine(parent, lineStart, lineLimit));
+        } finally {
+            if (parent != 0) {
+                BidiWrapper.ubidi_close(parent);
+            }
+        }
+    }
 
-        long parent = createUBiDi(text, 0, embeddings, 0, this.length, dir);
-
-        long line = BidiWrapper.ubidi_setLine(parent, lineStart, lineLimit);
-        Bidi result = new Bidi(line);
-        BidiWrapper.ubidi_close(line);
-        BidiWrapper.ubidi_close(parent);
+    private Bidi createEmptyLineBidi(long parent) {
+        // ICU4C doesn't allow this case, but the RI does.
+        Bidi result = new Bidi(parent);
+        result.length = 0;
+        result.offsetLevel = null;
+        result.runs = null;
+        result.unidirectional = true;
         return result;
-        // END android-changed
     }
 
     /**
@@ -580,11 +572,9 @@
         if (count < 0 || levelStart < 0 || objectStart < 0
                 || count > levels.length - levelStart
                 || count > objects.length - objectStart) {
-            // text.13=Invalid ranges (levels={0}, levelStart={1}, objects={2},
-            // objectStart={3}, count={4})
-            throw new IllegalArgumentException(Messages.getString("text.13", //$NON-NLS-1$
-                    new Object[] { levels.length, levelStart, objects.length,
-                            objectStart, count }));
+            throw new IllegalArgumentException("Invalid ranges (levels=" + levels.length +
+                    ", levelStart=" + levelStart + ", objects=" + objects.length +
+                    ", objectStart=" + objectStart + ", count=" + count + ")");
         }
         
         // BEGIN android-changed
@@ -641,8 +631,8 @@
     public String toString() {
         // BEGIN android-changed
         return super.toString()
-                + "[direction: " + direction + " baselevel: " + baseLevel //$NON-NLS-1$ //$NON-NLS-2$
-                + " length: " + length + " runs: " + (unidirectional ? "null" : runs.toString()) + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                + "[direction: " + direction + " baseLevel: " + baseLevel
+                + " length: " + length + " runs: " + Arrays.toString(runs) + "]";
         // END android-changed
     }
 }
diff --git a/text/src/main/java/java/text/BreakIterator.java b/text/src/main/java/java/text/BreakIterator.java
index 78870f0..a858b46 100644
--- a/text/src/main/java/java/text/BreakIterator.java
+++ b/text/src/main/java/java/text/BreakIterator.java
@@ -15,16 +15,12 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.text.NativeBreakIterator;
+import com.ibm.icu4jni.util.ICU;
 import java.util.Locale;
 
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * Locates boundaries in text. This class defines a protocol for objects that
  * break up a piece of natural-language text according to a set of criteria.
@@ -234,17 +230,11 @@
      */
     public static final int DONE = -1;
 
-    private static final int LONG_LENGTH = 8;
-
-    private static final int INT_LENGTH = 4;
-
-    private static final int SHORT_LENGTH = 2;
-
     // the wrapped ICU implementation
-    com.ibm.icu4jni.text.BreakIterator wrapped;
+    NativeBreakIterator wrapped;
 
     /**
-     * Default constructor, just for invocation by a subclass.
+     * Default constructor, for use by subclasses.
      */
     protected BreakIterator() {
         super();
@@ -253,28 +243,26 @@
     /*
      * wrapping constructor
      */
-    BreakIterator(com.ibm.icu4jni.text.BreakIterator iterator) {
+    BreakIterator(NativeBreakIterator iterator) {
         wrapped = iterator;
     }
 
     /**
-     * Returns all supported locales in an array.
-     * 
-     * @return all supported locales.
+     * Returns an array of locales for which custom {@code BreakIterator} instances
+     * are available.
      */
     public static Locale[] getAvailableLocales() {
-        return com.ibm.icu4jni.text.BreakIterator.getAvailableLocales();
+        return ICU.getAvailableBreakIteratorLocales();
     }
 
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
-     * characters using the default locale.
-     * 
+     * characters using the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @return a new instance of {@code BreakIterator} using the default locale.
      */
     public static BreakIterator getCharacterInstance() {
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getCharacterInstance());
+        return getCharacterInstance(Locale.getDefault());
     }
 
     /**
@@ -286,23 +274,17 @@
      * @return a new instance of {@code BreakIterator} using the given locale.
      */
     public static BreakIterator getCharacterInstance(Locale where) {
-        if (where == null) {
-            throw new NullPointerException();
-        }
-
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getCharacterInstance(where));
+        return new RuleBasedBreakIterator(NativeBreakIterator.getCharacterInstance(where));
     }
 
     /**
      * Returns a new instance of {{@code BreakIterator} to iterate over
-     * line breaks using the default locale.
-     * 
+     * line breaks using the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @return a new instance of {@code BreakIterator} using the default locale.
      */
     public static BreakIterator getLineInstance() {
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getLineInstance());
+        return getLineInstance(Locale.getDefault());
     }
 
     /**
@@ -315,23 +297,17 @@
      * @throws NullPointerException if {@code where} is {@code null}.
      */
     public static BreakIterator getLineInstance(Locale where) {
-        if (where == null) {
-            throw new NullPointerException();
-        }
-
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getLineInstance(where));
+        return new RuleBasedBreakIterator(NativeBreakIterator.getLineInstance(where));
     }
 
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
      * sentence-breaks using the default locale.
-     * 
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @return a new instance of {@code BreakIterator} using the default locale.
      */
     public static BreakIterator getSentenceInstance() {
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getSentenceInstance());
+        return getSentenceInstance(Locale.getDefault());
     }
 
     /**
@@ -344,23 +320,17 @@
      * @throws NullPointerException if {@code where} is {@code null}.
      */
     public static BreakIterator getSentenceInstance(Locale where) {
-        if (where == null) {
-            throw new NullPointerException();
-        }
-
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getSentenceInstance(where));
+        return new RuleBasedBreakIterator(NativeBreakIterator.getSentenceInstance(where));
     }
 
     /**
      * Returns a new instance of {@code BreakIterator} to iterate over
      * word-breaks using the default locale.
-     * 
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @return a new instance of {@code BreakIterator} using the default locale.
      */
     public static BreakIterator getWordInstance() {
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getWordInstance());
+        return getWordInstance(Locale.getDefault());
     }
 
     /**
@@ -373,12 +343,7 @@
      * @throws NullPointerException if {@code where} is {@code null}.
      */
     public static BreakIterator getWordInstance(Locale where) {
-        if (where == null) {
-            throw new NullPointerException();
-        }
-
-        return new RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator
-                .getWordInstance(where));
+        return new RuleBasedBreakIterator(NativeBreakIterator.getWordInstance(where));
     }
 
     /**
@@ -521,94 +486,10 @@
     public Object clone() {
         try {
             BreakIterator cloned = (BreakIterator) super.clone();
-            cloned.wrapped = (com.ibm.icu4jni.text.BreakIterator) wrapped.clone();
+            cloned.wrapped = (NativeBreakIterator) wrapped.clone();
             return cloned;
         } catch (CloneNotSupportedException e) {
             throw new AssertionError(e); // android-changed
         }
     }
-
-    /**
-     * Gets a long value from the given byte array, starting from the given
-     * offset.
-     * 
-     * @param buf
-     *            the bytes to be converted.
-     * @param offset
-     *            the start position of the conversion.
-     * @return the converted long value.
-     * @throws NullPointerException
-     *             if {@code buf} is {@code null}.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code offset < 0} or {@code offset + LONG_LENGTH} is
-     *             greater than the length of {@code buf}.
-     */
-    protected static long getLong(byte[] buf, int offset) {
-        // Force a buf null check first!
-        if (buf.length - offset < LONG_LENGTH || offset < 0) {
-            // text.1E=Offset out of bounds \: {0}
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("text.1E", offset)); //$NON-NLS-1$
-        }
-        long result = 0;
-        for (int i = offset; i < offset + LONG_LENGTH; i++) {
-            result = (result << 8) | (buf[i] & 0xff);
-        }
-        return result;
-    }
-
-    /**
-     * Gets an int value from the given byte array, starting from the given
-     * offset.
-     * 
-     * @param buf
-     *            the bytes to be converted.
-     * @param offset
-     *            the start position of the conversion.
-     * @return the converted int value.
-     * @throws NullPointerException
-     *             if {@code buf} is {@code null}.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code offset < 0} or {@code offset + INT_LENGTH} is
-     *             greater than the length of {@code buf}.
-     */
-    protected static int getInt(byte[] buf, int offset) {
-        // Force buf null check first!
-        if (buf.length - INT_LENGTH < offset || offset < 0) {
-            // text.1E=Offset out of bounds \: {0}
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("text.1E", offset)); //$NON-NLS-1$
-        }
-        int result = 0;
-        for (int i = offset; i < offset + INT_LENGTH; i++) {
-            result = (result << 8) | (buf[i] & 0xff);
-        }
-        return result;
-    }
-
-    /**
-     * Gets a short value from the given byte array, starting from the given
-     * offset.
-     * 
-     * @param buf
-     *            the bytes to be converted.
-     * @param offset
-     *            the start position of the conversion.
-     * @return the converted short value.
-     * @throws NullPointerException
-     *             if {@code buf} is {@code null}.
-     * @throws ArrayIndexOutOfBoundsException
-     *             if {@code offset < 0} or {@code offset + SHORT_LENGTH} is
-     *             greater than the length of {@code buf}.
-     */
-    protected static short getShort(byte[] buf, int offset) {
-        // Force buf null check first!
-        if (buf.length - SHORT_LENGTH < offset || offset < 0) {
-            // text.1E=Offset out of bounds \: {0}
-            throw new ArrayIndexOutOfBoundsException(Messages.getString("text.1E", offset)); //$NON-NLS-1$
-        }
-        short result = 0;
-        for (int i = offset; i < offset + SHORT_LENGTH; i++) {
-            result = (short) ((result << 8) | (buf[i] & 0xff));
-        }
-        return result;
-    }
 }
diff --git a/text/src/main/java/java/text/CollationElementIterator.java b/text/src/main/java/java/text/CollationElementIterator.java
index fb562d8..863821c 100644
--- a/text/src/main/java/java/text/CollationElementIterator.java
+++ b/text/src/main/java/java/text/CollationElementIterator.java
@@ -17,10 +17,6 @@
 
 package java.text;
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 /**
  * Created by a {@code RuleBasedCollator} to iterate through a string. The
  * result of each iteration is a 32-bit collation element that defines the
diff --git a/text/src/main/java/java/text/CollationKey.java b/text/src/main/java/java/text/CollationKey.java
index a994fe2..946f462 100644
--- a/text/src/main/java/java/text/CollationKey.java
+++ b/text/src/main/java/java/text/CollationKey.java
@@ -15,11 +15,8 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
+
 /**
  * Represents a string under the rules of a specific {@code Collator} object.
  * Comparing two {@code CollationKey} instances returns the relative order of
@@ -81,51 +78,21 @@
  * @see Collator
  * @see RuleBasedCollator
  */
-public final class CollationKey implements Comparable<CollationKey> {
+public abstract class CollationKey implements Comparable<CollationKey> {
+    private final String source;
 
-    private String source;
-
-    private com.ibm.icu4jni.text.CollationKey icuKey;
-
-    CollationKey(String source, com.ibm.icu4jni.text.CollationKey key) {
+    protected CollationKey(String source) {
         this.source = source;
-        this.icuKey = key;
     }
 
     /**
-     * Compares this object to the specified collation key object to determine
-     * their relative order.
+     * Compares this collation key to the given collation key.
      * 
-     * @param value
-     *            the collation key object to compare this object to.
-     * @return a negative value if this {@code CollationKey} is less than the
-     *         specified {@code CollationKey}, 0 if they are equal and a
-     *         positive value if this {@code CollationKey} is greater.
+     * @param value the other collation key.
+     * @return a negative value if this key is less than {@code value},
+     *         0 if they are equal, and a positive value if this key is greater.
      */
-    public int compareTo(CollationKey value) {
-        return icuKey.compareTo(value.icuKey);
-    }
-
-    /**
-     * Compares the specified object to this {@code CollationKey} and indicates
-     * if they are equal. The object must be an instance of {@code CollationKey}
-     * and have the same source string and collation key. Both instances of
-     * {@code CollationKey} must have been created by the same {@code Collator}.
-     * 
-     * @param object
-     *            the object to compare to this object.
-     * @return {@code true} if {@code object} is equal to this collation key;
-     *         {@code false} otherwise.
-     * @see #hashCode
-     */
-    @Override
-    public boolean equals(Object object) {
-        if (!(object instanceof CollationKey)) {
-            return false;
-        }
-        CollationKey collationKey = (CollationKey) object;
-        return icuKey.equals(collationKey.icuKey);
-    }
+    public abstract int compareTo(CollationKey value);
 
     /**
      * Returns the string from which this collation key was created.
@@ -133,28 +100,13 @@
      * @return the source string of this collation key.
      */
     public String getSourceString() {
-        return this.source;
+        return source;
     }
 
     /**
-     * Returns an integer hash code for the receiver. Objects which are equal
-     * return the same value for this method.
-     * 
-     * @return the receiver's hash.
-     * 
-     * @see #equals
-     */
-    @Override
-    public int hashCode() {
-        return icuKey.hashCode();
-    }
-
-    /**
-     * Returns the collation key as a byte array.
+     * Returns this collation key as a byte array.
      * 
      * @return an array of bytes.
      */
-    public byte[] toByteArray() {
-        return icuKey.toByteArray();
-    }
+    public abstract byte[] toByteArray();
 }
diff --git a/text/src/main/java/java/text/Collator.java b/text/src/main/java/java/text/Collator.java
index e954b8b..dba931c 100644
--- a/text/src/main/java/java/text/Collator.java
+++ b/text/src/main/java/java/text/Collator.java
@@ -15,12 +15,9 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.util.ICU;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Comparator;
@@ -114,13 +111,6 @@
  * @see CollationKey
  */
 public abstract class Collator implements Comparator<Object>, Cloneable {
-
-    static final int EQUAL = 0;
-
-    static final int GREATER = 1;
-
-    static final int LESS = -1;
-
     /**
      * Constant used to specify the decomposition rule.
      */
@@ -157,29 +147,6 @@
      */
     public static final int IDENTICAL = 3;
 
-    private static int CACHE_SIZE;
-
-    static {
-        // CACHE_SIZE includes key and value, so needs to be double
-        String cacheSize = AccessController
-                .doPrivileged(new PrivilegedAction<String>() {
-                    public String run() {
-                        return System.getProperty("collator.cache"); //$NON-NLS-1$
-                    }
-                });
-        if (cacheSize != null) {
-            try {
-                CACHE_SIZE = Integer.parseInt(cacheSize);
-            } catch (NumberFormatException e) {
-                CACHE_SIZE = 6;
-            }
-        } else {
-            CACHE_SIZE = 6;
-        }
-    }
-
-    private static Vector<Collator> cache = new Vector<Collator>(CACHE_SIZE);
-
     // Wrapper class of ICU4JNI Collator
     com.ibm.icu4jni.text.Collator icuColl;
 
@@ -283,13 +250,11 @@
     }
 
     /**
-     * Gets the list of installed {@link java.util.Locale} objects which support
-     * {@code Collator}.
-     * 
-     * @return an array of {@code Locale}.
+     * Returns an array of locales for which custom {@code Collator} instances
+     * are available.
      */
     public static Locale[] getAvailableLocales() {
-        return com.ibm.icu4jni.text.Collator.getAvailableLocales();
+        return ICU.getAvailableCollatorLocales();
     }
 
     /**
@@ -314,33 +279,21 @@
     }
 
     /**
-     * Returns a {@code Collator} instance which is appropriate for the default
+     * Returns a {@code Collator} instance which is appropriate for the user's default
      * {@code Locale}.
-     * 
-     * @return the collator for the default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
     public static Collator getInstance() {
         return getInstance(Locale.getDefault());
     }
 
     /**
-     * Returns a {@code Collator} instance which is appropriate for the
-     * specified {@code Locale}.
-     * 
-     * @param locale
-     *            the locale.
-     * @return the collator for {@code locale}.
+     * Returns a {@code Collator} instance which is appropriate for {@code locale}.
      */
     public static Collator getInstance(Locale locale) {
-        String key = locale.toString();
-        for (int i = cache.size() - 1; i >= 0; i -= 2) {
-            if (cache.elementAt(i).equals(key)) {
-                return (Collator) (cache.elementAt(i - 1)).clone();
-            }
-        }
-
-        return new RuleBasedCollator(com.ibm.icu4jni.text.Collator
-                .getInstance(locale));
+        // BEGIN android-changed: removed non-functional cache.
+        return new RuleBasedCollator(com.ibm.icu4jni.text.Collator.getInstance(locale));
+        // END android-changed
     }
 
     /**
@@ -353,14 +306,6 @@
         return strength_ICU_Java(this.icuColl.getStrength());
     }
 
-    /**
-     * Returns an integer hash code for this collator.
-     * 
-     * @return this collator's hash code.
-     * 
-     * @see #equals(Object)
-     * @see #equals(String, String)
-     */
     @Override
     public abstract int hashCode();
 
@@ -393,16 +338,13 @@
     }
 
     private int decompositionMode_Java_ICU(int mode) {
-        int icuDecomp = mode;
         switch (mode) {
-            case Collator.CANONICAL_DECOMPOSITION:
-                icuDecomp = com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION;
-                break;
-            case Collator.NO_DECOMPOSITION:
-                icuDecomp = com.ibm.icu4jni.text.Collator.NO_DECOMPOSITION;
-                break;
+        case Collator.CANONICAL_DECOMPOSITION:
+            return com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION;
+        case Collator.NO_DECOMPOSITION:
+            return com.ibm.icu4jni.text.Collator.NO_DECOMPOSITION;
         }
-        return icuDecomp;
+        throw new IllegalArgumentException();
     }
 
     private int decompositionMode_ICU_Java(int mode) {
@@ -419,23 +361,17 @@
     }
 
     private int strength_Java_ICU(int value) {
-        int icuValue = value;
         switch (value) {
-            case Collator.PRIMARY:
-                icuValue = com.ibm.icu4jni.text.Collator.PRIMARY;
-                break;
-            case Collator.SECONDARY:
-                icuValue = com.ibm.icu4jni.text.Collator.SECONDARY;
-                break;
-            case Collator.TERTIARY:
-                icuValue = com.ibm.icu4jni.text.Collator.TERTIARY;
-                break;
-            case Collator.IDENTICAL:
-                icuValue = com.ibm.icu4jni.text.Collator.IDENTICAL;
-                break;
+        case Collator.PRIMARY:
+            return com.ibm.icu4jni.text.Collator.PRIMARY;
+        case Collator.SECONDARY:
+            return com.ibm.icu4jni.text.Collator.SECONDARY;
+        case Collator.TERTIARY:
+            return com.ibm.icu4jni.text.Collator.TERTIARY;
+        case Collator.IDENTICAL:
+            return com.ibm.icu4jni.text.Collator.IDENTICAL;
         }
-        return icuValue;
-
+        throw new IllegalArgumentException();
     }
 
     private int strength_ICU_Java(int value) {
diff --git a/text/src/main/java/java/text/DateFormat.java b/text/src/main/java/java/text/DateFormat.java
index bf7ebbe..0b44aad 100644
--- a/text/src/main/java/java/text/DateFormat.java
+++ b/text/src/main/java/java/text/DateFormat.java
@@ -15,12 +15,10 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// changed from ICU to resource bundles
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.util.LocaleData;
+import com.ibm.icu4jni.util.ICU;
 import java.io.InvalidObjectException;
 import java.util.Calendar;
 import java.util.Date;
@@ -28,9 +26,6 @@
 import java.util.Locale;
 import java.util.TimeZone;
 
-import com.ibm.icu4jni.util.LocaleData;
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * An abstract class for date/time formatting subclasses which formats and
  * parses dates or time in a language-independent manner. The date/time
@@ -407,12 +402,11 @@
             FieldPosition field);
 
     /**
-     * Gets the list of installed locales which support {@code DateFormat}.
-     * 
-     * @return an array of locales.
+     * Returns an array of locales for which custom {@code DateFormat} instances
+     * are available.
      */
     public static Locale[] getAvailableLocales() {
-        return Locale.getAvailableLocales();
+        return ICU.getAvailableDateFormatLocales();
     }
 
     /**
@@ -436,8 +430,8 @@
 
     /**
      * Returns a {@code DateFormat} instance for formatting and parsing dates in
-     * the specified style for the default locale.
-     * 
+     * the specified style for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @param style
      *            one of SHORT, MEDIUM, LONG, FULL, or DEFAULT.
      * @return the {@code DateFormat} instance for {@code style} and the default
@@ -467,10 +461,7 @@
      */
     public final static DateFormat getDateInstance(int style, Locale locale) {
         checkDateStyle(style);
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        return new SimpleDateFormat(localeData.getDateFormat(style), locale);
-        // END android-changed
+        return new SimpleDateFormat(LocaleData.get(locale).getDateFormat(style), locale);
     }
 
     /**
@@ -485,8 +476,8 @@
 
     /**
      * Returns a {@code DateFormat} instance for formatting and parsing of both
-     * dates and time values in the manner appropriate for the default locale.
-     * 
+     * dates and time values in the manner appropriate for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @param dateStyle
      *            one of SHORT, MEDIUM, LONG, FULL, or DEFAULT.
      * @param timeStyle
@@ -497,8 +488,7 @@
      *             if {@code dateStyle} or {@code timeStyle} is not one of
      *             SHORT, MEDIUM, LONG, FULL, or DEFAULT.
      */
-    public final static DateFormat getDateTimeInstance(int dateStyle,
-            int timeStyle) {
+    public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
         checkTimeStyle(timeStyle);
         checkDateStyle(dateStyle);
         return getDateTimeInstance(dateStyle, timeStyle, Locale.getDefault());
@@ -520,15 +510,12 @@
      *             if {@code dateStyle} or {@code timeStyle} is not one of
      *             SHORT, MEDIUM, LONG, FULL, or DEFAULT.
      */
-    public final static DateFormat getDateTimeInstance(int dateStyle,
-            int timeStyle, Locale locale) {
+    public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {
         checkTimeStyle(timeStyle);
         checkDateStyle(dateStyle);
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
+        LocaleData localeData = LocaleData.get(locale);
         String pattern = localeData.getDateFormat(dateStyle) + " " + localeData.getTimeFormat(timeStyle);
         return new SimpleDateFormat(pattern, locale);
-        // END android-changed
     }
 
     /**
@@ -563,8 +550,8 @@
 
     /**
      * Returns a {@code DateFormat} instance for formatting and parsing time
-     * values in the specified style for the default locale.
-     * 
+     * values in the specified style for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @param style
      *            one of SHORT, MEDIUM, LONG, FULL, or DEFAULT.
      * @return the {@code DateFormat} instance for {@code style} and the default
@@ -594,10 +581,7 @@
      */
     public final static DateFormat getTimeInstance(int style, Locale locale) {
         checkTimeStyle(style);
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        return new SimpleDateFormat(localeData.getTimeFormat(style), locale);
-        // END android-changed
+        return new SimpleDateFormat(LocaleData.get(locale).getTimeFormat(style), locale);
     }
 
     /**
@@ -641,9 +625,7 @@
         ParsePosition position = new ParsePosition(0);
         Date date = parse(string, position);
         if (position.getIndex() == 0) {
-            // text.19=Unparseable date: {0}
-            throw new ParseException(
-                    Messages.getString("text.19", string), position.getErrorIndex()); //$NON-NLS-1$
+            throw new ParseException("Unparseable date " + string, position.getErrorIndex());
         }
         return date;
     }
@@ -762,100 +744,95 @@
         /**
          * Marks the era part of a date.
          */
-        public final static Field ERA = new Field("era", Calendar.ERA); //$NON-NLS-1$
+        public final static Field ERA = new Field("era", Calendar.ERA);
 
         /**
          * Marks the year part of a date.
          */
-        public final static Field YEAR = new Field("year", Calendar.YEAR); //$NON-NLS-1$
+        public final static Field YEAR = new Field("year", Calendar.YEAR);
 
         /**
          * Marks the month part of a date.
          */
-        public final static Field MONTH = new Field("month", Calendar.MONTH); //$NON-NLS-1$
+        public final static Field MONTH = new Field("month", Calendar.MONTH);
 
         /**
          * Marks the hour of the day part of a date (0-11).
          */
-        public final static Field HOUR_OF_DAY0 = new Field("hour of day", //$NON-NLS-1$
-                Calendar.HOUR_OF_DAY);
+        public final static Field HOUR_OF_DAY0 = new Field("hour of day", Calendar.HOUR_OF_DAY);
 
         /**
          * Marks the hour of the day part of a date (1-12).
          */
-        public final static Field HOUR_OF_DAY1 = new Field("hour of day 1", -1); //$NON-NLS-1$
+        public final static Field HOUR_OF_DAY1 = new Field("hour of day 1", -1);
 
         /**
          * Marks the minute part of a time.
          */
-        public final static Field MINUTE = new Field("minute", Calendar.MINUTE); //$NON-NLS-1$
+        public final static Field MINUTE = new Field("minute", Calendar.MINUTE);
 
         /**
          * Marks the second part of a time.
          */
-        public final static Field SECOND = new Field("second", Calendar.SECOND); //$NON-NLS-1$
+        public final static Field SECOND = new Field("second", Calendar.SECOND);
 
         /**
          * Marks the millisecond part of a time.
          */
-        public final static Field MILLISECOND = new Field("millisecond", //$NON-NLS-1$
-                Calendar.MILLISECOND);
+        public final static Field MILLISECOND = new Field("millisecond", Calendar.MILLISECOND);
 
         /**
          * Marks the day of the week part of a date.
          */
-        public final static Field DAY_OF_WEEK = new Field("day of week", //$NON-NLS-1$
-                Calendar.DAY_OF_WEEK);
+        public final static Field DAY_OF_WEEK = new Field("day of week", Calendar.DAY_OF_WEEK);
 
         /**
          * Marks the day of the month part of a date.
          */
-        public final static Field DAY_OF_MONTH = new Field("day of month", //$NON-NLS-1$
-                Calendar.DAY_OF_MONTH);
+        public final static Field DAY_OF_MONTH = new Field("day of month", Calendar.DAY_OF_MONTH);
 
         /**
          * Marks the day of the year part of a date.
          */
-        public final static Field DAY_OF_YEAR = new Field("day of year", //$NON-NLS-1$
-                Calendar.DAY_OF_YEAR);
+        public final static Field DAY_OF_YEAR = new Field("day of year", Calendar.DAY_OF_YEAR);
 
         /**
          * Marks the day of the week in the month part of a date.
          */
-        public final static Field DAY_OF_WEEK_IN_MONTH = new Field(
-                "day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH); //$NON-NLS-1$
+        public final static Field DAY_OF_WEEK_IN_MONTH = new Field("day of week in month",
+                Calendar.DAY_OF_WEEK_IN_MONTH);
 
         /**
          * Marks the week of the year part of a date.
          */
-        public final static Field WEEK_OF_YEAR = new Field("week of year", //$NON-NLS-1$
+        public final static Field WEEK_OF_YEAR = new Field("week of year",
                 Calendar.WEEK_OF_YEAR);
 
         /**
          * Marks the week of the month part of a date.
          */
-        public final static Field WEEK_OF_MONTH = new Field("week of month", //$NON-NLS-1$
+        public final static Field WEEK_OF_MONTH = new Field("week of month",
                 Calendar.WEEK_OF_MONTH);
 
         /**
          * Marks the time indicator part of a date.
          */
-        public final static Field AM_PM = new Field("am pm", Calendar.AM_PM); //$NON-NLS-1$
+        public final static Field AM_PM = new Field("am pm", Calendar.AM_PM);
 
         /**
          * Marks the hour part of a date (0-11).
          */
-        public final static Field HOUR0 = new Field("hour", Calendar.HOUR); //$NON-NLS-1$
+        public final static Field HOUR0 = new Field("hour", Calendar.HOUR);
 
         /**
          * Marks the hour part of a date (1-12).
          */
-        public final static Field HOUR1 = new Field("hour 1", -1); //$NON-NLS-1$
+        public final static Field HOUR1 = new Field("hour 1", -1);
 
         /**
          * Marks the time zone part of a date.
          */
-        public final static Field TIME_ZONE = new Field("time zone", -1); //$NON-NLS-1$
+        public final static Field TIME_ZONE = new Field("time zone", -1);
 
         /**
          * The calendar field that this field represents.
@@ -874,9 +851,8 @@
         protected Field(String fieldName, int calendarField) {
             super(fieldName);
             this.calendarField = calendarField;
-            if (calendarField != -1
-                    && table.get(new Integer(calendarField)) == null) {
-                table.put(new Integer(calendarField), this);
+            if (calendarField != -1 && table.get(Integer.valueOf(calendarField)) == null) {
+                table.put(Integer.valueOf(calendarField), this);
             }
         }
 
@@ -906,7 +882,7 @@
                 throw new IllegalArgumentException();
             }
 
-            return table.get(new Integer(calendarField));
+            return table.get(Integer.valueOf(calendarField));
         }
 
         /**
@@ -919,11 +895,9 @@
          */
         @Override
         protected Object readResolve() throws InvalidObjectException {
-        	if (this.getClass() != Field.class) {
-                // text.0C=cannot resolve subclasses
-                throw new InvalidObjectException(Messages.getString("text.0C")); //$NON-NLS-1$
+            if (this.getClass() != Field.class) {
+                throw new InvalidObjectException("cannot resolve subclasses");
             }
-        	
             if (calendarField != -1) {
                 try {
                     Field result = ofCalendarField(calendarField);
@@ -932,9 +906,7 @@
                         return result;
                     }
                 } catch (IllegalArgumentException e) {
-                    // text.02=Unknown attribute
-                    throw new InvalidObjectException(Messages
-                            .getString("text.02")); //$NON-NLS-1$
+                    throw new InvalidObjectException("Unknown attribute");
                 }
             } else {
                 if (this.equals(TIME_ZONE)) {
@@ -947,26 +919,21 @@
                     return HOUR_OF_DAY1;
                 }
             }
-            // text.02=Unknown attribute
-            throw new InvalidObjectException(Messages.getString("text.02")); //$NON-NLS-1$
+            throw new InvalidObjectException("Unknown attribute");
         }
     }
 
     private static void checkDateStyle(int style) {
         if (!(style == SHORT || style == MEDIUM || style == LONG
                 || style == FULL || style == DEFAULT)) {
-            // text.0E=Illegal date style: {0}
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.0E", style)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Illegal date style " + style);
         }
     }
 
     private static void checkTimeStyle(int style) {
         if (!(style == SHORT || style == MEDIUM || style == LONG
                 || style == FULL || style == DEFAULT)) {
-            // text.0F=Illegal time style: {0}
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.0F", style)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Illegal time style " + style);
         }
     }
 }
diff --git a/text/src/main/java/java/text/DateFormatSymbols.java b/text/src/main/java/java/text/DateFormatSymbols.java
index ac23ad2..d586ae1 100644
--- a/text/src/main/java/java/text/DateFormatSymbols.java
+++ b/text/src/main/java/java/text/DateFormatSymbols.java
@@ -15,22 +15,16 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.util.LocaleData;
+import com.ibm.icu4jni.util.ICU;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Locale;
 
-// BEGIN android-added
-import com.ibm.icu4jni.util.LocaleData;
-import com.ibm.icu4jni.util.Resources;
-// END android-added
 /**
  * Encapsulates localizable date-time formatting data, such as the names of the
  * months, the names of the days of the week, and the time zone data.
@@ -100,7 +94,7 @@
      */
     synchronized String[][] internalZoneStrings() {
         if (zoneStrings == null) {
-            zoneStrings = Resources.getDisplayTimeZones(locale.toString());
+            zoneStrings = ICU.getDisplayTimeZones(locale.toString());
         }
         return zoneStrings;
     }
@@ -108,7 +102,8 @@
 
     /**
      * Constructs a new {@code DateFormatSymbols} instance containing the
-     * symbols for the default locale.
+     * symbols for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
     public DateFormatSymbols() {
         this(Locale.getDefault());
@@ -123,18 +118,53 @@
      */
     public DateFormatSymbols(Locale locale) {
         this.locale = locale;
-        // BEGIN android-changed
         this.localPatternChars = SimpleDateFormat.patternChars;
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
+        LocaleData localeData = LocaleData.get(locale);
         this.ampms = localeData.amPm;
         this.eras = localeData.eras;
         this.months = localeData.longMonthNames;
         this.shortMonths = localeData.shortMonthNames;
         this.weekdays = localeData.longWeekdayNames;
         this.shortWeekdays = localeData.shortWeekdayNames;
-        // END android-changed
     }
 
+    /**
+     * Returns a new {@code DateFormatSymbols} instance for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
+     * @return an instance of {@code DateFormatSymbols}
+     * @since 1.6
+     * @hide
+     */
+    public static final DateFormatSymbols getInstance() {
+        return getInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns a new {@code DateFormatSymbols} for the given locale.
+     *
+     * @param locale the locale
+     * @return an instance of {@code DateFormatSymbols}
+     * @throws NullPointerException if {@code locale == null}
+     * @since 1.6
+     * @hide
+     */
+    public static final DateFormatSymbols getInstance(Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException();
+        }
+        return new DateFormatSymbols(locale);
+    }
+
+    /**
+     * Returns an array of locales for which custom {@code DateFormatSymbols} instances
+     * are available.
+     * @since 1.6
+     * @hide
+     */
+    public static Locale[] getAvailableLocales() {
+        return ICU.getAvailableDateFormatSymbolsLocales();
+    }
 
     private void writeObject(ObjectOutputStream oos) throws IOException {
         // BEGIN android-changed
@@ -188,64 +218,42 @@
         if (!(object instanceof DateFormatSymbols)) {
             return false;
         }
+        DateFormatSymbols rhs = (DateFormatSymbols) object;
+        return localPatternChars.equals(rhs.localPatternChars) &&
+                Arrays.equals(ampms, rhs.ampms) &&
+                Arrays.equals(eras, rhs.eras) &&
+                Arrays.equals(months, rhs.months) &&
+                Arrays.equals(shortMonths, rhs.shortMonths) &&
+                Arrays.equals(shortWeekdays, rhs.shortWeekdays) &&
+                Arrays.equals(weekdays, rhs.weekdays) &&
+                timeZoneStringsEqual(this, rhs);
+    }
 
-        // BEGIN android-removed
-        // if (zoneStrings == null) {
-        //     zoneStrings = icuSymbols.getZoneStrings();
-        // }
-        // END android-removed
-        DateFormatSymbols obj = (DateFormatSymbols) object;
-        // BEGIN android-removed
-        // if (obj.zoneStrings == null) {
-        //     obj.zoneStrings = obj.icuSymbols.getZoneStrings();
-        // }
-        // END android-removed
-        if (!localPatternChars.equals(obj.localPatternChars)) {
-            return false;
-        }
-        if (!Arrays.equals(ampms, obj.ampms)) {
-            return false;
-        }
-        if (!Arrays.equals(eras, obj.eras)) {
-            return false;
-        }
-        if (!Arrays.equals(months, obj.months)) {
-            return false;
-        }
-        if (!Arrays.equals(shortMonths, obj.shortMonths)) {
-            return false;
-        }
-        if (!Arrays.equals(shortWeekdays, obj.shortWeekdays)) {
-            return false;
-        }
-        if (!Arrays.equals(weekdays, obj.weekdays)) {
-            return false;
-        }
-        // BEGIN android-changed
+    private static boolean timeZoneStringsEqual(DateFormatSymbols lhs, DateFormatSymbols rhs) {
         // Quick check that may keep us from having to load the zone strings.
-        if (zoneStrings == null && obj.zoneStrings == null
-                    && !locale.equals(obj.locale)) {
-            return false;
+        // Note that different locales may have the same strings, so the opposite check isn't valid.
+        if (lhs.zoneStrings == null && rhs.zoneStrings == null && lhs.locale.equals(rhs.locale)) {
+            return true;
         }
-        // Make sure zone strings are loaded.
-        internalZoneStrings();
-        obj.internalZoneStrings();
-        // END android-changed
-        if (zoneStrings.length != obj.zoneStrings.length) {
-            return false;
-        }
-        for (String[] element : zoneStrings) {
-            if (element.length != element.length) {
-                return false;
-            }
-            for (int j = 0; j < element.length; j++) {
-                if (element[j] != element[j]
-                        && !(element[j].equals(element[j]))) {
-                    return false;
-                }
-            }
-        }
-        return true;
+        // Make sure zone strings are loaded, then check.
+        return Arrays.deepEquals(lhs.internalZoneStrings(), rhs.internalZoneStrings());
+    }
+
+    @Override
+    public String toString() {
+        // 'locale' isn't part of the externally-visible state.
+        // 'zoneStrings' is so large, we just print a representative value.
+        return getClass().getName() +
+                "[amPmStrings=" + Arrays.toString(ampms) +
+                ",customZoneStrings=" + customZoneStrings +
+                ",eras=" + Arrays.toString(eras) +
+                ",localPatternChars=" + new String(localPatternChars) +
+                ",months=" + Arrays.toString(months) +
+                ",shortMonths=" + Arrays.toString(shortMonths) +
+                ",shortWeekdays=" + Arrays.toString(shortWeekdays) +
+                ",weekdays=" + Arrays.toString(weekdays) +
+                ",zoneStrings=[" + Arrays.toString(internalZoneStrings()[0]) + "...]" +
+                "]";
     }
 
     /**
@@ -334,9 +342,7 @@
      * @return a two-dimensional array of strings.
      */
     public String[][] getZoneStrings() {
-        // BEGIN android-changed
-        return Resources.clone2dStringArray(internalZoneStrings());
-        // END android-changed
+        return ICU.clone2dStringArray(internalZoneStrings());
     }
 
     @Override
@@ -473,7 +479,7 @@
      *            the two-dimensional array of strings.
      */
     public void setZoneStrings(String[][] data) {
-        zoneStrings = Resources.clone2dStringArray(data);
+        zoneStrings = ICU.clone2dStringArray(data);
         customZoneStrings = true;
     }
 }
diff --git a/text/src/main/java/java/text/DecimalFormat.java b/text/src/main/java/java/text/DecimalFormat.java
index 65d4d48..d7ac012 100644
--- a/text/src/main/java/java/text/DecimalFormat.java
+++ b/text/src/main/java/java/text/DecimalFormat.java
@@ -15,26 +15,22 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.text.NativeDecimalFormat;
+import com.ibm.icu4jni.util.LocaleData;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Currency;
 import java.util.Locale;
 
-import com.ibm.icu4jni.text.NativeDecimalFormat;
-import com.ibm.icu4jni.util.LocaleData;
-
 /**
  * A concrete subclass of {@link NumberFormat} that formats decimal numbers. It
  * has a variety of features designed to make it possible to parse and format
@@ -241,7 +237,7 @@
  * </tr>
  * </table> </blockquote>
  * <p>
- * A {@code DecimalFormat} pattern contains a postive and negative subpattern,
+ * A {@code DecimalFormat} pattern contains a positive and negative subpattern,
  * for example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, a numeric
  * part and a suffix. If there is no explicit negative subpattern, the negative
  * subpattern is the localized minus sign prefixed to the positive subpattern.
@@ -356,7 +352,7 @@
  * example, 0.125 is formatted as "0.12" if the maximum fraction digits is 2.
  * <li>If the number of actual fraction digits is less than the
  * <em>minimum fraction digits</em>, then trailing zeros are added. For
- * example, 0.125 is formatted as "0.1250" if the mimimum fraction digits is set
+ * example, 0.125 is formatted as "0.1250" if the minimum fraction digits is set
  * to 4.
  * <li>Trailing fractional zeros are not displayed if they occur <em>j</em>
  * positions after the decimal, where <em>j</em> is less than the maximum
@@ -502,7 +498,7 @@
  * number of '@' characters in the pattern - 1, and a maximum fraction digit
  * count of the number of '@' and '#' characters in the pattern - 1. For
  * example, the pattern {@code "@@###E0"} is equivalent to {@code "0.0###E0"}.
- * <li>If signficant digits are in use then the integer and fraction digit
+ * <li>If significant digits are in use then the integer and fraction digit
  * counts, as set via the API, are ignored.
  * </ul>
  * <h4> <strong><font color="red">NEW</font>&nbsp;</strong> Padding</h4>
@@ -553,32 +549,30 @@
 
     private transient NativeDecimalFormat dform;
 
+    private transient RoundingMode roundingMode = RoundingMode.HALF_EVEN;
+
     /**
      * Constructs a new {@code DecimalFormat} for formatting and parsing numbers
-     * for the default locale.
+     * for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
     public DecimalFormat() {
-        // BEGIN android-changed: reduce duplication.
         Locale locale = Locale.getDefault();
         this.symbols = new DecimalFormatSymbols(locale);
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        initNative(localeData.numberPattern);
-        // END android-changed
+        initNative(LocaleData.get(locale).numberPattern);
     }
 
     /**
      * Constructs a new {@code DecimalFormat} using the specified non-localized
-     * pattern and the {@code DecimalFormatSymbols} for the default Locale.
-     * 
+     * pattern and the {@code DecimalFormatSymbols} for the user's default Locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * @param pattern
      *            the non-localized pattern.
      * @throws IllegalArgumentException
      *            if the pattern cannot be parsed.
      */
     public DecimalFormat(String pattern) {
-        // BEGIN android-changed: reduce duplication.
         this(pattern, Locale.getDefault());
-        // END android-changed
     }
 
     /**
@@ -593,20 +587,16 @@
      *            if the pattern cannot be parsed.
      */
     public DecimalFormat(String pattern, DecimalFormatSymbols value) {
-        // BEGIN android-changed: reduce duplication.
         this.symbols = (DecimalFormatSymbols) value.clone();
         initNative(pattern);
-        // END android-changed
     }
 
-    // BEGIN android-added: used by NumberFormat.getInstance because cloning DecimalFormatSymbols is slow.
+    // Used by NumberFormat.getInstance because cloning DecimalFormatSymbols is slow.
     DecimalFormat(String pattern, Locale locale) {
         this.symbols = new DecimalFormatSymbols(locale);
         initNative(pattern);
     }
-    // END android-added
 
-    // BEGIN android-changed: reduce duplication.
     private void initNative(String pattern) {
         try {
             this.dform = new NativeDecimalFormat(pattern, symbols);
@@ -618,7 +608,6 @@
         super.setMinimumFractionDigits(dform.getMinimumFractionDigits());
         super.setMinimumIntegerDigits(dform.getMinimumIntegerDigits());
     }
-    // END android-added
 
     /**
      * Changes the pattern of this decimal format to the specified pattern which
@@ -709,6 +698,21 @@
 
     @Override
     public StringBuffer format(double value, StringBuffer buffer, FieldPosition position) {
+        // All float/double/Float/Double formatting ends up here...
+        if (roundingMode == RoundingMode.UNNECESSARY) {
+            // ICU4C doesn't support this rounding mode, so we have to fake it.
+            try {
+                setRoundingMode(RoundingMode.UP);
+                String upResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
+                setRoundingMode(RoundingMode.DOWN);
+                String downResult = format(value, new StringBuffer(), new FieldPosition(0)).toString();
+                if (!upResult.equals(downResult)) {
+                    throw new ArithmeticException("rounding mode UNNECESSARY but rounding required");
+                }
+            } finally {
+                setRoundingMode(RoundingMode.UNNECESSARY);
+            }
+        }
         return dform.format(value, buffer, position);
     }
 
@@ -1040,6 +1044,8 @@
     public void setMaximumFractionDigits(int value) {
         super.setMaximumFractionDigits(value);
         dform.setMaximumFractionDigits(getMaximumFractionDigits());
+        // Changing the maximum fraction digits needs to update ICU4C's rounding configuration.
+        setRoundingMode(roundingMode);
     }
 
     /**
@@ -1176,11 +1182,10 @@
             new ObjectStreamField("negSuffixPattern", String.class), //$NON-NLS-1$
             new ObjectStreamField("multiplier", int.class), //$NON-NLS-1$
             new ObjectStreamField("groupingSize", byte.class), //$NON-NLS-1$
-            // BEGIN android-added
             new ObjectStreamField("groupingUsed", boolean.class), //$NON-NLS-1$
-            // END android-added
             new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class), //$NON-NLS-1$
             new ObjectStreamField("parseBigDecimal", boolean.class), //$NON-NLS-1$
+            new ObjectStreamField("roundingMode", RoundingMode.class), //$NON-NLS-1$
             new ObjectStreamField("symbols", DecimalFormatSymbols.class), //$NON-NLS-1$
             new ObjectStreamField("useExponentialNotation", boolean.class), //$NON-NLS-1$
             new ObjectStreamField("minExponentDigits", byte.class), //$NON-NLS-1$
@@ -1220,6 +1225,7 @@
         fields.put("decimalSeparatorAlwaysShown", dform
                 .isDecimalSeparatorAlwaysShown());
         fields.put("parseBigDecimal", parseBigDecimal);
+        fields.put("roundingMode", roundingMode);
         fields.put("symbols", symbols);
         fields.put("useExponentialNotation", false);
         fields.put("minExponentDigits", (byte) 0);
@@ -1227,7 +1233,7 @@
         fields.put("minimumIntegerDigits", dform.getMinimumIntegerDigits());
         fields.put("maximumFractionDigits", dform.getMaximumFractionDigits());
         fields.put("minimumFractionDigits", dform.getMinimumFractionDigits());
-        fields.put("serialVersionOnStream", 3);
+        fields.put("serialVersionOnStream", 4);
         stream.writeFields();
     }
 
@@ -1243,9 +1249,7 @@
      *             if some class of serialized objects or fields cannot be found
      */
     @SuppressWarnings("nls")
-    private void readObject(ObjectInputStream stream) throws IOException,
-            ClassNotFoundException {
-
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         // BEGIN android-changed
         ObjectInputStream.GetField fields = stream.readFields();
         this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
@@ -1260,6 +1264,8 @@
         dform.setGroupingUsed(fields.get("groupingUsed", true));
         dform.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown", false));
 
+        setRoundingMode((RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN));
+
         final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
         final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
         final int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
@@ -1285,4 +1291,29 @@
         }
         // END android-changed
     }
+
+    /**
+     * Returns the {@code RoundingMode} used by this {@code NumberFormat}.
+     * @since 1.6
+     * @hide
+     */
+    public RoundingMode getRoundingMode() {
+        return roundingMode;
+    }
+
+    /**
+     * Sets the {@code RoundingMode} used by this {@code NumberFormat}.
+     * @since 1.6
+     * @hide
+     */
+    public void setRoundingMode(RoundingMode roundingMode) {
+        if (roundingMode == null) {
+            throw new NullPointerException();
+        }
+        this.roundingMode = roundingMode;
+        if (roundingMode != RoundingMode.UNNECESSARY) { // ICU4C doesn't support UNNECESSARY.
+            double roundingIncrement = 1.0 / Math.pow(10, Math.max(0, getMaximumFractionDigits()));
+            dform.setRoundingMode(roundingMode, roundingIncrement);
+        }
+    }
 }
diff --git a/text/src/main/java/java/text/DecimalFormatSymbols.java b/text/src/main/java/java/text/DecimalFormatSymbols.java
index 28e9603..a32f6cf 100644
--- a/text/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/text/src/main/java/java/text/DecimalFormatSymbols.java
@@ -17,6 +17,8 @@
 
 package java.text;
 
+import com.ibm.icu4jni.util.LocaleData;
+import com.ibm.icu4jni.util.ICU;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -26,8 +28,6 @@
 import java.util.Currency;
 import java.util.Locale;
 
-import com.ibm.icu4jni.util.LocaleData;
-
 /**
  * Encapsulates the set of symbols (such as the decimal separator, the grouping
  * separator, and so on) needed by {@code DecimalFormat} to format numbers.
@@ -43,22 +43,26 @@
 
     private static final long serialVersionUID = 5772796243397350300L;
 
-    private final int ZeroDigit = 0, Digit = 1, DecimalSeparator = 2,
-            GroupingSeparator = 3, PatternSeparator = 4, Percent = 5,
-            PerMill = 6, Exponent = 7, MonetaryDecimalSeparator = 8,
-            MinusSign = 9;
-
-    private transient char[] patternChars;
+    private char zeroDigit;
+    private char digit;
+    private char decimalSeparator;
+    private char groupingSeparator;
+    private char patternSeparator;
+    private char percent;
+    private char perMill;
+    private char monetarySeparator;
+    private char minusSign;
+    private String infinity, NaN, currencySymbol, intlCurrencySymbol;
 
     private transient Currency currency;
-
     private transient Locale locale;
-
-    private String infinity, NaN, currencySymbol, intlCurrencySymbol;
+    private transient String exponentSeparator;
 
     /**
      * Constructs a new {@code DecimalFormatSymbols} containing the symbols for
-     * the default locale. Best practice is to create a {@code DecimalFormat}
+     * the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * Best practice is to create a {@code DecimalFormat}
      * and then to get the {@code DecimalFormatSymbols} from that object by
      * calling {@link DecimalFormat#getDecimalFormatSymbols()}.
      */
@@ -68,7 +72,9 @@
 
     /**
      * Constructs a new DecimalFormatSymbols containing the symbols for the
-     * specified Locale. Best practice is to create a {@code DecimalFormat}
+     * specified Locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * Best practice is to create a {@code DecimalFormat}
      * and then to get the {@code DecimalFormatSymbols} from that object by
      * calling {@link DecimalFormat#getDecimalFormatSymbols()}.
      * 
@@ -76,41 +82,75 @@
      *            the locale.
      */
     public DecimalFormatSymbols(Locale locale) {
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        this.patternChars = localeData.decimalPatternChars.toCharArray();
+        LocaleData localeData = LocaleData.get(locale);
+        this.zeroDigit = localeData.zeroDigit;
+        this.digit = localeData.digit;
+        this.decimalSeparator = localeData.decimalSeparator;
+        this.groupingSeparator = localeData.groupingSeparator;
+        this.patternSeparator = localeData.patternSeparator;
+        this.percent = localeData.percent;
+        this.perMill = localeData.perMill;
+        this.monetarySeparator = localeData.monetarySeparator;
+        this.minusSign = localeData.minusSign;
         this.infinity = localeData.infinity;
         this.NaN = localeData.NaN;
+        this.exponentSeparator = localeData.exponentSeparator;
         this.locale = locale;
         try {
             currency = Currency.getInstance(locale);
             currencySymbol = currency.getSymbol(locale);
             intlCurrencySymbol = currency.getCurrencyCode();
         } catch (IllegalArgumentException e) {
-            currency = Currency.getInstance("XXX"); //$NON-NLS-1$
+            currency = Currency.getInstance("XXX");
             currencySymbol = localeData.currencySymbol;
             intlCurrencySymbol = localeData.internationalCurrencySymbol;
         }
-        // END android-changed
     }
 
- 
     /**
-     * Returns a new {@code DecimalFormatSymbols} with the same symbols as this
-     * {@code DecimalFormatSymbols}.
+     * Returns a new {@code DecimalFormatSymbols} instance for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
-     * @return a shallow copy of this {@code DecimalFormatSymbols}.
-     * 
-     * @see java.lang.Cloneable
+     * @return an instance of {@code DecimalFormatSymbols}
+     * @since 1.6
+     * @hide
      */
+    public static final DecimalFormatSymbols getInstance() {
+        return getInstance(Locale.getDefault());
+    }
+
+    /**
+     * Returns a new {@code DecimalFormatSymbols} for the given locale.
+     *
+     * @param locale the locale
+     * @return an instance of {@code DecimalFormatSymbols}
+     * @throws NullPointerException if {@code locale == null}
+     * @since 1.6
+     * @hide
+     */
+    public static final DecimalFormatSymbols getInstance(Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException();
+        }
+        return new DecimalFormatSymbols(locale);
+    }
+
+    /**
+     * Returns an array of locales for which custom {@code DecimalFormatSymbols} instances
+     * are available.
+     * @since 1.6
+     * @hide
+     */
+    public static Locale[] getAvailableLocales() {
+        return ICU.getAvailableDecimalFormatSymbolsLocales();
+    }
+
     @Override
     public Object clone() {
         try {
-            DecimalFormatSymbols symbols = (DecimalFormatSymbols) super.clone();
-            symbols.patternChars = patternChars.clone();
-            return symbols;
+            return super.clone();
         } catch (CloneNotSupportedException e) {
-            throw new AssertionError(e); // android-changed
+            throw new AssertionError(e);
         }
     }
 
@@ -134,10 +174,42 @@
             return false;
         }
         DecimalFormatSymbols obj = (DecimalFormatSymbols) object;
-        return Arrays.equals(patternChars, obj.patternChars)
-                && infinity.equals(obj.infinity) && NaN.equals(obj.NaN)
-                && currencySymbol.equals(obj.currencySymbol)
-                && intlCurrencySymbol.equals(obj.intlCurrencySymbol);
+        return currency.equals(obj.currency) &&
+                currencySymbol.equals(obj.currencySymbol) &&
+                decimalSeparator == obj.decimalSeparator &&
+                digit == obj.digit &&
+                exponentSeparator.equals(obj.exponentSeparator) &&
+                groupingSeparator == obj.groupingSeparator &&
+                infinity.equals(obj.infinity) &&
+                intlCurrencySymbol.equals(obj.intlCurrencySymbol) &&
+                minusSign == obj.minusSign &&
+                monetarySeparator == obj.monetarySeparator &&
+                NaN.equals(obj.NaN) &&
+                patternSeparator == obj.patternSeparator &&
+                perMill == obj.perMill &&
+                percent == obj.percent &&
+                zeroDigit == obj.zeroDigit;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName() +
+                "[currency=" + currency +
+                ",currencySymbol=" + currencySymbol +
+                ",decimalSeparator=" + decimalSeparator +
+                ",digit=" + digit +
+                ",exponentSeparator=" + exponentSeparator +
+                ",groupingSeparator=" + groupingSeparator +
+                ",infinity=" + infinity +
+                ",intlCurrencySymbol=" + intlCurrencySymbol +
+                ",minusSign=" + minusSign +
+                ",monetarySeparator=" + monetarySeparator +
+                ",NaN=" + NaN +
+                ",patternSeparator=" + patternSeparator +
+                ",perMill=" + perMill +
+                ",percent=" + percent +
+                ",zeroDigit=" + zeroDigit +
+                "]";
     }
 
     /**
@@ -182,7 +254,7 @@
      * @return the decimal separator character.
      */
     public char getDecimalSeparator() {
-        return patternChars[DecimalSeparator];
+        return decimalSeparator;
     }
 
     /**
@@ -192,7 +264,7 @@
      * @return the digit pattern character.
      */
     public char getDigit() {
-        return patternChars[Digit];
+        return digit;
     }
 
     /**
@@ -201,7 +273,7 @@
      * @return the thousands separator character.
      */
     public char getGroupingSeparator() {
-        return patternChars[GroupingSeparator];
+        return groupingSeparator;
     }
 
     /**
@@ -219,7 +291,7 @@
      * @return the minus sign as a character.
      */
     public char getMinusSign() {
-        return patternChars[MinusSign];
+        return minusSign;
     }
 
     /**
@@ -229,7 +301,7 @@
      * @return the monetary decimal point as a character.
      */
     public char getMonetaryDecimalSeparator() {
-        return patternChars[MonetaryDecimalSeparator];
+        return monetarySeparator;
     }
 
     /**
@@ -248,7 +320,7 @@
      * @return the pattern separator character.
      */
     public char getPatternSeparator() {
-        return patternChars[PatternSeparator];
+        return patternSeparator;
     }
 
     /**
@@ -257,7 +329,7 @@
      * @return the percent character.
      */
     public char getPercent() {
-        return patternChars[Percent];
+        return percent;
     }
 
     /**
@@ -266,7 +338,7 @@
      * @return the per mill sign character.
      */
     public char getPerMill() {
-        return patternChars[PerMill];
+        return perMill;
     }
 
     /**
@@ -275,21 +347,36 @@
      * @return the zero character.
      */
     public char getZeroDigit() {
-        return patternChars[ZeroDigit];
+        return zeroDigit;
     }
 
     /*
-     * Returns the exponent as a character.
+     * Returns the string used to separate mantissa and exponent. Typically "E", as in "1.2E3".
+     * @since 1.6
+     * @hide
      */
-    char getExponential() {
-        return patternChars[Exponent];
+    public String getExponentSeparator() {
+        return exponentSeparator;
     }
 
     @Override
     public int hashCode() {
-        return new String(patternChars).hashCode() + infinity.hashCode()
-                + NaN.hashCode() + currencySymbol.hashCode()
-                + intlCurrencySymbol.hashCode();
+        int result = 17;
+        result = 31*result + zeroDigit;
+        result = 31*result + digit;
+        result = 31*result + decimalSeparator;
+        result = 31*result + groupingSeparator;
+        result = 31*result + patternSeparator;
+        result = 31*result + percent;
+        result = 31*result + perMill;
+        result = 31*result + monetarySeparator;
+        result = 31*result + minusSign;
+        result = 31*result + exponentSeparator.hashCode();
+        result = 31*result + infinity.hashCode();
+        result = 31*result + NaN.hashCode();
+        result = 31*result + currencySymbol.hashCode();
+        result = 31*result + intlCurrencySymbol.hashCode();
+        return result;
     }
 
     /**
@@ -354,7 +441,7 @@
      *            the currency symbol.
      */
     public void setCurrencySymbol(String value) {
-        currencySymbol = value;
+        this.currencySymbol = value;
     }
 
     /**
@@ -364,7 +451,7 @@
      *            the decimal separator character.
      */
     public void setDecimalSeparator(char value) {
-        patternChars[DecimalSeparator] = value;
+        this.decimalSeparator = value;
     }
 
     /**
@@ -374,7 +461,7 @@
      *            the digit character.
      */
     public void setDigit(char value) {
-        patternChars[Digit] = value;
+        this.digit = value;
     }
 
     /**
@@ -384,7 +471,7 @@
      *            the grouping separator character.
      */
     public void setGroupingSeparator(char value) {
-        patternChars[GroupingSeparator] = value;
+        this.groupingSeparator = value;
     }
 
     /**
@@ -394,7 +481,7 @@
      *            the string representing infinity.
      */
     public void setInfinity(String value) {
-        infinity = value;
+        this.infinity = value;
     }
 
     /**
@@ -404,7 +491,7 @@
      *            the minus sign character.
      */
     public void setMinusSign(char value) {
-        patternChars[MinusSign] = value;
+        this.minusSign = value;
     }
 
     /**
@@ -415,7 +502,7 @@
      *            the monetary decimal separator character.
      */
     public void setMonetaryDecimalSeparator(char value) {
-        patternChars[MonetaryDecimalSeparator] = value;
+        this.monetarySeparator = value;
     }
 
     /**
@@ -425,7 +512,7 @@
      *            the string representing NaN.
      */
     public void setNaN(String value) {
-        NaN = value;
+        this.NaN = value;
     }
 
     /**
@@ -436,7 +523,7 @@
      *            the pattern separator character.
      */
     public void setPatternSeparator(char value) {
-        patternChars[PatternSeparator] = value;
+        this.patternSeparator = value;
     }
 
     /**
@@ -446,7 +533,7 @@
      *            the percent character.
      */
     public void setPercent(char value) {
-        patternChars[Percent] = value;
+        this.percent = value;
     }
 
     /**
@@ -456,7 +543,7 @@
      *            the per mill character.
      */
     public void setPerMill(char value) {
-        patternChars[PerMill] = value;
+        this.perMill = value;
     }
 
     /**
@@ -466,80 +553,96 @@
      *            the zero digit character.
      */
     public void setZeroDigit(char value) {
-        patternChars[ZeroDigit] = value;
+        this.zeroDigit = value;
     }
 
-    /*
-     * Sets the exponent character.
+    /**
+     * Sets the string used to separate mantissa and exponent. Typically "E", as in "1.2E3".
+     * @since 1.6
+     * @hide
      */
-    void setExponential(char value) {
-        patternChars[Exponent] = value;
+    public void setExponentSeparator(String value) {
+        if (value == null) {
+            throw new NullPointerException();
+        }
+        this.exponentSeparator = value;
     }
 
     private static final ObjectStreamField[] serialPersistentFields = {
-            new ObjectStreamField("currencySymbol", String.class), //$NON-NLS-1$
-            new ObjectStreamField("decimalSeparator", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("digit", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("exponential", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("groupingSeparator", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("infinity", String.class), //$NON-NLS-1$
-            new ObjectStreamField("intlCurrencySymbol", String.class), //$NON-NLS-1$
-            new ObjectStreamField("minusSign", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("monetarySeparator", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("NaN", String.class), //$NON-NLS-1$
-            new ObjectStreamField("patternSeparator", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("percent", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("perMill", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("serialVersionOnStream", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("zeroDigit", Character.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("locale", Locale.class), }; //$NON-NLS-1$
+        new ObjectStreamField("currencySymbol", String.class),
+        new ObjectStreamField("decimalSeparator", Character.TYPE),
+        new ObjectStreamField("digit", Character.TYPE),
+        new ObjectStreamField("exponential", Character.TYPE),
+        new ObjectStreamField("exponentialSeparator", String.class),
+        new ObjectStreamField("groupingSeparator", Character.TYPE),
+        new ObjectStreamField("infinity", String.class),
+        new ObjectStreamField("intlCurrencySymbol", String.class),
+        new ObjectStreamField("minusSign", Character.TYPE),
+        new ObjectStreamField("monetarySeparator", Character.TYPE),
+        new ObjectStreamField("NaN", String.class),
+        new ObjectStreamField("patternSeparator", Character.TYPE),
+        new ObjectStreamField("percent", Character.TYPE),
+        new ObjectStreamField("perMill", Character.TYPE),
+        new ObjectStreamField("serialVersionOnStream", Integer.TYPE),
+        new ObjectStreamField("zeroDigit", Character.TYPE),
+        new ObjectStreamField("locale", Locale.class),
+    };
 
     private void writeObject(ObjectOutputStream stream) throws IOException {
         ObjectOutputStream.PutField fields = stream.putFields();
-        fields.put("currencySymbol", currencySymbol); //$NON-NLS-1$
-        fields.put("decimalSeparator", getDecimalSeparator()); //$NON-NLS-1$
-        fields.put("digit", getDigit()); //$NON-NLS-1$
-        fields.put("exponential", getExponential()); //$NON-NLS-1$
-        fields.put("groupingSeparator", getGroupingSeparator()); //$NON-NLS-1$
-        fields.put("infinity", infinity); //$NON-NLS-1$
-        fields.put("intlCurrencySymbol", intlCurrencySymbol); //$NON-NLS-1$
-        fields.put("minusSign", getMinusSign()); //$NON-NLS-1$
-        fields.put("monetarySeparator", getMonetaryDecimalSeparator()); //$NON-NLS-1$
-        fields.put("NaN", NaN); //$NON-NLS-1$
-        fields.put("patternSeparator", getPatternSeparator()); //$NON-NLS-1$
-        fields.put("percent", getPercent()); //$NON-NLS-1$
-        fields.put("perMill", getPerMill()); //$NON-NLS-1$
-        fields.put("serialVersionOnStream", 1); //$NON-NLS-1$
-        fields.put("zeroDigit", getZeroDigit()); //$NON-NLS-1$
-        fields.put("locale", locale); //$NON-NLS-1$
+        fields.put("currencySymbol", currencySymbol);
+        fields.put("decimalSeparator", getDecimalSeparator());
+        fields.put("digit", getDigit());
+        fields.put("exponential", exponentSeparator.charAt(0));
+        fields.put("exponentialSeparator", exponentSeparator);
+        fields.put("groupingSeparator", getGroupingSeparator());
+        fields.put("infinity", infinity);
+        fields.put("intlCurrencySymbol", intlCurrencySymbol);
+        fields.put("minusSign", getMinusSign());
+        fields.put("monetarySeparator", getMonetaryDecimalSeparator());
+        fields.put("NaN", NaN);
+        fields.put("patternSeparator", getPatternSeparator());
+        fields.put("percent", getPercent());
+        fields.put("perMill", getPerMill());
+        fields.put("serialVersionOnStream", 3);
+        fields.put("zeroDigit", getZeroDigit());
+        fields.put("locale", locale);
         stream.writeFields();
     }
 
-    private void readObject(ObjectInputStream stream) throws IOException,
-            ClassNotFoundException {
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
         ObjectInputStream.GetField fields = stream.readFields();
-        patternChars = new char[10];
-        currencySymbol = (String) fields.get("currencySymbol", ""); //$NON-NLS-1$ //$NON-NLS-2$
-        setDecimalSeparator(fields.get("decimalSeparator", '.')); //$NON-NLS-1$
-        setDigit(fields.get("digit", '#')); //$NON-NLS-1$
-        setGroupingSeparator(fields.get("groupingSeparator", ',')); //$NON-NLS-1$
-        infinity = (String) fields.get("infinity", ""); //$NON-NLS-1$ //$NON-NLS-2$
-        intlCurrencySymbol = (String) fields.get("intlCurrencySymbol", ""); //$NON-NLS-1$ //$NON-NLS-2$
-        setMinusSign(fields.get("minusSign", '-')); //$NON-NLS-1$
-        NaN = (String) fields.get("NaN", ""); //$NON-NLS-1$ //$NON-NLS-2$
-        setPatternSeparator(fields.get("patternSeparator", ';')); //$NON-NLS-1$
-        setPercent(fields.get("percent", '%')); //$NON-NLS-1$
-        setPerMill(fields.get("perMill", '\u2030')); //$NON-NLS-1$
-        setZeroDigit(fields.get("zeroDigit", '0')); //$NON-NLS-1$
-        locale = (Locale) fields.get("locale", null); //$NON-NLS-1$
-        if (fields.get("serialVersionOnStream", 0) == 0) { //$NON-NLS-1$
+        final int serialVersionOnStream = fields.get("serialVersionOnStream", 0);
+        currencySymbol = (String) fields.get("currencySymbol", "");
+        setDecimalSeparator(fields.get("decimalSeparator", '.'));
+        setDigit(fields.get("digit", '#'));
+        setGroupingSeparator(fields.get("groupingSeparator", ','));
+        infinity = (String) fields.get("infinity", "");
+        intlCurrencySymbol = (String) fields.get("intlCurrencySymbol", "");
+        setMinusSign(fields.get("minusSign", '-'));
+        NaN = (String) fields.get("NaN", "");
+        setPatternSeparator(fields.get("patternSeparator", ';'));
+        setPercent(fields.get("percent", '%'));
+        setPerMill(fields.get("perMill", '\u2030'));
+        setZeroDigit(fields.get("zeroDigit", '0'));
+        locale = (Locale) fields.get("locale", null);
+        if (serialVersionOnStream == 0) {
             setMonetaryDecimalSeparator(getDecimalSeparator());
-            setExponential('E');
         } else {
-            setMonetaryDecimalSeparator(fields.get("monetarySeparator", '.')); //$NON-NLS-1$
-            setExponential(fields.get("exponential", 'E')); //$NON-NLS-1$
-
+            setMonetaryDecimalSeparator(fields.get("monetarySeparator", '.'));
         }
+
+        if (serialVersionOnStream == 0) {
+            // Prior to Java 1.1.6, the exponent separator wasn't configurable.
+            exponentSeparator = "E";
+        } else if (serialVersionOnStream < 3) {
+            // In Javas 1.1.6 and 1.4, there was a character field "exponential".
+            setExponentSeparator(String.valueOf(fields.get("exponential", 'E')));
+        } else {
+            // In Java 6, there's a new "exponentialSeparator" field.
+            setExponentSeparator((String) fields.get("exponentialSeparator", "E"));
+        }
+
         try {
             currency = Currency.getInstance(intlCurrencySymbol);
         } catch (IllegalArgumentException e) {
diff --git a/text/src/main/java/java/text/Format.java b/text/src/main/java/java/text/Format.java
index 18b0490..0ebaba5 100644
--- a/text/src/main/java/java/text/Format.java
+++ b/text/src/main/java/java/text/Format.java
@@ -20,11 +20,7 @@
 import java.io.Serializable;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-// BEGIN android-added
 import java.util.Locale;
-// END android-added
-
-import org.apache.harmony.text.internal.nls.Messages;
 
 /**
  * The base class for all formats.
@@ -66,9 +62,9 @@
     private static final long serialVersionUID = -299282585814624189L;
 
     /**
-     * Constructs a new {@code Format} instance.
+     * Used by subclasses. This was public in Java 5.
      */
-    public Format() {
+    protected Format() {
     }
 
     /**
@@ -103,19 +99,16 @@
             }
             if (!quote && (index = fromChars.indexOf(next)) != -1) {
                 output.append(toChars.charAt(index));
-            } else if (check
-                    && !quote
+            } else if (check && !quote
                     && ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) {
-                // text.05=Invalid pattern char {0} in {1}
-                throw new IllegalArgumentException(Messages.getString(
-                        "text.05", String.valueOf(next), template)); //$NON-NLS-1$
+                throw new IllegalArgumentException("Invalid pattern character '" + next + "' in " +
+                        "'" + template + "'");
             } else {
                 output.append(next);
             }
         }
         if (quote) {
-            // text.04=Unterminated quote
-            throw new IllegalArgumentException(Messages.getString("text.04")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Unterminated quote");
         }
         return output.toString();
     }
@@ -189,9 +182,7 @@
         ParsePosition position = new ParsePosition(0);
         Object result = parseObject(string, position);
         if (position.getIndex() == 0) {
-            // text.1C=Format.parseObject(String) parse failure
-            throw new ParseException(
-                    Messages.getString("text.1C"), position.getErrorIndex()); //$NON-NLS-1$
+            throw new ParseException("parse failure", position.getErrorIndex());
         }
         return result;
     }
@@ -263,8 +254,7 @@
             }
             buffer.append(ch);
         }
-        // text.07=Unmatched braces in the pattern
-        throw new IllegalArgumentException(Messages.getString("text.07")); //$NON-NLS-1$
+        throw new IllegalArgumentException("Unmatched braces in the pattern");
     }
 
     /**
diff --git a/text/src/main/java/java/text/MessageFormat.java b/text/src/main/java/java/text/MessageFormat.java
index f6074b2..d770869 100644
--- a/text/src/main/java/java/text/MessageFormat.java
+++ b/text/src/main/java/java/text/MessageFormat.java
@@ -28,12 +28,9 @@
 import java.util.Locale;
 import java.util.Vector;
 
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
- * Produces concatenated
- * messages in language-neutral way. Use this class to construct messages
- * displayed for end users.
+ * Produces concatenated messages in language-neutral way. New code
+ * should probably use {@link java.util.Formatter} instead.
  * <p>
  * {@code MessageFormat} takes a set of objects, formats them and then
  * inserts the formatted strings into the pattern at the appropriate places.
@@ -42,8 +39,8 @@
  * {@code Format} classes in that you create a {@code MessageFormat}
  * object with one of its constructors (not with a {@code getInstance}
  * style factory method). The factory methods aren't necessary because
- * {@code MessageFormat} itself doesn't implement locale specific
- * behavior. Any locale specific behavior is defined by the pattern that you
+ * {@code MessageFormat} itself doesn't implement locale-specific
+ * behavior. Any locale-specific behavior is defined by the pattern that you
  * provide as well as the subformats used for inserted arguments.
  *
  * <h4><a name="patterns">Patterns and their interpretation</a></h4>
@@ -226,7 +223,7 @@
  *
  * <pre>
  * Object[] arguments = {
- *         new Integer(7), new Date(System.currentTimeMillis()),
+ *         Integer.valueOf(7), new Date(System.currentTimeMillis()),
  *         "a disturbance in the Force"};
  * String result = MessageFormat.format(
  *         "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
@@ -245,7 +242,7 @@
  * Example 2: <blockquote>
  *
  * <pre>
- * Object[] testArgs = {new Long(3), "MyDisk"};
+ * Object[] testArgs = {Long.valueOf(3), "MyDisk"};
  * MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0} file(s).");
  * System.out.println(form.format(testArgs));
  * <em>
@@ -269,7 +266,7 @@
  * String[] filepart = {"no files","one file","{0,number} files"};
  * ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
  * form.setFormatByArgumentIndex(0, fileform);
- * Object[] testArgs = {new Long(12373), "MyDisk"};
+ * Object[] testArgs = {Long.valueOf(12373), "MyDisk"};
  * System.out.println(form.format(testArgs));
  * <em>
  * Output (with different testArgs):
@@ -328,17 +325,13 @@
  * format instances for each thread. If multiple threads access a format
  * concurrently, it must be synchronized externally.
  *
- * @see java.util.Locale
- * @see Format
- * @see NumberFormat
- * @see DecimalFormat
- * @see ChoiceFormat
+ * @see java.util.Formatter
  */
 public class MessageFormat extends Format {
 
     private static final long serialVersionUID = 6479157306784022952L;
 
-    private Locale locale = Locale.getDefault();
+    private Locale locale;
 
     transient private String[] strings;
 
@@ -351,8 +344,7 @@
     transient private int maxArgumentIndex;
 
     /**
-     * Constructs a new {@code MessageFormat} using the specified pattern and
-     * the specified locale for formats.
+     * Constructs a new {@code MessageFormat} using the specified pattern and {@code locale}.
      * 
      * @param template
      *            the pattern.
@@ -368,7 +360,8 @@
 
     /**
      * Constructs a new {@code MessageFormat} using the specified pattern and
-     * the default locale for formats.
+     * the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
      * @param template
      *            the pattern.
@@ -376,7 +369,7 @@
      *            if the pattern cannot be parsed.
      */
     public MessageFormat(String template) {
-        applyPattern(template);
+        this(template, Locale.getDefault());
     }
 
     /**
@@ -401,25 +394,19 @@
                 int arg = 0;
                 int offset = position.getIndex();
                 if (offset >= length) {
-                    // text.19=Invalid argument number
-                    throw new IllegalArgumentException(Messages
-                            .getString("text.19")); //$NON-NLS-1$
+                    throw new IllegalArgumentException("Invalid argument number");
                 }
                 // Get argument number
                 char ch;
                 while ((ch = template.charAt(offset++)) != '}' && ch != ',') {
                     if (ch < '0' && ch > '9') {
-                        // text.19=Invalid argument number
-                        throw new IllegalArgumentException(Messages
-                            .getString("text.19")); //$NON-NLS-1$
+                        throw new IllegalArgumentException("Invalid argument number");
                     }
                     
                     arg = arg * 10 + (ch - '0');
                     
                     if (arg < 0 || offset >= length) {
-                        // text.19=Invalid argument number
-                        throw new IllegalArgumentException(Messages
-                            .getString("text.19")); //$NON-NLS-1$
+                        throw new IllegalArgumentException("Invalid argument number");
                     }
                 }
                 offset--;
@@ -621,21 +608,14 @@
 
     /**
      * Adds a new FieldContainer with MessageFormat.Field.ARGUMENT field,
-     * argnumber, begin and end index to the fields vector, or sets the
+     * argIndex, begin and end index to the fields vector, or sets the
      * position's begin and end index if it has MessageFormat.Field.ARGUMENT as
      * its field attribute.
-     * 
-     * @param begin
-     * @param end
-     * @param argnumber
-     * @param position
-     * @param fields
      */
-    private void handleArgumentField(int begin, int end, int argnumber,
+    private void handleArgumentField(int begin, int end, int argIndex,
             FieldPosition position, Vector<FieldContainer> fields) {
         if (fields != null) {
-            fields.add(new FieldContainer(begin, end, Field.ARGUMENT,
-                    new Integer(argnumber)));
+            fields.add(new FieldContainer(begin, end, Field.ARGUMENT, Integer.valueOf(argIndex)));
         } else {
             if (position != null
                     && position.getFieldAttribute() == Field.ARGUMENT
@@ -740,25 +720,24 @@
     /**
      * Formats the supplied objects using the specified message format pattern.
      * 
-     * @param template
-     *            the pattern to use for formatting.
-     * @param objects
-     *            the array of objects to format.
+     * @param format the format string (see {@link java.util.Formatter#format})
+     * @param args
+     *            the list of arguments passed to the formatter. If there are
+     *            more arguments than required by {@code format},
+     *            additional arguments are ignored.
      * @return the formatted result.
      * @throws IllegalArgumentException
      *            if the pattern cannot be parsed.
      */
-    public static String format(String template, Object... objects) {
-        if (objects != null) {
-            for (int i = 0; i < objects.length; i++) {
-                if (objects[i] == null) {
-                    objects[i] = "null";
+    public static String format(String format, Object... args) {
+        if (args != null) {
+            for (int i = 0; i < args.length; i++) {
+                if (args[i] == null) {
+                    args[i] = "null";
                 }
             }
         }
-        // BEGIN android-changed
-        return new MessageFormat(template).format(objects);
-        // END android-changed
+        return new MessageFormat(format).format(args);
     }
 
     /**
@@ -860,9 +839,7 @@
         ParsePosition position = new ParsePosition(0);
         Object[] result = parse(string, position);
         if (position.getIndex() == 0) {
-            // text.1B=MessageFormat.parseObject(String) parse failure
-            throw new ParseException(
-                    Messages.getString("text.1B"), position.getErrorIndex()); //$NON-NLS-1$
+            throw new ParseException("Parse failure", position.getErrorIndex());
         }
         return result;
     }
@@ -994,20 +971,17 @@
     private Format parseVariable(String string, ParsePosition position) {
         int length = string.length(), offset = position.getIndex();
         char ch;
-        if (offset >= length
-                || ((ch = string.charAt(offset++)) != '}' && ch != ',')) {
-            // text.15=Missing element format
-            throw new IllegalArgumentException(Messages.getString("text.15")); //$NON-NLS-1$
+        if (offset >= length || ((ch = string.charAt(offset++)) != '}' && ch != ',')) {
+            throw new IllegalArgumentException("Missing element format");
         }
         position.setIndex(offset);
         if (ch == '}') {
             return null;
         }
-        int type = match(string, position, false, new String[] { "time", //$NON-NLS-1$
-                "date", "number", "choice" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        int type = match(string, position, false,
+                new String[] { "time", "date", "number", "choice" });
         if (type == -1) {
-            // text.16=Unknown element format
-            throw new IllegalArgumentException(Messages.getString("text.16")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Unknown element format");
         }
         StringBuffer buffer = new StringBuffer();
         ch = string.charAt(position.getIndex() - 1);
@@ -1019,8 +993,8 @@
                             DateFormat.DEFAULT, locale) : DateFormat
                             .getTimeInstance(DateFormat.DEFAULT, locale);
                 }
-                int dateStyle = match(string, position, true, new String[] {
-                        "full", "long", "medium", "short" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                int dateStyle = match(string, position, true,
+                        new String[] { "full", "long", "medium", "short" });
                 if (dateStyle == -1) {
                     Format.upToWithQuotes(string, position, buffer, '}', '{');
                     return new SimpleDateFormat(buffer.toString(), locale);
@@ -1048,8 +1022,8 @@
                     return NumberFormat.getInstance(locale);
                     // END android-changed
                 }
-                int numberStyle = match(string, position, true, new String[] {
-                        "currency", "percent", "integer" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                int numberStyle = match(string, position, true,
+                        new String[] { "currency", "percent", "integer" });
                 if (numberStyle == -1) {
                     Format.upToWithQuotes(string, position, buffer, '}', '{');
                     return new DecimalFormat(buffer.toString(),
@@ -1144,15 +1118,15 @@
     }
 
     private String decodeDecimalFormat(StringBuffer buffer, Format format) {
-        buffer.append(",number"); //$NON-NLS-1$
+        buffer.append(",number");
         if (format.equals(NumberFormat.getNumberInstance(locale))) {
             // Empty block
         } else if (format.equals(NumberFormat.getIntegerInstance(locale))) {
-            buffer.append(",integer"); //$NON-NLS-1$
+            buffer.append(",integer");
         } else if (format.equals(NumberFormat.getCurrencyInstance(locale))) {
-            buffer.append(",currency"); //$NON-NLS-1$
+            buffer.append(",currency");
         } else if (format.equals(NumberFormat.getPercentInstance(locale))) {
-            buffer.append(",percent"); //$NON-NLS-1$
+            buffer.append(",percent");
         } else {
             buffer.append(',');
             return ((DecimalFormat) format).toPattern();
@@ -1161,32 +1135,31 @@
     }
 
     private String decodeSimpleDateFormat(StringBuffer buffer, Format format) {
-        if (format.equals(DateFormat
-                .getTimeInstance(DateFormat.DEFAULT, locale))) {
-            buffer.append(",time"); //$NON-NLS-1$
+        if (format.equals(DateFormat.getTimeInstance(DateFormat.DEFAULT, locale))) {
+            buffer.append(",time");
         } else if (format.equals(DateFormat.getDateInstance(DateFormat.DEFAULT,
                 locale))) {
-            buffer.append(",date"); //$NON-NLS-1$
+            buffer.append(",date");
         } else if (format.equals(DateFormat.getTimeInstance(DateFormat.SHORT,
                 locale))) {
-            buffer.append(",time,short"); //$NON-NLS-1$
+            buffer.append(",time,short");
         } else if (format.equals(DateFormat.getDateInstance(DateFormat.SHORT,
                 locale))) {
-            buffer.append(",date,short"); //$NON-NLS-1$
+            buffer.append(",date,short");
         } else if (format.equals(DateFormat.getTimeInstance(DateFormat.LONG,
                 locale))) {
-            buffer.append(",time,long"); //$NON-NLS-1$
+            buffer.append(",time,long");
         } else if (format.equals(DateFormat.getDateInstance(DateFormat.LONG,
                 locale))) {
-            buffer.append(",date,long"); //$NON-NLS-1$
+            buffer.append(",date,long");
         } else if (format.equals(DateFormat.getTimeInstance(DateFormat.FULL,
                 locale))) {
-            buffer.append(",time,full"); //$NON-NLS-1$
+            buffer.append(",time,full");
         } else if (format.equals(DateFormat.getDateInstance(DateFormat.FULL,
                 locale))) {
-            buffer.append(",date,full"); //$NON-NLS-1$
+            buffer.append(",date,full");
         } else {
-            buffer.append(",date,"); //$NON-NLS-1$
+            buffer.append(",date,");
             return ((SimpleDateFormat) format).toPattern();
         }
         return null;
@@ -1206,16 +1179,14 @@
             Format format = formats[i];
             String pattern = null;
             if (format instanceof ChoiceFormat) {
-                buffer.append(",choice,"); //$NON-NLS-1$
+                buffer.append(",choice,");
                 pattern = ((ChoiceFormat) format).toPattern();
             } else if (format instanceof DecimalFormat) {
                 pattern = decodeDecimalFormat(buffer, format);
             } else if (format instanceof SimpleDateFormat) {
                 pattern = decodeSimpleDateFormat(buffer, format);
             } else if (format != null) {
-                // text.17=Unknown format
-                throw new IllegalArgumentException(Messages
-                        .getString("text.17")); //$NON-NLS-1$
+                throw new IllegalArgumentException("Unknown format");
             }
             if (pattern != null) {
                 boolean quote = false;
@@ -1233,7 +1204,7 @@
                             if (count > 0) {
                                 count--;
                             } else {
-                                buffer.append("'}"); //$NON-NLS-1$
+                                buffer.append("'}");
                                 ch = '\'';
                             }
                         }
@@ -1264,20 +1235,20 @@
     }
 
     private static final ObjectStreamField[] serialPersistentFields = {
-            new ObjectStreamField("argumentNumbers", int[].class), //$NON-NLS-1$
-            new ObjectStreamField("formats", Format[].class), //$NON-NLS-1$
-            new ObjectStreamField("locale", Locale.class), //$NON-NLS-1$
-            new ObjectStreamField("maxOffset", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("offsets", int[].class), //$NON-NLS-1$
-            new ObjectStreamField("pattern", String.class), }; //$NON-NLS-1$
+            new ObjectStreamField("argumentNumbers", int[].class),
+            new ObjectStreamField("formats", Format[].class),
+            new ObjectStreamField("locale", Locale.class),
+            new ObjectStreamField("maxOffset", Integer.TYPE),
+            new ObjectStreamField("offsets", int[].class),
+            new ObjectStreamField("pattern", String.class), };
 
     private void writeObject(ObjectOutputStream stream) throws IOException {
         ObjectOutputStream.PutField fields = stream.putFields();
-        fields.put("argumentNumbers", argumentNumbers); //$NON-NLS-1$
+        fields.put("argumentNumbers", argumentNumbers);
         Format[] compatibleFormats = formats;
-        fields.put("formats", compatibleFormats); //$NON-NLS-1$
-        fields.put("locale", locale); //$NON-NLS-1$
-        fields.put("maxOffset", maxOffset); //$NON-NLS-1$
+        fields.put("formats", compatibleFormats);
+        fields.put("locale", locale);
+        fields.put("maxOffset", maxOffset);
         int offset = 0;
         int offsetsLength = maxOffset + 1;
         int[] offsets = new int[offsetsLength];
@@ -1290,20 +1261,20 @@
         if (maxOffset + 1 < strings.length) {
             pattern.append(strings[maxOffset + 1]);
         }
-        fields.put("offsets", offsets); //$NON-NLS-1$
-        fields.put("pattern", pattern.toString()); //$NON-NLS-1$
+        fields.put("offsets", offsets);
+        fields.put("pattern", pattern.toString());
         stream.writeFields();
     }
 
     private void readObject(ObjectInputStream stream) throws IOException,
             ClassNotFoundException {
         ObjectInputStream.GetField fields = stream.readFields();
-        argumentNumbers = (int[]) fields.get("argumentNumbers", null); //$NON-NLS-1$
-        formats = (Format[]) fields.get("formats", null); //$NON-NLS-1$
-        locale = (Locale) fields.get("locale", null); //$NON-NLS-1$
-        maxOffset = fields.get("maxOffset", 0); //$NON-NLS-1$
-        int[] offsets = (int[]) fields.get("offsets", null); //$NON-NLS-1$
-        String pattern = (String) fields.get("pattern", null); //$NON-NLS-1$
+        argumentNumbers = (int[]) fields.get("argumentNumbers", null);
+        formats = (Format[]) fields.get("formats", null);
+        locale = (Locale) fields.get("locale", null);
+        maxOffset = fields.get("maxOffset", 0);
+        int[] offsets = (int[]) fields.get("offsets", null);
+        String pattern = (String) fields.get("pattern", null);
         int length;
         if (maxOffset < 0) {
             length = pattern.length() > 0 ? 1 : 0;
@@ -1338,7 +1309,7 @@
         /**
          * This constant stands for the message argument.
          */
-        public static final Field ARGUMENT = new Field("message argument field"); //$NON-NLS-1$
+        public static final Field ARGUMENT = new Field("message argument field");
 
         /**
          * Constructs a new instance of {@code MessageFormat.Field} with the
@@ -1362,20 +1333,10 @@
         @Override
         protected Object readResolve() throws InvalidObjectException {
             String name = this.getName();
-            if (name == null) {
-                // text.18=Not a valid {0}, subclass should override
-                // readResolve()
-                throw new InvalidObjectException(Messages.getString(
-                        "text.18", "MessageFormat.Field")); //$NON-NLS-1$ //$NON-NLS-2$
-            }
-
-            if (name.equals(ARGUMENT.getName())) {
+            if (name != null && name.equals(ARGUMENT.getName())) {
                 return ARGUMENT;
             }
-            // text.18=Not a valid {0}, subclass should override readResolve()
-            throw new InvalidObjectException(Messages.getString(
-                    "text.18", "MessageFormat.Field")); //$NON-NLS-1$ //$NON-NLS-2$
+            throw new InvalidObjectException("Not a valid MessageFormat.Field, subclass should override readResolve()");
         }
     }
-
 }
diff --git a/text/src/main/java/java/text/NumberFormat.java b/text/src/main/java/java/text/NumberFormat.java
index 0ad6ac4..a4cccc0 100644
--- a/text/src/main/java/java/text/NumberFormat.java
+++ b/text/src/main/java/java/text/NumberFormat.java
@@ -15,24 +15,20 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// changed from ICU to resource bundles
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.util.LocaleData;
+import com.ibm.icu4jni.util.ICU;
 import java.io.IOException;
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamField;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.util.Currency;
 import java.util.Locale;
 
-import com.ibm.icu4jni.util.LocaleData;
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * The abstract base class for all number formats. This class provides the
  * interface for formatting and parsing numbers. {@code NumberFormat} also
@@ -164,9 +160,9 @@
             maximumFractionDigits = 3, minimumFractionDigits = 0;
 
     /**
-     * Constructs a new instance of {@code NumberFormat}.
+     * Used by subclasses. This was public in Java 5.
      */
-    public NumberFormat() {
+    protected NumberFormat() {
     }
 
     /**
@@ -314,12 +310,11 @@
     }
 
     /**
-     * Gets the list of installed locales which support {@code NumberFormat}.
-     * 
-     * @return an array of locales.
+     * Returns an array of locales for which custom {@code NumberFormat} instances
+     * are available.
      */
     public static Locale[] getAvailableLocales() {
-        return Locale.getAvailableLocales();
+        return ICU.getAvailableNumberFormatLocales();
     }
 
     /**
@@ -340,7 +335,8 @@
 
     /**
      * Returns a {@code NumberFormat} for formatting and parsing currency values
-     * for the default locale.
+     * for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
      * @return a {@code NumberFormat} for handling currency values.
      */
@@ -357,15 +353,13 @@
      * @return a {@code NumberFormat} for handling currency values.
      */
     public static NumberFormat getCurrencyInstance(Locale locale) {
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        return getInstance(localeData.currencyPattern, locale);
-        // END android-changed
+        return getInstance(LocaleData.get(locale).currencyPattern, locale);
     }
 
     /**
      * Returns a {@code NumberFormat} for formatting and parsing integers for the
-     * default locale.
+     * user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
      * @return a {@code NumberFormat} for handling integers.
      */
@@ -382,12 +376,9 @@
      * @return a {@code NumberFormat} for handling integers.
      */
     public static NumberFormat getIntegerInstance(Locale locale) {
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        NumberFormat result = getInstance(localeData.integerPattern, locale);
+        NumberFormat result = getInstance(LocaleData.get(locale).integerPattern, locale);
         result.setParseIntegerOnly(true);
         return result;
-        // END android-changed
     }
 
     /**
@@ -462,7 +453,8 @@
 
     /**
      * Returns a {@code NumberFormat} for formatting and parsing numbers for the
-     * default locale.
+     * user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
      * @return a {@code NumberFormat} for handling {@code Number} objects.
      */
@@ -479,15 +471,13 @@
      * @return a {@code NumberFormat} for handling {@code Number} objects.
      */
     public static NumberFormat getNumberInstance(Locale locale) {
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        return getInstance(localeData.numberPattern, locale);
-        // END android-changed
+        return getInstance(LocaleData.get(locale).numberPattern, locale);
     }
 
     /**
      * Returns a {@code NumberFormat} for formatting and parsing percentage
-     * values for the default locale.
+     * values for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
      * @return a {@code NumberFormat} for handling percentage values.
      */
@@ -504,10 +494,7 @@
      * @return a {@code NumberFormat} for handling percentage values.
      */
     public static NumberFormat getPercentInstance(Locale locale) {
-        // BEGIN android-changed
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
-        return getInstance(localeData.percentPattern, locale);
-        // END android-changed
+        return getInstance(LocaleData.get(locale).percentPattern, locale);
     }
 
     @Override
@@ -553,9 +540,7 @@
         ParsePosition pos = new ParsePosition(0);
         Number number = parse(string, pos);
         if (pos.getIndex() == 0) {
-            // text.1D=Unparseable number: {0}
-            throw new ParseException(
-                    Messages.getString("text.1D", string), pos.getErrorIndex()); //$NON-NLS-1$
+            throw new ParseException("Unparseable number" + string, pos.getErrorIndex());
         }
         return number;
     }
@@ -583,10 +568,8 @@
     @Override
     public final Object parseObject(String string, ParsePosition position) {
         if (position == null) {
-            // text.1A=position is null
-            throw new NullPointerException(Messages.getString("text.1A")); //$NON-NLS-1$
+            throw new NullPointerException("position is null");
         }
-
         try {
             return parse(string, position);
         } catch (Exception e) {
@@ -695,75 +678,64 @@
     }
 
     private static final ObjectStreamField[] serialPersistentFields = {
-            new ObjectStreamField("groupingUsed", Boolean.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("maxFractionDigits", Byte.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("maximumFractionDigits", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("maximumIntegerDigits", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("maxIntegerDigits", Byte.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("minFractionDigits", Byte.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("minimumFractionDigits", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("minimumIntegerDigits", Integer.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("minIntegerDigits", Byte.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("parseIntegerOnly", Boolean.TYPE), //$NON-NLS-1$
-            new ObjectStreamField("serialVersionOnStream", Integer.TYPE), }; //$NON-NLS-1$
+            new ObjectStreamField("groupingUsed", Boolean.TYPE),
+            new ObjectStreamField("maxFractionDigits", Byte.TYPE),
+            new ObjectStreamField("maximumFractionDigits", Integer.TYPE),
+            new ObjectStreamField("maximumIntegerDigits", Integer.TYPE),
+            new ObjectStreamField("maxIntegerDigits", Byte.TYPE),
+            new ObjectStreamField("minFractionDigits", Byte.TYPE),
+            new ObjectStreamField("minimumFractionDigits", Integer.TYPE),
+            new ObjectStreamField("minimumIntegerDigits", Integer.TYPE),
+            new ObjectStreamField("minIntegerDigits", Byte.TYPE),
+            new ObjectStreamField("parseIntegerOnly", Boolean.TYPE),
+            new ObjectStreamField("serialVersionOnStream", Integer.TYPE), };
 
     private void writeObject(ObjectOutputStream stream) throws IOException {
         ObjectOutputStream.PutField fields = stream.putFields();
-        fields.put("groupingUsed", groupingUsed); //$NON-NLS-1$
-        fields
-                .put(
-                        "maxFractionDigits", //$NON-NLS-1$
+        fields.put("groupingUsed", groupingUsed);
+        fields.put("maxFractionDigits",
                         maximumFractionDigits < Byte.MAX_VALUE ? (byte) maximumFractionDigits
                                 : Byte.MAX_VALUE);
-        fields.put("maximumFractionDigits", maximumFractionDigits); //$NON-NLS-1$
-        fields.put("maximumIntegerDigits", maximumIntegerDigits); //$NON-NLS-1$
-        fields
-                .put(
-                        "maxIntegerDigits", //$NON-NLS-1$
+        fields.put("maximumFractionDigits", maximumFractionDigits);
+        fields.put("maximumIntegerDigits", maximumIntegerDigits);
+        fields.put("maxIntegerDigits",
                         maximumIntegerDigits < Byte.MAX_VALUE ? (byte) maximumIntegerDigits
                                 : Byte.MAX_VALUE);
-        fields
-                .put(
-                        "minFractionDigits", //$NON-NLS-1$
+        fields.put("minFractionDigits",
                         minimumFractionDigits < Byte.MAX_VALUE ? (byte) minimumFractionDigits
                                 : Byte.MAX_VALUE);
-        fields.put("minimumFractionDigits", minimumFractionDigits); //$NON-NLS-1$
-        fields.put("minimumIntegerDigits", minimumIntegerDigits); //$NON-NLS-1$
-        fields
-                .put(
-                        "minIntegerDigits", //$NON-NLS-1$
-                        minimumIntegerDigits < Byte.MAX_VALUE ? (byte) minimumIntegerDigits
-                                : Byte.MAX_VALUE);
-        fields.put("parseIntegerOnly", parseIntegerOnly); //$NON-NLS-1$
-        fields.put("serialVersionOnStream", 1); //$NON-NLS-1$
+        fields.put("minimumFractionDigits", minimumFractionDigits); 
+        fields.put("minimumIntegerDigits", minimumIntegerDigits);
+        fields.put("minIntegerDigits",
+                minimumIntegerDigits < Byte.MAX_VALUE ? (byte) minimumIntegerDigits : Byte.MAX_VALUE);
+        fields.put("parseIntegerOnly", parseIntegerOnly);
+        fields.put("serialVersionOnStream", 1);
         stream.writeFields();
     }
 
     private void readObject(ObjectInputStream stream) throws IOException,
             ClassNotFoundException {
         ObjectInputStream.GetField fields = stream.readFields();
-        groupingUsed = fields.get("groupingUsed", true); //$NON-NLS-1$
-        parseIntegerOnly = fields.get("parseIntegerOnly", false); //$NON-NLS-1$
-        if (fields.get("serialVersionOnStream", 0) == 0) { //$NON-NLS-1$
-            maximumFractionDigits = fields.get("maxFractionDigits", (byte) 3); //$NON-NLS-1$
-            maximumIntegerDigits = fields.get("maxIntegerDigits", (byte) 40); //$NON-NLS-1$
-            minimumFractionDigits = fields.get("minFractionDigits", (byte) 0); //$NON-NLS-1$
-            minimumIntegerDigits = fields.get("minIntegerDigits", (byte) 1); //$NON-NLS-1$
+        groupingUsed = fields.get("groupingUsed", true);
+        parseIntegerOnly = fields.get("parseIntegerOnly", false);
+        if (fields.get("serialVersionOnStream", 0) == 0) {
+            maximumFractionDigits = fields.get("maxFractionDigits", (byte) 3);
+            maximumIntegerDigits = fields.get("maxIntegerDigits", (byte) 40);
+            minimumFractionDigits = fields.get("minFractionDigits", (byte) 0);
+            minimumIntegerDigits = fields.get("minIntegerDigits", (byte) 1);
         } else {
-            maximumFractionDigits = fields.get("maximumFractionDigits", 3); //$NON-NLS-1$
-            maximumIntegerDigits = fields.get("maximumIntegerDigits", 40); //$NON-NLS-1$
-            minimumFractionDigits = fields.get("minimumFractionDigits", 0); //$NON-NLS-1$
-            minimumIntegerDigits = fields.get("minimumIntegerDigits", 1); //$NON-NLS-1$
+            maximumFractionDigits = fields.get("maximumFractionDigits", 3);
+            maximumIntegerDigits = fields.get("maximumIntegerDigits", 40);
+            minimumFractionDigits = fields.get("minimumFractionDigits", 0);
+            minimumIntegerDigits = fields.get("minimumIntegerDigits", 1);
         }
         if (minimumIntegerDigits > maximumIntegerDigits
                 || minimumFractionDigits > maximumFractionDigits) {
-            // text.00=min digits greater than max digits
-            throw new InvalidObjectException(Messages.getString("text.00")); //$NON-NLS-1$
+            throw new InvalidObjectException("min digits greater than max digits");
         }
         if (minimumIntegerDigits < 0 || maximumIntegerDigits < 0
                 || minimumFractionDigits < 0 || maximumFractionDigits < 0) {
-            // text.01=min or max digits negative
-            throw new InvalidObjectException(Messages.getString("text.01")); //$NON-NLS-1$
+            throw new InvalidObjectException("min or max digits negative");
         }
     }
 
@@ -783,59 +755,57 @@
         /**
          * This constant stands for the number sign.
          */
-        public static final Field SIGN = new Field("sign"); //$NON-NLS-1$
+        public static final Field SIGN = new Field("sign");
 
         /**
          * This constant stands for the integer part of the number.
          */
-        public static final Field INTEGER = new Field("integer"); //$NON-NLS-1$
+        public static final Field INTEGER = new Field("integer");
 
         /**
          * This constant stands for the fraction part of the number.
          */
-        public static final Field FRACTION = new Field("fraction"); //$NON-NLS-1$
+        public static final Field FRACTION = new Field("fraction");
 
         /**
          * This constant stands for the exponent part of the number.
          */
-        public static final Field EXPONENT = new Field("exponent"); //$NON-NLS-1$
+        public static final Field EXPONENT = new Field("exponent");
 
         /**
          * This constant stands for the exponent sign symbol.
          */
-        public static final Field EXPONENT_SIGN = new Field("exponent sign"); //$NON-NLS-1$
+        public static final Field EXPONENT_SIGN = new Field("exponent sign");
 
         /**
          * This constant stands for the exponent symbol.
          */
-        public static final Field EXPONENT_SYMBOL = new Field("exponent symbol"); //$NON-NLS-1$
+        public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
 
         /**
          * This constant stands for the decimal separator.
          */
-        public static final Field DECIMAL_SEPARATOR = new Field(
-                "decimal separator"); //$NON-NLS-1$
+        public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
 
         /**
          * This constant stands for the grouping separator.
          */
-        public static final Field GROUPING_SEPARATOR = new Field(
-                "grouping separator"); //$NON-NLS-1$
+        public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
 
         /**
          * This constant stands for the percent symbol.
          */
-        public static final Field PERCENT = new Field("percent"); //$NON-NLS-1$
+        public static final Field PERCENT = new Field("percent");
 
         /**
          * This constant stands for the permille symbol.
          */
-        public static final Field PERMILLE = new Field("per mille"); //$NON-NLS-1$
+        public static final Field PERMILLE = new Field("per mille");
 
         /**
          * This constant stands for the currency symbol.
          */
-        public static final Field CURRENCY = new Field("currency"); //$NON-NLS-1$
+        public static final Field CURRENCY = new Field("currency");
 
         /**
          * Constructs a new instance of {@code NumberFormat.Field} with the
@@ -891,9 +861,29 @@
             if (this.equals(SIGN)) {
                 return SIGN;
             }
-            // text.02=Unknown attribute
-            throw new InvalidObjectException(Messages.getString("text.02")); //$NON-NLS-1$
+            throw new InvalidObjectException("Unknown attribute");
         }
     }
 
+    /**
+     * Returns the {@code RoundingMode} used by this {@code NumberFormat}. The default
+     * implementation in {@code NumberFormat} throws {@code UnsupportedOperationException}.
+     * Subclasses for which a rounding mode is meaningful are expected to override this method.
+     * @since 1.6
+     * @hide
+     */
+    public RoundingMode getRoundingMode() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Sets the {@code RoundingMode} used by this {@code NumberFormat}. The default
+     * implementation in {@code NumberFormat} throws {@code UnsupportedOperationException}.
+     * Subclasses for which a rounding mode is meaningful are expected to override this method.
+     * @since 1.6
+     * @hide
+     */
+    public void setRoundingMode(RoundingMode roundingMode) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/text/src/main/java/java/text/RuleBasedBreakIterator.java b/text/src/main/java/java/text/RuleBasedBreakIterator.java
index 2ca6f9b..2537f0c 100644
--- a/text/src/main/java/java/text/RuleBasedBreakIterator.java
+++ b/text/src/main/java/java/text/RuleBasedBreakIterator.java
@@ -15,23 +15,22 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.text.NativeBreakIterator;
+
 /*
- * Default implementation of BreakIterator, wrap
- * com.ibm.icu4jni.text.RuleBasedBreakIterator
- * 
+ * Default implementation of BreakIterator. Wraps com.ibm.icu4jni.text.NativeBreakIterator.
+ * We need this because BreakIterator.isBoundary and BreakIterator.preceding are non-abstract,
+ * and we don't have Java implementations of those methods (other than the current ones, which
+ * forward to the wrapped NativeBreakIterator).
  */
 class RuleBasedBreakIterator extends BreakIterator {
 
     /*
-     * Wrapping construction
+     * Wrapping constructor.
      */
-    RuleBasedBreakIterator(com.ibm.icu4jni.text.BreakIterator iterator) {
+    RuleBasedBreakIterator(NativeBreakIterator iterator) {
         super(iterator);
     }
 
@@ -201,9 +200,7 @@
     @Override
     public Object clone() {
         RuleBasedBreakIterator cloned = (RuleBasedBreakIterator) super.clone();
-        cloned.wrapped = (com.ibm.icu4jni.text.RuleBasedBreakIterator) wrapped
-                .clone();
+        cloned.wrapped = (NativeBreakIterator) wrapped.clone();
         return cloned;
     }
-
 }
diff --git a/text/src/main/java/java/text/RuleBasedCollator.java b/text/src/main/java/java/text/RuleBasedCollator.java
index 1a3bab7..0955f89 100644
--- a/text/src/main/java/java/text/RuleBasedCollator.java
+++ b/text/src/main/java/java/text/RuleBasedCollator.java
@@ -15,14 +15,8 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// The icu implementation used was changed from icu4j to icu4jni.
-// END android-note
-
 package java.text;
 
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * A concrete implementation class for {@code Collation}.
  * <p>
@@ -34,50 +28,50 @@
  * <li> All non-mentioned Unicode characters are at the end of the collation
  * order.</li>
  * <li> If a character is not located in the {@code RuleBasedCollator}, the
- * default Unicode Collation Algorithm (UCA) rulebased table is automatically
+ * default Unicode Collation Algorithm (UCA) rule-based table is automatically
  * searched as a backup.</li>
  * </ol>
  * <p>
  * The collation table is composed of a list of collation rules, where each rule
  * is of three forms:
  * <blockquote>
- *
  * <pre>
- * <modifier>
- * <relation> <text-argument>
- * <reset> <text-argument>
+ * &lt;modifier&gt;
+ * &lt;relation&gt; &lt;text-argument&gt;
+ * &lt;reset&gt; &lt;text-argument&gt;
  * </pre>
- *
  * </blockquote>
  * <p>
  * The rule elements are defined as follows:
  * <ul type="disc">
- * <li><strong>Text-Argument</strong>: A text-argument is any sequence of
- * characters, excluding special characters (that is, common whitespace
- * characters [0009-000D, 0020] and rule syntax characters [0021-002F,
- * 003A-0040, 005B-0060, 007B-007E]). If those characters are desired, you can
- * put them in single quotes (for example, use '&' for ampersand). Note that
- * unquoted white space characters are ignored; for example, {@code b c} is
- * treated as {@code bc}.</li>
  * <li><strong>Modifier</strong>: There is a single modifier which is used to
- * specify that all accents (secondary differences) are backwards.
- * <p>
- * '@' : Indicates that accents are sorted backwards, as in French.
+ * specify that all accents (secondary differences) are backwards:
+ * <ul type=square>
+ * <li>'@' : Indicates that accents are sorted backwards, as in French.
+ * </ul>
  * </li>
  * <li><strong>Relation</strong>: The relations are the following:
  * <ul type=square>
- * <li>'<' : Greater, as a letter difference (primary)
+ * <li>'&lt;' : Greater, as a letter difference (primary)
  * <li>';' : Greater, as an accent difference (secondary)
  * <li>',' : Greater, as a case difference (tertiary)
  * <li>'=' : Equal
  * </ul>
  * </li>
+ * <li><strong>Text-Argument</strong>: A text-argument is any sequence of
+ * characters, excluding special characters (that is, common whitespace
+ * characters [0009-000D, 0020] and rule syntax characters [0021-002F,
+ * 003A-0040, 005B-0060, 007B-007E]). If those characters are desired, you can
+ * put them in single quotes (for example, use '&amp;' for ampersand). Note that
+ * unquoted white space characters are ignored; for example, {@code b c} is
+ * treated as {@code bc}.</li>
  * <li><strong>Reset</strong>: There is a single reset which is used primarily
  * for contractions and expansions, but which can also be used to add a
- * modification at the end of a set of rules.
- * <p>
- * '&' : Indicates that the next rule follows the position to where the reset
+ * modification at the end of a set of rules:
+ * <ul type=square>
+ * <li>'&amp;' : Indicates that the next rule follows the position to where the reset
  * text-argument would be sorted.
+ * </ul>
  * </li>
  * </ul>
  * <p>
@@ -164,7 +158,6 @@
  *
  * <pre>
  * String Simple = "< a < b < c < d";
- *
  * RuleBasedCollator mySimple = new RuleBasedCollator(Simple);
  * </pre>
  *
@@ -179,7 +172,6 @@
  *         + "< s,S< t,T< u,U< v,V< w,W< x,X< y,Y< z,Z"
  *         + "< \u00E5=a\u030A,\u00C5=A\u030A"
  *         + ";aa,AA< \u00E6,\u00C6< \u00F8,\u00D8";
- *
  * RuleBasedCollator myNorwegian = new RuleBasedCollator(Norwegian);
  * </pre>
  *
@@ -277,15 +269,14 @@
      * the result of a former {@link #getRules()} call.
      * <p>
      * Note that the {@code rules} are actually interpreted as a delta to the
-     * standard Unicode Collation Algorithm (UCA). Hence, an empty {@code rules}
-     * string results in the default UCA rules being applied. This differs
+     * standard Unicode Collation Algorithm (UCA). This differs
      * slightly from other implementations which work with full {@code rules}
      * specifications and may result in different behavior.
      *
      * @param rules
      *            the collation rules.
      * @throws NullPointerException
-     *             if {@code rules} is {@code null}.
+     *             if {@code rules == null}.
      * @throws ParseException
      *             if {@code rules} contains rules with invalid collation rule
      *             syntax.
@@ -294,26 +285,19 @@
         if (rules == null) {
             throw new NullPointerException();
         }
-        // BEGIN android-removed
-        // if (rules.length() == 0) {
-        //     // text.06=Build rules empty
-        //     throw new ParseException(Messages.getString("text.06"), 0); //$NON-NLS-1$
-        // }
-        // END andriod-removed
-
+        if (rules.isEmpty()) {
+            throw new ParseException("empty rules", 0);
+        }
         try {
             this.icuColl = new com.ibm.icu4jni.text.RuleBasedCollator(rules);
-            // BEGIN android-added
-            this.icuColl.setDecomposition(
-                    com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION);
-            // END android-added
+            this.icuColl.setDecomposition(com.ibm.icu4jni.text.Collator.CANONICAL_DECOMPOSITION);
         } catch (Exception e) {
             if (e instanceof ParseException) {
                 throw (ParseException) e;
             }
             /*
              * -1 means it's not a ParseException. Maybe IOException thrown when
-             * an error occured while reading internal data.
+             * an error occurred while reading internal data.
              */
             throw new ParseException(e.getMessage(), -1);
         }
@@ -328,8 +312,7 @@
      *            the source character iterator.
      * @return a {@code CollationElementIterator} for {@code source}.
      */
-    public CollationElementIterator getCollationElementIterator(
-            CharacterIterator source) {
+    public CollationElementIterator getCollationElementIterator(CharacterIterator source) {
         if (source == null) {
             throw new NullPointerException();
         }
@@ -407,8 +390,7 @@
     @Override
     public int compare(String source, String target) {
         if (source == null || target == null) {
-            // text.08=one of arguments is null
-            throw new NullPointerException(Messages.getString("text.08")); //$NON-NLS-1$
+            throw new NullPointerException();
         }
         return this.icuColl.compare(source, target);
     }
@@ -422,18 +404,12 @@
      */
     @Override
     public CollationKey getCollationKey(String source) {
-        com.ibm.icu4jni.text.CollationKey icuKey = this.icuColl
-                .getCollationKey(source);
-        if (icuKey == null) {
-            return null;
-        }
-        return new CollationKey(source, icuKey);
+        return icuColl.getCollationKey(source);
     }
 
     @Override
     public int hashCode() {
-        return ((com.ibm.icu4jni.text.RuleBasedCollator) this.icuColl).getRules()
-                .hashCode();
+        return ((com.ibm.icu4jni.text.RuleBasedCollator) this.icuColl).getRules().hashCode();
     }
 
     /**
diff --git a/text/src/main/java/java/text/SimpleDateFormat.java b/text/src/main/java/java/text/SimpleDateFormat.java
index 20fff63..cb114a3 100644
--- a/text/src/main/java/java/text/SimpleDateFormat.java
+++ b/text/src/main/java/java/text/SimpleDateFormat.java
@@ -15,12 +15,10 @@
  * limitations under the License.
  */
 
-// BEGIN android-note
-// changed from ICU to resource bundles and Java parsing/formatting
-// END android-note
-
 package java.text;
 
+import com.ibm.icu4jni.util.LocaleData;
+import com.ibm.icu4jni.util.ICU;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -29,16 +27,10 @@
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.Locale;
-// BEGIN android-added
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
-// END android-added
 import java.util.Vector;
 
-import com.ibm.icu4jni.util.LocaleData;
-import com.ibm.icu4jni.util.Resources;
-import org.apache.harmony.text.internal.nls.Messages;
-
 /**
  * A concrete class for formatting and parsing dates in a locale-sensitive
  * manner. It allows for formatting (date to text), parsing (text to date) and
@@ -316,9 +308,7 @@
 
     private static final long serialVersionUID = 4774881970558875024L;
 
-    // BEGIN android-changed
-    static final String patternChars = "GyMdkHmsSEDFwWahKzZ"; //$NON-NLS-1$
-    // END android-changed
+    static final String patternChars = "GyMdkHmsSEDFwWahKzZ";
 
     private String pattern;
 
@@ -328,28 +318,22 @@
 
     private Date defaultCenturyStart;
 
-    // BEGIN android-removed
-    // private transient String tzId;
-    //
-    // private transient com.ibm.icu.text.SimpleDateFormat icuFormat;
-    // END android-removed
-
     /**
      * Constructs a new {@code SimpleDateFormat} for formatting and parsing
-     * dates and times in the {@code SHORT} style for the default locale.
+     * dates and times in the {@code SHORT} style for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      */
     public SimpleDateFormat() {
         this(Locale.getDefault());
-        // BEGIN android-changed
-        pattern = defaultPattern();
-        // END android-changed
-        formatData = new DateFormatSymbols(Locale.getDefault());
+        this.pattern = defaultPattern();
+        this.formatData = new DateFormatSymbols(Locale.getDefault());
     }
 
     /**
      * Constructs a new {@code SimpleDateFormat} using the specified
      * non-localized pattern and the {@code DateFormatSymbols} and {@code
-     * Calendar} for the default locale.
+     * Calendar} for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
      * 
      * @param pattern
      *            the pattern.
@@ -375,9 +359,7 @@
     private void validateFormat(char format) {
         int index = patternChars.indexOf(format);
         if (index == -1) {
-            // text.03=Unknown pattern character - '{0}'
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.03", format)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Unknown pattern character '" + format + "'");
         }
     }
 
@@ -436,17 +418,16 @@
         }
 
         if (quote) {
-            // text.04=Unterminated quote {0}
-            throw new IllegalArgumentException(Messages.getString("text.04")); //$NON-NLS-1$
+            throw new IllegalArgumentException("Unterminated quote");
         }
-
     }
     
     /**
      * Constructs a new {@code SimpleDateFormat} using the specified
      * non-localized pattern and {@code DateFormatSymbols} and the {@code
-     * Calendar} for the default locale.
-     *
+     * Calendar} for the user's default locale.
+     * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>".
+     * 
      * @param template
      *            the pattern.
      * @param value
@@ -459,27 +440,10 @@
     public SimpleDateFormat(String template, DateFormatSymbols value) {
         this(Locale.getDefault());
         validatePattern(template);
-        // BEGIN android-removed
-        // icuFormat = new com.ibm.icu.text.SimpleDateFormat(template, Locale.getDefault());
-        // icuFormat.setTimeZone(com.ibm.icu.util.TimeZone.getTimeZone(tzId));
-        // END android-removed
         pattern = template;
         formatData = (DateFormatSymbols) value.clone();
     }
 
-    // BEGIN android-removed
-    // private void copySymbols(DateFormatSymbols value, com.ibm.icu.text.DateFormatSymbols icuSymbols) {
-    //     icuSymbols.setAmPmStrings(value.getAmPmStrings());
-    //     icuSymbols.setEras(value.getEras());
-    //     icuSymbols.setLocalPatternChars(value.getLocalPatternChars());
-    //     icuSymbols.setMonths(value.getMonths());
-    //     icuSymbols.setShortMonths(value.getShortMonths());
-    //     icuSymbols.setShortWeekdays(value.getShortWeekdays());
-    //     icuSymbols.setWeekdays(value.getWeekdays());
-    //     icuSymbols.setZoneStrings(value.getZoneStrings());
-    // }
-    // END android-removed
-
     /**
      * Constructs a new {@code SimpleDateFormat} using the specified
      * non-localized pattern and the {@code DateFormatSymbols} and {@code
@@ -507,11 +471,6 @@
         // END android-changed
     }
 
-    // BEGIN android-removed
-    // SimpleDateFormat(Locale locale, com.ibm.icu.text.SimpleDateFormat icuFormat){
-    // }
-    // END android-removed
-    
     private SimpleDateFormat(Locale locale) {
         numberFormat = NumberFormat.getInstance(locale);
         numberFormat.setParseIntegerOnly(true);
@@ -606,18 +565,13 @@
         SimpleDateFormat clone = (SimpleDateFormat) super.clone();
         clone.formatData = (DateFormatSymbols) formatData.clone();
         clone.defaultCenturyStart = new Date(defaultCenturyStart.getTime());
-        // BEGIN android-removed
-        // clone.tzId = tzId;
-        // END android-removed
         return clone;
     }
 
-    // BEGIN android-added
     private static String defaultPattern() {
-        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(Locale.getDefault());
+        LocaleData localeData = LocaleData.get(Locale.getDefault());
         return localeData.getDateFormat(SHORT) + " " + localeData.getTimeFormat(SHORT);
     }
-    // END android-added
 
     /**
      * Compares the specified object with this simple date format and indicates
@@ -780,9 +734,7 @@
         int field = -1;
         int index = patternChars.indexOf(format);
         if (index == -1) {
-            // text.03=Unknown pattern character - '{0}'
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.03", format)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Unknown pattern character '" + format + "'");
         }
 
         int beginPosition = buffer.length();
@@ -934,7 +886,7 @@
             }
             // We can't call TimeZone.getDisplayName() because it would not use
             // the custom DateFormatSymbols of this SimpleDateFormat.
-            String custom = Resources.lookupDisplayTimeZone(formatData.zoneStrings, tz.getID(), daylight, style);
+            String custom = ICU.lookupDisplayTimeZone(formatData.zoneStrings, tz.getID(), daylight, style);
             if (custom != null) {
                 buffer.append(custom);
                 return;
@@ -1048,9 +1000,7 @@
     private int parse(String string, int offset, char format, int count) {
         int index = patternChars.indexOf(format);
         if (index == -1) {
-            // text.03=Unknown pattern character - '{0}'
-            throw new IllegalArgumentException(Messages.getString(
-                    "text.03", format)); //$NON-NLS-1$
+            throw new IllegalArgumentException("Unknown pattern character '" + format + "'");
         }
         int field = -1;
         int absolute = 0;
@@ -1332,7 +1282,7 @@
         // BEGIN android-changed
         String[][] zones = formatData.internalZoneStrings();
         // END android-changed
-        boolean foundGMT = string.regionMatches(offset, "GMT", 0, 3); //$NON-NLS-1$
+        boolean foundGMT = string.regionMatches(offset, "GMT", 0, 3);
         if (foundGMT) {
             offset += 3;
         }
@@ -1361,11 +1311,11 @@
             if (sign == '-') {
                 raw = -raw;
             }
-            calendar.setTimeZone(new SimpleTimeZone(raw, "")); //$NON-NLS-1$
+            calendar.setTimeZone(new SimpleTimeZone(raw, ""));
             return position.getIndex();
         }
         if (foundGMT) {
-            calendar.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
+            calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
             return offset;
         }
         for (String[] element : zones) {
@@ -1380,7 +1330,7 @@
                     if (j >= 3 && zone.useDaylightTime()) {
                         raw += 3600000;
                     }
-                    calendar.setTimeZone(new SimpleTimeZone(raw, "")); //$NON-NLS-1$
+                    calendar.setTimeZone(new SimpleTimeZone(raw, ""));
                     return offset + element[j].length();
                 }
             }
@@ -1445,32 +1395,32 @@
     }
 
     private static final ObjectStreamField[] serialPersistentFields = {
-            new ObjectStreamField("defaultCenturyStart", Date.class), //$NON-NLS-1$
-            new ObjectStreamField("formatData", DateFormatSymbols.class), //$NON-NLS-1$
-            new ObjectStreamField("pattern", String.class), //$NON-NLS-1$
-            new ObjectStreamField("serialVersionOnStream", Integer.TYPE), }; //$NON-NLS-1$
+            new ObjectStreamField("defaultCenturyStart", Date.class),
+            new ObjectStreamField("formatData", DateFormatSymbols.class),
+            new ObjectStreamField("pattern", String.class),
+            new ObjectStreamField("serialVersionOnStream", Integer.TYPE), };
 
     private void writeObject(ObjectOutputStream stream) throws IOException {
         ObjectOutputStream.PutField fields = stream.putFields();
-        fields.put("defaultCenturyStart", defaultCenturyStart); //$NON-NLS-1$
-        fields.put("formatData", formatData); //$NON-NLS-1$
-        fields.put("pattern", pattern); //$NON-NLS-1$
-        fields.put("serialVersionOnStream", 1); //$NON-NLS-1$
+        fields.put("defaultCenturyStart", defaultCenturyStart);
+        fields.put("formatData", formatData);
+        fields.put("pattern", pattern);
+        fields.put("serialVersionOnStream", 1);
         stream.writeFields();
     }
 
     private void readObject(ObjectInputStream stream) throws IOException,
             ClassNotFoundException {
         ObjectInputStream.GetField fields = stream.readFields();
-        int version = fields.get("serialVersionOnStream", 0); //$NON-NLS-1$
+        int version = fields.get("serialVersionOnStream", 0);
         Date date;
         if (version > 0) {
-            date = (Date) fields.get("defaultCenturyStart", new Date()); //$NON-NLS-1$
+            date = (Date) fields.get("defaultCenturyStart", new Date());
         } else {
             date = new Date();
         }
         set2DigitYearStart(date);
-        formatData = (DateFormatSymbols) fields.get("formatData", null); //$NON-NLS-1$
-        pattern = (String) fields.get("pattern", ""); //$NON-NLS-1$ //$NON-NLS-2$
+        formatData = (DateFormatSymbols) fields.get("formatData", null);
+        pattern = (String) fields.get("pattern", "");
     }
 }
diff --git a/text/src/main/java/java/text/package.html b/text/src/main/java/java/text/package.html
index 2bcd8f9..b3f387a 100644
--- a/text/src/main/java/java/text/package.html
+++ b/text/src/main/java/java/text/package.html
@@ -1,17 +1,16 @@
 <html>
   <body>
   <p>
-    The java.text package allows to uncouple the text in an application 
-    from natural languages.
+    The java.text package offers internationalization and localization
+    facilities.
   </p>
   <p>
     By using the classes in this package, it is possible to write the
-    application in an unlocalized way. The benefit of this is that a new 
+    application in an internationalized way. The benefit of this is that a new 
     localization can be provided at any time without having to change the 
     code. Support for localization is given for numbers, messages, dates and 
     other characteristics of a language like the directionality, sorting order
     or enumeration of characters, words or lines.
   </p>
-  @since Android 1.0
 </body>
 </html>
diff --git a/text/src/main/java/java/text/spi/BreakIteratorProvider.java b/text/src/main/java/java/text/spi/BreakIteratorProvider.java
new file mode 100644
index 0000000..e2f85d7
--- /dev/null
+++ b/text/src/main/java/java/text/spi/BreakIteratorProvider.java
@@ -0,0 +1,90 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text.spi;
+
+import java.text.BreakIterator;
+import java.util.Locale;
+import java.util.spi.LocaleServiceProvider;
+
+/**
+ * This abstract class should be extended by service providers that provide
+ * instances of {@code BreakIterator}.
+ * <p>Note that Android does not currently support user-supplied locale service providers.
+ * @since 1.6
+ * @hide
+ */
+public abstract class BreakIteratorProvider extends LocaleServiceProvider {
+    /**
+     * Default constructor, for use by subclasses.
+     */
+    protected BreakIteratorProvider() {
+        // Do nothing.
+    }
+
+    /**
+     * Returns an instance of {@code BreakIterator} for word breaks in the
+     * given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code BreakIterator}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract BreakIterator getWordInstance(Locale locale);
+
+    /**
+     * Returns an instance of {@code BreakIterator} for line breaks in the
+     * given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code BreakIterator}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract BreakIterator getLineInstance(Locale locale);
+
+    /**
+     * Returns an instance of {@code BreakIterator} for character breaks in the
+     * given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code BreakIterator}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract BreakIterator getCharacterInstance(Locale locale);
+
+    /**
+     * Returns an instance of {@code BreakIterator} for sentence breaks in the
+     * given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code BreakIterator}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract BreakIterator getSentenceInstance(Locale locale);
+}
diff --git a/text/src/main/java/java/text/spi/CollatorProvider.java b/text/src/main/java/java/text/spi/CollatorProvider.java
new file mode 100644
index 0000000..8d234a1
--- /dev/null
+++ b/text/src/main/java/java/text/spi/CollatorProvider.java
@@ -0,0 +1,50 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text.spi;
+
+import java.text.Collator;
+import java.util.Locale;
+import java.util.spi.LocaleServiceProvider;
+
+/**
+ * This abstract class should be extended by service providers which provide
+ * instances of {@code Collator}.
+ * <p>Note that Android does not currently support user-supplied locale service providers.
+ * @since 1.6
+ * @hide
+ */
+public abstract class CollatorProvider extends LocaleServiceProvider {
+    /**
+     * Default constructor, for use by subclasses.
+     */
+    protected CollatorProvider() {
+        // Do nothing.
+    }
+
+    /**
+     * Returns an instance of {@code Collator} for the given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code Collator}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract Collator getInstance(Locale locale);
+}
diff --git a/text/src/main/java/java/text/spi/DateFormatProvider.java b/text/src/main/java/java/text/spi/DateFormatProvider.java
new file mode 100644
index 0000000..ba17cb4
--- /dev/null
+++ b/text/src/main/java/java/text/spi/DateFormatProvider.java
@@ -0,0 +1,81 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text.spi;
+
+import java.text.DateFormat;
+import java.util.Locale;
+import java.util.spi.LocaleServiceProvider;
+
+/**
+ * This abstract class should be extended by service providers that provide
+ * instances of {@code DateFormat}.
+ * <p>Note that Android does not currently support user-supplied locale service providers.
+ * @since 1.6
+ * @hide
+ */
+public abstract class DateFormatProvider extends LocaleServiceProvider {
+    /**
+     * Default constructor, for use by subclasses.
+     */
+    protected DateFormatProvider() {
+        // Do nothing.
+    }
+
+    /**
+     * Returns an instance of {@code DateFormat} that formats times
+     * in the given style for the given locale.
+     * 
+     * @param style the given time formatting style.
+     * @param locale the locale
+     * @return an instance of {@code DateFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract DateFormat getTimeInstance(int style, Locale locale);
+
+    /**
+     * Returns an instance of {@code DateFormat} that formats dates
+     * in the given style for the given locale.
+     * 
+     * @param style the given date formatting style.
+     * @param locale the locale
+     * @return an instance of {@code DateFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract DateFormat getDateInstance(int style, Locale locale);
+
+    /**
+     * Returns an instance of {@code DateFormat} that formats dates and times
+     * in the given style for the given locale.
+     * 
+     * @param dateStyle the given date formatting style.
+     * @param timeStyle the given time formatting style.
+     * @param locale the locale
+     * @return an instance of {@code DateFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale);
+}
diff --git a/text/src/main/java/java/text/spi/DateFormatSymbolsProvider.java b/text/src/main/java/java/text/spi/DateFormatSymbolsProvider.java
new file mode 100644
index 0000000..8467f05
--- /dev/null
+++ b/text/src/main/java/java/text/spi/DateFormatSymbolsProvider.java
@@ -0,0 +1,50 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text.spi;
+
+import java.text.DateFormatSymbols;
+import java.util.Locale;
+import java.util.spi.LocaleServiceProvider;
+
+/**
+ * This abstract class should be extended by service providers that provide
+ * instances of {@code DateFormatSymbols}.
+ * <p>Note that Android does not currently support user-supplied locale service providers.
+ * @since 1.6
+ * @hide
+ */
+public abstract class DateFormatSymbolsProvider extends LocaleServiceProvider {
+    /**
+     * Default constructor, for use by subclasses.
+     */
+    protected DateFormatSymbolsProvider() {
+        // Do nothing.
+    }
+
+    /**
+     * Returns an instance of {@code DateFormatSymbols} for the given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code DateFormatSymbols}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract DateFormatSymbols getInstance(Locale locale);
+}
diff --git a/text/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java b/text/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java
new file mode 100644
index 0000000..81dbd4a
--- /dev/null
+++ b/text/src/main/java/java/text/spi/DecimalFormatSymbolsProvider.java
@@ -0,0 +1,51 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text.spi;
+
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.util.spi.LocaleServiceProvider;
+
+/**
+ * This abstract class should be extended by service providers that provide
+ * instances of {@code DecimalFormatSymbols}.
+ * <p>Note that Android does not currently support user-supplied locale service providers.
+ * @since 1.6
+ * @hide
+ */
+public abstract class DecimalFormatSymbolsProvider extends LocaleServiceProvider {
+    /**
+     * Default constructor, for use by subclasses.
+     */
+    protected DecimalFormatSymbolsProvider() {
+        // Do nothing.
+    }
+
+    /**
+     * Returns an instance of {@code DecimalFormatSymbols} for the given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code DecimalFormatSymbols}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract DecimalFormatSymbols getInstance(Locale locale);
+
+}
diff --git a/text/src/main/java/java/text/spi/NumberFormatProvider.java b/text/src/main/java/java/text/spi/NumberFormatProvider.java
new file mode 100644
index 0000000..f6d43e0
--- /dev/null
+++ b/text/src/main/java/java/text/spi/NumberFormatProvider.java
@@ -0,0 +1,93 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.text.spi;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+import java.util.spi.LocaleServiceProvider;
+
+/**
+ * This abstract class should be extended by service providers that provide
+ * {@code NumberFormat} instances.
+ * <p>Note that Android does not currently support user-supplied locale service providers.
+ * @since 1.6
+ * @hide
+ */
+public abstract class NumberFormatProvider extends LocaleServiceProvider {
+    /**
+     * Default constructor, for use by subclasses.
+     */
+    protected NumberFormatProvider() {
+        // Do nothing.
+    }
+
+    /**
+     * Returns an instance of {@code NumberFormat} that formats
+     * monetary values for the given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code NumberFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract NumberFormat getCurrencyInstance(Locale locale);
+
+    /**
+     * Returns an instance of {@code NumberFormat} that formats
+     * integer values for the given locale. The returned {@code NumberFormat}
+     * is configured to round floating point numbers to the nearest integer
+     * using half-even rounding mode for formatting, and to parse only the
+     * integer part of an input string.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code NumberFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract NumberFormat getIntegerInstance(Locale locale);
+
+    /**
+     * Returns an instance of {@code NumberFormat} class for general
+     * use in the given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code NumberFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract NumberFormat getNumberInstance(Locale locale);
+
+    /**
+     * Returns an instance of {@code NumberFormat} class that formats
+     * percentage values for the given locale.
+     * 
+     * @param locale the locale
+     * @return an instance of {@code NumberFormat}
+     * @throws NullPointerException if {@code locale == null}
+     * @throws IllegalArgumentException
+     *             if locale isn't one of the locales returned from
+     *             getAvailableLocales().
+     */
+    public abstract NumberFormat getPercentInstance(Locale locale);
+}
diff --git a/text/src/main/java/org/apache/harmony/text/internal/nls/Messages.java b/text/src/main/java/org/apache/harmony/text/internal/nls/Messages.java
deleted file mode 100644
index 95a8ad6..0000000
--- a/text/src/main/java/org/apache/harmony/text/internal/nls/Messages.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.text.internal.nls;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.text.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.text.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties b/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties
deleted file mode 100644
index b80cde2..0000000
--- a/text/src/main/java/org/apache/harmony/text/internal/nls/messages.properties
+++ /dev/null
@@ -1,49 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
-text.00=min digits greater than max digits
-text.01=min or max digits negative
-text.02=Unknown attribute
-text.03=Unknown pattern character - '{0}'
-text.04=Unterminated quote
-text.05=Invalid pattern char {0} in {1}
-text.07=Unmatched braces in the pattern
-text.06=Build rules empty
-text.08=one of arguments is null
-text.09=The deserialized date is invalid
-text.0A=Invalid substring range
-text.0B=Cannot add attributes to empty string
-text.0C=cannot resolve subclasses
-text.0E=Illegal date style: {0}
-text.0F=Illegal time style: {0}
-text.0D=Negative textStart value {0}
-text.10=Negative embStart value {0}
-text.11=Negative paragraph length {0}
-text.12=Invalid ranges (start={0}, limit={1}, length={2})
-text.13=Invalid ranges (levels={0}, levelStart={1}, objects={2}, objectStart={3}, count={4})
-text.14=paragraph is null
-text.19=Invalid argument number
-text.15=Missing element format
-text.16=Unknown element format
-text.17=Unknown format
-text.18=Not a valid {0}, subclass should override readResolve()
-text.19=Unparseable date: {0}
-text.1A=position is null
-text.1B=MessageFormat.parseObject(String) parse failure
-text.1C=Format.parseObject(String) parse failure
-text.1D=Unparseable number: {0}
-text.1E=Offset out of bounds \: {0}
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/AllTests.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/AllTests.java
index c968b38..d5c539e 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/AllTests.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/AllTests.java
@@ -21,14 +21,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "Suite org.apache.harmony.text.tests.java.text");
+        TestSuite suite = new TestSuite("Suite org.apache.harmony.text.tests.java.text");
         //$JUnit-BEGIN$
         suite.addTestSuite(AnnotationTest.class);
         suite.addTestSuite(AttributedCharacterIteratorAttributeTest.class);
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java
index deef841..be618c7 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/BidiTest.java
@@ -1778,8 +1778,9 @@
         method = "createLineBidi",
         args = {int.class, int.class}
     )
-    @KnownFailure("Is this a failure or just a different behaviour of ICU?")
     public void testCreateLineBidi_AndroidFailure() {
+        // This is a difference between ICU4C and the RI. ICU4C insists that 'limit' is strictly
+        // greater than 'start'. We have to paper over this in our Java code.
         Bidi bidi = new Bidi("str", Bidi.DIRECTION_RIGHT_TO_LEFT);
         bidi.createLineBidi(2, 2);
     }
@@ -1983,7 +1984,6 @@
         method = "getRunLimit",
         args = {int.class}
     )
-    @KnownFailure("Doesn't verify any int value between 0 and getRunCount().")
     public void testGetRunLimit() {
         bd = new Bidi("text", Bidi.DIRECTION_LEFT_TO_RIGHT);
         try {
@@ -1992,8 +1992,9 @@
             // Expected for illegal run limit
             return;
         }
-
-        fail("Expected IllegalArgumentException to be thrown for invalid run limit");
+        // BEGIN android-changed: the RI doesn't throw.
+        // fail("Expected IllegalArgumentException to be thrown for invalid run limit");
+        // END android-changed
     }
 
     @TestTargetNew(
@@ -2061,7 +2062,6 @@
         method = "Bidi",
         args = {java.text.AttributedCharacterIterator.class}
     )
-    @KnownFailure("Doesn't verify any int value between 0 and getRunCount().")
     public void testBidiConstructor_Iterator() {
         AttributedString paragraph = new AttributedString("text");
         bd = new Bidi(paragraph.getIterator());
@@ -2071,7 +2071,8 @@
             // Expected for illegal run limit
             return;
         }
-
-        fail("Expected IllegalArgumentException to be thrown for invalid run limit");
+        // BEGIN android-changed: the RI doesn't throw.
+        // fail("Expected IllegalArgumentException to be thrown for invalid run limit");
+        // END android-changed
     }
 }
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/BreakIteratorTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/BreakIteratorTest.java
index f3b0b31..b64bafb 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/BreakIteratorTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/BreakIteratorTest.java
@@ -127,23 +127,6 @@
         assertEquals(iterator.first(), iterator.current());
     }
 
-    /**
-     * @tests java.text.BreakIterator#BreakIterator() Test of method
-     *        java.text.BreakIterator#BreakIterator().
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "BreakIterator",
-        args = {}
-    )
-    public void testConstructor() {
-        try {
-            new MockBreakIterator();
-        } catch (Exception e) {
-            fail("Unexpected exception " + e.toString());
-        }
-    }
     @TestTargetNew(
         level = TestLevel.COMPLETE,
         notes = "",
@@ -513,185 +496,6 @@
     }
 
     /**
-     * @tests java.text.BreakIterator.getShort(byte[], int)
-     * 
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getShort",
-        args = {byte[].class, int.class}
-    )
-    public void test_getShort() {
-        try {
-            MockBreakIterator.publicGetShort(null, 0);
-            fail("should throw NPE.");
-        } catch (NullPointerException e) {
-        }
-        try {
-            MockBreakIterator.publicGetShort(null, -1);
-            fail("should throw NPE.");
-        } catch (NullPointerException e) {
-        }
-        try {
-            MockBreakIterator.publicGetShort(new byte[] { 0, 0, 0, 1, 1 }, -1);
-            fail("should throw ArrayIndexOutOfBoundsException.");
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-        try {
-            MockBreakIterator.publicGetShort(new byte[] { 0, 0 }, 1);
-            fail("should throw ArrayIndexOutOfBoundsException.");
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-        assertEquals(0, MockBreakIterator
-                .publicGetShort(new byte[] { 0, 0 }, 0));
-        assertEquals(1, MockBreakIterator
-                .publicGetShort(new byte[] { 0, 1 }, 0));
-        assertEquals(-1, MockBreakIterator.publicGetShort(new byte[] {
-                (byte) 0xff, (byte) 0xff }, 0));
-        assertEquals(1, MockBreakIterator.publicGetShort(new byte[] { 1, 0, 1,
-                0 }, 1));
-        assertEquals(1, MockBreakIterator.publicGetShort(new byte[] { 0, 0, 1,
-                0 }, 1));
-        assertEquals(1, MockBreakIterator.publicGetShort(new byte[] { 0, 0, 1,
-                1 }, 1));
-        assertEquals(257, MockBreakIterator.publicGetShort(
-                new byte[] { 0, 1, 1 }, 1));
-
-        // regression for Harmony-944
-        try {
-            MockBreakIterator.publicGetShort(new byte[] { 0, 0 },
-                    Integer.MAX_VALUE);
-            fail("should throw ArrayIndexOutOfBoundsException");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // expected
-        }
-
-        try {
-            MockBreakIterator.publicGetShort(new byte[] { 0, 0 },
-                    Short.MAX_VALUE);
-            fail("should throw ArrayIndexOutOfBoundsException");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // expected
-        }
-    }
-
-    /**
-     * @tests java.text.BreakIterator.getInt(byte[], int)
-     * 
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInt",
-        args = {byte[].class, int.class}
-    )
-    public void test_getInt() {
-        try {
-            MockBreakIterator.publicGetInt(null, 0);
-            fail("should throw NPE.");
-        } catch (NullPointerException e) {
-        }
-        try {
-            MockBreakIterator.publicGetInt(null, -1);
-            fail("should throw NPE.");
-        } catch (NullPointerException e) {
-        }
-        try {
-            MockBreakIterator.publicGetInt(new byte[] { 0, 0, 0, 1, 1 }, -1);
-            fail("should throw ArrayIndexOutOfBoundsException.");
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-        try {
-            MockBreakIterator.publicGetInt(new byte[] { 0, 0, 0, 0 }, 1);
-            fail("should throw ArrayIndexOutOfBoundsException.");
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-        assertEquals(0, MockBreakIterator.publicGetInt(
-                new byte[] { 0, 0, 0, 0 }, 0));
-        assertEquals(1, MockBreakIterator.publicGetInt(
-                new byte[] { 0, 0, 0, 1 }, 0));
-        assertEquals(-1, MockBreakIterator.publicGetInt(new byte[] {
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }, 0));
-        assertEquals(1, MockBreakIterator.publicGetInt(new byte[] { 1, 0, 0, 0,
-                1, 0 }, 1));
-        assertEquals(1, MockBreakIterator.publicGetInt(new byte[] { 0, 0, 0, 0,
-                1, 0 }, 1));
-        assertEquals(1, MockBreakIterator.publicGetInt(new byte[] { 0, 0, 0, 0,
-                1, 1 }, 1));
-        assertEquals(257, MockBreakIterator.publicGetInt(new byte[] { 0, 0, 0,
-                1, 1 }, 1));
-
-        // regression for Harmony-944
-        try {
-            MockBreakIterator.publicGetInt(new byte[] { 0, 0 },
-                    Integer.MAX_VALUE);
-            fail("should throw ArrayIndexOutOfBoundsException");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // expected
-        }
-    }
-
-    /**
-     * @tests java.text.BreakIterator.getLong(byte[], int)
-     * 
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getLong",
-        args = {byte[].class, int.class}
-    )
-    public void test_getLong() {
-        try {
-            MockBreakIterator.publicGetLong(null, 0);
-            fail("should throw NPE.");
-        } catch (NullPointerException e) {
-        }
-        try {
-            MockBreakIterator.publicGetLong(null, -1);
-            fail("should throw NPE.");
-        } catch (NullPointerException e) {
-        }
-        try {
-            MockBreakIterator.publicGetLong(
-                    new byte[] { 0, 0, 0, 0, 0, 0, 1, 1 }, -1);
-            fail("should throw ArrayIndexOutOfBoundsException.");
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-        try {
-            MockBreakIterator.publicGetLong(
-                    new byte[] { 0, 0, 0, 0, 0, 0, 1, 1 }, 1);
-            fail("should throw ArrayIndexOutOfBoundsException.");
-        } catch (ArrayIndexOutOfBoundsException e) {
-        }
-        assertEquals(0, MockBreakIterator.publicGetLong(new byte[] { 0, 0, 0,
-                0, 0, 0, 0, 0 }, 0));
-        assertEquals(1, MockBreakIterator.publicGetLong(new byte[] { 0, 0, 0,
-                0, 0, 0, 0, 1 }, 0));
-        assertEquals(-1, MockBreakIterator.publicGetLong(new byte[] {
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-                (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }, 0));
-        assertEquals(1, MockBreakIterator.publicGetLong(new byte[] { 1, 0, 0,
-                0, 0, 0, 0, 0, 1, 0 }, 1));
-        assertEquals(1, MockBreakIterator.publicGetLong(new byte[] { 0, 0, 0,
-                0, 0, 0, 0, 0, 1, 0 }, 1));
-        assertEquals(1, MockBreakIterator.publicGetLong(new byte[] { 0, 0, 0,
-                0, 0, 0, 0, 0, 1, 1 }, 1));
-        assertEquals(257, MockBreakIterator.publicGetLong(new byte[] { 0, 0, 0,
-                0, 0, 0, 0, 1, 1 }, 1));
-
-        // regression for Harmony-944
-        try {
-            MockBreakIterator.publicGetLong(new byte[] { 0, 1 },
-                    Integer.MAX_VALUE);
-            fail("should throw ArrayIndexOutOfBoundsException");
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // expected
-        }
-    }
-
-    /**
      * @tests java.text.BreakIterator#getCharacterInstance(Locale)
      */
     @TestTargetNew(
@@ -747,57 +551,4 @@
         } catch (NullPointerException e) {
         }
     }
-
-    private static class MockBreakIterator extends BreakIterator {
-        public MockBreakIterator() {
-            super();
-        }
-
-        public static int publicGetInt(byte[] buf, int offset) {
-            return BreakIterator.getInt(buf, offset);
-        }
-
-        public static long publicGetLong(byte[] buf, int offset) {
-            return BreakIterator.getLong(buf, offset);
-        }
-
-        public static short publicGetShort(byte[] buf, int offset) {
-            return BreakIterator.getShort(buf, offset);
-        }
-
-        public int current() {
-            return 0;
-        }
-
-        public int first() {
-            return 0;
-        }
-
-        public int following(int offset) {
-            return 0;
-        }
-
-        public CharacterIterator getText() {
-            return null;
-        }
-
-        public int last() {
-            return 0;
-        }
-
-        public int next() {
-            return 0;
-        }
-
-        public int next(int n) {
-            return 0;
-        }
-
-        public int previous() {
-            return 0;
-        }
-
-        public void setText(CharacterIterator newText) {
-        }
-    }
 }
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java
index 161a2c5..92225d7 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/CollatorTest.java
@@ -16,501 +16,261 @@
  */
 package org.apache.harmony.text.tests.java.text;
 
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
-import java.io.UnsupportedEncodingException;
-import java.text.CollationKey;
 import java.text.Collator;
 import java.text.ParseException;
 import java.text.RuleBasedCollator;
 import java.util.Locale;
 
-@TestTargetClass(Collator.class) 
 public class CollatorTest extends junit.framework.TestCase {
 
-    /**
-     * @tests java.text.Collator#clone()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clone",
-        args = {}
-    )
-    public void test_clone() {
-        Collator c = Collator.getInstance(Locale.GERMAN);
-        Collator c2 = (Collator) c.clone();
-        assertTrue("Clones answered false to equals", c.equals(c2));
-        assertTrue("Clones were equivalent", c != c2);
-    }
+	/**
+	 * @tests java.text.Collator#clone()
+	 */
+	public void test_clone() {
+		Collator c = Collator.getInstance(Locale.GERMAN);
+		Collator c2 = (Collator) c.clone();
+		assertTrue("Clones answered false to equals", c.equals(c2));
+		assertTrue("Clones were equivalent", c != c2);
+	}
 
-    /**
-     * @tests java.text.Collator#compare(java.lang.Object, java.lang.Object)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "compare",
-            args = {java.lang.Object.class, java.lang.Object.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setStrength",
-            args = {int.class}
-        )
-    })
-    public void test_compareLjava_lang_ObjectLjava_lang_Object() {
-        Collator c = Collator.getInstance(Locale.FRENCH);
-        Object o, o2;
+	/**
+	 * @tests java.text.Collator#compare(java.lang.Object, java.lang.Object)
+	 */
+	public void test_compareLjava_lang_ObjectLjava_lang_Object() {
+		Collator c = Collator.getInstance(Locale.FRENCH);
+		Object o, o2;
 
-        c.setStrength(Collator.IDENTICAL);
-        o = "E";
-        o2 = "F";
-        assertTrue("a) Failed on primary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "\u00e9";
-        assertTrue("a) Failed on secondary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "E";
-        assertTrue("a) Failed on tertiary difference", c.compare(o, o2) < 0);
-        o = "\u0001";
-        o2 = "\u0002";
-        assertTrue("a) Failed on identical", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "e";
-        assertEquals("a) Failed on equivalence", 0, c.compare(o, o2));
-        assertTrue("a) Failed on primary expansion",
-                c.compare("\u01db", "v") < 0);
+		c.setStrength(Collator.IDENTICAL);
+		o = "E";
+		o2 = "F";
+		assertTrue("a) Failed on primary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "\u00e9";
+		assertTrue("a) Failed on secondary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "E";
+		assertTrue("a) Failed on tertiary difference", c.compare(o, o2) < 0);
+		o = "\u0001";
+		o2 = "\u0002";
+		assertTrue("a) Failed on identical", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "e";
+		assertEquals("a) Failed on equivalence", 0, c.compare(o, o2));
+		assertTrue("a) Failed on primary expansion",
+				c.compare("\u01db", "v") < 0);
 
-        c.setStrength(Collator.TERTIARY);
-        o = "E";
-        o2 = "F";
-        assertTrue("b) Failed on primary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "\u00e9";
-        assertTrue("b) Failed on secondary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "E";
-        assertTrue("b) Failed on tertiary difference", c.compare(o, o2) < 0);
-        o = "\u0001";
-        o2 = "\u0002";
-        assertEquals("b) Failed on identical", 0, c.compare(o, o2));
-        o = "e";
-        o2 = "e";
-        assertEquals("b) Failed on equivalence", 0, c.compare(o, o2));
+		c.setStrength(Collator.TERTIARY);
+		o = "E";
+		o2 = "F";
+		assertTrue("b) Failed on primary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "\u00e9";
+		assertTrue("b) Failed on secondary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "E";
+		assertTrue("b) Failed on tertiary difference", c.compare(o, o2) < 0);
+		o = "\u0001";
+		o2 = "\u0002";
+		assertEquals("b) Failed on identical", 0, c.compare(o, o2));
+		o = "e";
+		o2 = "e";
+		assertEquals("b) Failed on equivalence", 0, c.compare(o, o2));
 
-        c.setStrength(Collator.SECONDARY);
-        o = "E";
-        o2 = "F";
-        assertTrue("c) Failed on primary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "\u00e9";
-        assertTrue("c) Failed on secondary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "E";
-        assertEquals("c) Failed on tertiary difference", 0, c.compare(o, o2));
-        o = "\u0001";
-        o2 = "\u0002";
-        assertEquals("c) Failed on identical", 0, c.compare(o, o2));
-        o = "e";
-        o2 = "e";
-        assertEquals("c) Failed on equivalence", 0, c.compare(o, o2));
+		c.setStrength(Collator.SECONDARY);
+		o = "E";
+		o2 = "F";
+		assertTrue("c) Failed on primary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "\u00e9";
+		assertTrue("c) Failed on secondary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "E";
+		assertEquals("c) Failed on tertiary difference", 0, c.compare(o, o2));
+		o = "\u0001";
+		o2 = "\u0002";
+		assertEquals("c) Failed on identical", 0, c.compare(o, o2));
+		o = "e";
+		o2 = "e";
+		assertEquals("c) Failed on equivalence", 0, c.compare(o, o2));
 
-        c.setStrength(Collator.PRIMARY);
-        o = "E";
-        o2 = "F";
-        assertTrue("d) Failed on primary difference", c.compare(o, o2) < 0);
-        o = "e";
-        o2 = "\u00e9";
-        assertEquals("d) Failed on secondary difference", 0, c.compare(o, o2));
-        o = "e";
-        o2 = "E";
-        assertEquals("d) Failed on tertiary difference", 0, c.compare(o, o2));
-        o = "\u0001";
-        o2 = "\u0002";
-        assertEquals("d) Failed on identical", 0, c.compare(o, o2));
-        o = "e";
-        o2 = "e";
-        assertEquals("d) Failed on equivalence", 0, c.compare(o, o2));
+		c.setStrength(Collator.PRIMARY);
+		o = "E";
+		o2 = "F";
+		assertTrue("d) Failed on primary difference", c.compare(o, o2) < 0);
+		o = "e";
+		o2 = "\u00e9";
+		assertEquals("d) Failed on secondary difference", 0, c.compare(o, o2));
+		o = "e";
+		o2 = "E";
+		assertEquals("d) Failed on tertiary difference", 0, c.compare(o, o2));
+		o = "\u0001";
+		o2 = "\u0002";
+		assertEquals("d) Failed on identical", 0, c.compare(o, o2));
+		o = "e";
+		o2 = "e";
+		assertEquals("d) Failed on equivalence", 0, c.compare(o, o2));
 
-        try {
-            c.compare("e", new StringBuffer("Blah"));
-        } catch (ClassCastException e) {
-            // correct
-            return;
-        }
-        fail("Failed to throw ClassCastException");
-    }
+		try {
+			c.compare("e", new StringBuffer("Blah"));
+		} catch (ClassCastException e) {
+			// correct
+			return;
+		}
+		fail("Failed to throw ClassCastException");
+	}
 
-    /**
-     * @tests java.text.Collator#equals(java.lang.Object)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
-    public void test_equalsLjava_lang_Object() {
-        Collator c = Collator.getInstance(Locale.ENGLISH);
-        Collator c2 = (Collator) c.clone();
-        assertTrue("Cloned collators not equal", c.equals(c2));
-        c2.setStrength(Collator.SECONDARY);
-        assertTrue("Collators with different strengths equal", !c.equals(c2));
-    }
+	/**
+	 * @tests java.text.Collator#equals(java.lang.Object)
+	 */
+	public void test_equalsLjava_lang_Object() {
+		Collator c = Collator.getInstance(Locale.ENGLISH);
+		Collator c2 = (Collator) c.clone();
+		assertTrue("Cloned collators not equal", c.equals(c2));
+		c2.setStrength(Collator.SECONDARY);
+		assertTrue("Collators with different strengths equal", !c.equals(c2));
+	}
 
-    /**
-     * @tests java.text.Collator#equals(java.lang.String, java.lang.String)
-     */
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "equals",
-            args = {java.lang.String.class, java.lang.String.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setStrength",
-            args = {int.class}
-        )
-    })
-    public void test_equalsLjava_lang_StringLjava_lang_String() {
-        Collator c = Collator.getInstance(Locale.FRENCH);
+	/**
+	 * @tests java.text.Collator#equals(java.lang.String, java.lang.String)
+	 */
+	public void test_equalsLjava_lang_StringLjava_lang_String() {
+		Collator c = Collator.getInstance(Locale.FRENCH);
 
-        c.setStrength(Collator.IDENTICAL);
-        assertTrue("a) Failed on primary difference", !c.equals("E", "F"));
-        assertTrue("a) Failed on secondary difference", !c
-                .equals("e", "\u00e9"));
-        assertTrue("a) Failed on tertiary difference", !c.equals("e", "E"));
-        assertTrue("a) Failed on identical", !c.equals("\u0001", "\u0002"));
-        assertTrue("a) Failed on equivalence", c.equals("e", "e"));
+		c.setStrength(Collator.IDENTICAL);
+		assertTrue("a) Failed on primary difference", !c.equals("E", "F"));
+		assertTrue("a) Failed on secondary difference", !c
+				.equals("e", "\u00e9"));
+		assertTrue("a) Failed on tertiary difference", !c.equals("e", "E"));
+		assertTrue("a) Failed on identical", !c.equals("\u0001", "\u0002"));
+		assertTrue("a) Failed on equivalence", c.equals("e", "e"));
 
-        c.setStrength(Collator.TERTIARY);
-        assertTrue("b) Failed on primary difference", !c.equals("E", "F"));
-        assertTrue("b) Failed on secondary difference", !c
-                .equals("e", "\u00e9"));
-        assertTrue("b) Failed on tertiary difference", !c.equals("e", "E"));
-        assertTrue("b) Failed on identical", c.equals("\u0001", "\u0002"));
-        assertTrue("b) Failed on equivalence", c.equals("e", "e"));
+		c.setStrength(Collator.TERTIARY);
+		assertTrue("b) Failed on primary difference", !c.equals("E", "F"));
+		assertTrue("b) Failed on secondary difference", !c
+				.equals("e", "\u00e9"));
+		assertTrue("b) Failed on tertiary difference", !c.equals("e", "E"));
+		assertTrue("b) Failed on identical", c.equals("\u0001", "\u0002"));
+		assertTrue("b) Failed on equivalence", c.equals("e", "e"));
 
-        c.setStrength(Collator.SECONDARY);
-        assertTrue("c) Failed on primary difference", !c.equals("E", "F"));
-        assertTrue("c) Failed on secondary difference", !c
-                .equals("e", "\u00e9"));
-        assertTrue("c) Failed on tertiary difference", c.equals("e", "E"));
-        assertTrue("c) Failed on identical", c.equals("\u0001", "\u0002"));
-        assertTrue("c) Failed on equivalence", c.equals("e", "e"));
+		c.setStrength(Collator.SECONDARY);
+		assertTrue("c) Failed on primary difference", !c.equals("E", "F"));
+		assertTrue("c) Failed on secondary difference", !c
+				.equals("e", "\u00e9"));
+		assertTrue("c) Failed on tertiary difference", c.equals("e", "E"));
+		assertTrue("c) Failed on identical", c.equals("\u0001", "\u0002"));
+		assertTrue("c) Failed on equivalence", c.equals("e", "e"));
 
-        c.setStrength(Collator.PRIMARY);
-        assertTrue("d) Failed on primary difference", !c.equals("E", "F"));
-        assertTrue("d) Failed on secondary difference", c.equals("e", "\u00e9"));
-        assertTrue("d) Failed on tertiary difference", c.equals("e", "E"));
-        assertTrue("d) Failed on identical", c.equals("\u0001", "\u0002"));
-        assertTrue("d) Failed on equivalence", c.equals("e", "e"));
-    }
+		c.setStrength(Collator.PRIMARY);
+		assertTrue("d) Failed on primary difference", !c.equals("E", "F"));
+		assertTrue("d) Failed on secondary difference", c.equals("e", "\u00e9"));
+		assertTrue("d) Failed on tertiary difference", c.equals("e", "E"));
+		assertTrue("d) Failed on identical", c.equals("\u0001", "\u0002"));
+		assertTrue("d) Failed on equivalence", c.equals("e", "e"));
+	}
 
-    /**
-     * @tests java.text.Collator#getAvailableLocales()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getAvailableLocales",
-        args = {}
-    )
-    public void test_getAvailableLocales() {
-        Locale[] locales = Collator.getAvailableLocales();
-        assertTrue("No locales", locales.length > 0);
-        boolean hasUS = false;
-        for (int i = locales.length; --i >= 0;) {
-            Collator c1 = Collator.getInstance(locales[i]);
-            assertTrue("Doesn't work", c1.compare("a", "b") < 0);
-            assertTrue("Wrong decomposition",
-                    c1.getDecomposition() == Collator.NO_DECOMPOSITION);
-            assertTrue("Wrong strength", c1.getStrength() == Collator.TERTIARY);
-            // The default decomposition for collators created with getInstance
-            // is NO_DECOMPOSITION where collators created from rules have
-            // CANONICAL_DECOMPOSITION. Verified on RI.
-            c1.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
-            if (locales[i].equals(Locale.US)) {
-                hasUS = true;
-            }
-            if (c1 instanceof RuleBasedCollator) {
-                String rule = "";
-                Collator temp = null;
-                try {
-                    rule = ((RuleBasedCollator) c1).getRules();
-                    temp = new RuleBasedCollator(rule);
-                } catch (ParseException e) {
-                    fail(e.getMessage() + " for rule: \"" + rule + "\"");
-                }
-                assertTrue("Can't recreate: " + locales[i], temp.equals(c1));
-            }
-        }
-        assertTrue("en_US locale not available", hasUS);
-    }
+	/**
+	 * @tests java.text.Collator#getAvailableLocales()
+	 */
+	//FIXME This test fails on Harmony ClassLibrary
+	public void failing_test_getAvailableLocales() {
+		Locale[] locales = Collator.getAvailableLocales();
+		assertTrue("No locales", locales.length > 0);
+		boolean english = false, german = false;
+		for (int i = locales.length; --i >= 0;) {
+			if (locales[i].equals(Locale.ENGLISH))
+				english = true;
+			if (locales[i].equals(Locale.GERMAN))
+				german = true;
+			// Output the working locale to help diagnose a hang
+			Collator c1 = Collator.getInstance(locales[i]);
+			assertTrue("Doesn't work", c1.compare("a", "b") < 0);
+			assertTrue("Wrong decomposition",
+					c1.getDecomposition() == Collator.NO_DECOMPOSITION);
+			assertTrue("Wrong strength", c1.getStrength() == Collator.TERTIARY);
+			if (c1 instanceof RuleBasedCollator) {
+				try {
+					new RuleBasedCollator(((RuleBasedCollator) c1).getRules());
+				} catch (ParseException e) {
+					fail("ParseException");
+				}
+				// assertTrue("Can't recreate: " + locales[i], temp.equals(c1));
+			}
+		}
+		assertTrue("Missing locales", english && german);
+	}
 
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "Collator",
-        args = {}
-    )
-    public void test_Constructor() {
-        TestCollator collator = new TestCollator();
-        assertEquals(Collator.TERTIARY, collator.getStrength());
-    }
-    
-    /**
-     * @tests java.text.Collator#getDecomposition()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getDecomposition",
-        args = {}
-    )
-    public void test_getDecomposition() {
-        RuleBasedCollator collator;
-        try {
-            collator = new RuleBasedCollator("; \u0300 < a, A < b < c < d");
-        } catch (ParseException e) {
-            fail("ParseException");
-            return;
-        }
-        assertTrue("Wrong default",
-                collator.getDecomposition() == Collator.CANONICAL_DECOMPOSITION);
-        
-        collator.setDecomposition(Collator.NO_DECOMPOSITION);
-        assertEquals(Collator.NO_DECOMPOSITION, collator.getDecomposition());
+	/**
+	 * @tests java.text.Collator#getDecomposition()
+	 */
+	//FIXME This test fails on Harmony ClassLibrary
+	public void failing_test_getDecomposition() {
+		RuleBasedCollator collator;
+		try {
+			collator = new RuleBasedCollator("; \u0300 < a, A < b < c < d");
+		} catch (ParseException e) {
+			fail("ParseException");
+			return;
+		}
+		assertTrue("Wrong default",
+				collator.getDecomposition() == Collator.CANONICAL_DECOMPOSITION);
+	}
 
-        // BEGIN android-removed
-        // Android doesn't support full decomposition
-        // collator.setDecomposition(Collator.FULL_DECOMPOSITION);
-        // assertEquals(Collator.FULL_DECOMPOSITION, collator.getDecomposition());
-        // EN android-removed
-    }
+	/**
+	 * @tests java.text.Collator#getInstance()
+	 */
+	public void test_getInstance() {
+		Collator c1 = Collator.getInstance();
+		Collator c2 = Collator.getInstance(Locale.getDefault());
+		assertTrue("Wrong locale", c1.equals(c2));
+	}
 
-    /**
-     * @tests java.text.Collator#getInstance()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInstance",
-        args = {}
-    )
-    public void test_getInstance() {
-        Collator c1 = Collator.getInstance();
-        Collator c2 = Collator.getInstance(Locale.getDefault());
-        assertTrue("Wrong locale", c1.equals(c2));
-    }
+	/**
+	 * @tests java.text.Collator#getInstance(java.util.Locale)
+	 */
+	public void test_getInstanceLjava_util_Locale() {
+		assertTrue("Used to test", true);
+	}
 
-    /**
-     * @tests java.text.Collator#getInstance(java.util.Locale)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInstance",
-        args = {java.util.Locale.class}
-    )
-    public void test_getInstanceLjava_util_Locale() {
-        assertTrue("Used to test", true);
-    }
+	/**
+	 * @tests java.text.Collator#getStrength()
+	 */
+	public void test_getStrength() {
+		RuleBasedCollator collator;
+		try {
+			collator = new RuleBasedCollator("; \u0300 < a, A < b < c < d");
+		} catch (ParseException e) {
+			fail("ParseException");
+			return;
+		}
+		assertTrue("Wrong default", collator.getStrength() == Collator.TERTIARY);
+	}
 
-    /**
-     * @tests java.text.Collator#getStrength()
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getStrength",
-        args = {}
-    )
-    public void test_getStrength() {
-        RuleBasedCollator collator;
-        try {
-            collator = new RuleBasedCollator("; \u0300 < a, A < b < c < d");
-        } catch (ParseException e) {
-            fail("ParseException");
-            return;
-        }
-        assertTrue("Wrong default", collator.getStrength() == Collator.TERTIARY);
-    }
+	/**
+	 * @tests java.text.Collator#setDecomposition(int)
+	 */
+	//FIXME This test fails on Harmony ClassLibrary
+	public void failing_test_setDecompositionI() {
+		Collator c = Collator.getInstance(Locale.FRENCH);
+		c.setStrength(Collator.IDENTICAL);
+		c.setDecomposition(Collator.NO_DECOMPOSITION);
+		assertTrue("Collator should not be using decomposition", !c.equals(
+				"\u212B", "\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL
+		// LETTER A WITH RING ABOVE"
+		c.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+		assertTrue("Collator should be using decomposition", c.equals("\u212B",
+				"\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL LETTER A WITH
+		// RING ABOVE"
+		assertTrue("Should not be equal under canonical decomposition", !c
+				.equals("\u2163", "IV")); // roman number "IV"
+		c.setDecomposition(Collator.FULL_DECOMPOSITION);
+		assertTrue("Should be equal under full decomposition", c.equals(
+				"\u2163", "IV")); // roman number "IV"
+	}
 
-    /**
-     * @tests java.text.Collator#setDecomposition(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "setDecomposition",
-        args = {int.class}
-    )
-    @KnownFailure("uses decomposition even if set to NO_DECOMPOSITION")
-    public void test_setDecompositionI() {
-        Collator c = Collator.getInstance(Locale.FRENCH);
-        c.setStrength(Collator.IDENTICAL);
-        c.setDecomposition(Collator.NO_DECOMPOSITION);
-        assertFalse("Collator should not be using decomposition", c.equals(
-                "\u212B", "\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL
-                                      // LETTER A WITH RING ABOVE"
-        c.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
-        assertTrue("Collator should be using decomposition", c.equals("\u212B",
-                "\u00C5")); // "ANGSTROM SIGN" and "LATIN CAPITAL LETTER A WITH
-        // RING ABOVE"
-        // BEGIN android-removed
-        // Android doesn't support FULL_DECOMPOSITION
-        // c.setDecomposition(Collator.FULL_DECOMPOSITION);
-        // assertTrue("Should be equal under full decomposition", c.equals(
-        //         "\u2163", "IV")); // roman number "IV"
-        // END android-removed
-        
-        try {
-            c.setDecomposition(-1);
-            fail("IllegalArgumentException should be thrown.");
-        } catch(IllegalArgumentException iae) {
-            //expected
-        }
-    }
-
-    /**
-     * @tests java.text.Collator#setStrength(int)
-     */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL_COMPLETE,
-        notes = "Verifies IllegalArgumentException.",
-        method = "setStrength",
-        args = {int.class}
-    )
-    public void test_setStrengthI() {
-        // Functionality is verified in compare and equals tests.
-        Collator collator = Collator.getInstance();
-        collator.setStrength(Collator.PRIMARY);
-        assertEquals(Collator.PRIMARY, collator.getStrength());
-        
-        collator.setStrength(Collator.SECONDARY);
-        assertEquals(Collator.SECONDARY, collator.getStrength());
-        
-        collator.setStrength(Collator.TERTIARY);
-        assertEquals(Collator.TERTIARY, collator.getStrength());
-        
-        collator.setStrength(Collator.IDENTICAL);
-        assertEquals(Collator.IDENTICAL, collator.getStrength());        
-        
-        try {
-            collator.setStrength(-1);
-            fail("IllegalArgumentException was not thrown.");
-        } catch(IllegalArgumentException  iae) {
-            //expected
-        }        
-    }
-    // Regression test for Android bug   
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Regression test.",
-            method = "setStrength",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Regression test.",
-            method = "getCollationKey",
-            args = {java.lang.String.class}
-        )
-    })
-    public void test_stackCorruption() {
-        Collator mColl = Collator.getInstance();
-        mColl.setStrength(Collator.PRIMARY);
-        mColl.getCollationKey("2d294f2d3739433565147655394f3762f3147312d3731641452f310");    
-    }
-    
-    // Test to verify that very large collation keys are not truncated.
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't verify null as a parameter.",
-        method = "getCollationKey",
-        args = {java.lang.String.class}
-    )
-    public void test_collationKeySize() {
-        StringBuilder b = new StringBuilder();
-        for (int i = 0; i < 1024; i++) {
-            b.append("0123456789ABCDEF");
-        }
-        String sixteen = b.toString();
-        b.append("_THE_END");
-        String sixteenplus = b.toString();
-        
-        Collator mColl = Collator.getInstance();
-        mColl.setStrength(Collator.PRIMARY);
-
-        try {
-            byte [] arr = mColl.getCollationKey(sixteen).toByteArray();
-            int len = arr.length;
-            assertTrue("Collation key not 0 terminated", arr[arr.length - 1] == 0);
-            len--;
-            String foo = new String(arr, 0, len, "iso8859-1");
-
-            arr = mColl.getCollationKey(sixteen).toByteArray();
-            len = arr.length;
-            assertTrue("Collation key not 0 terminated", arr[arr.length - 1] == 0);
-            len--;
-            String bar = new String(arr, 0, len, "iso8859-1");
-            
-            assertTrue("Collation keys should differ", foo.equals(bar));
-        } catch (UnsupportedEncodingException ex) {
-            fail("UnsupportedEncodingException");
-        }
-    }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "",
-            method = "setDecomposition",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "",
-            method = "compare",
-            args = {java.lang.String.class, java.lang.String.class}
-        )
-    })
-    public void test_decompositionCompatibility() {
-        Collator myCollator = Collator.getInstance();
-        myCollator.setDecomposition(Collator.NO_DECOMPOSITION);
-        assertFalse("Error: \u00e0\u0325 should not equal to a\u0325\u0300 " +
-                "without decomposition", 
-                myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
-        myCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
-        assertTrue("Error: \u00e0\u0325 should equal to a\u0325\u0300 " +
-                "with decomposition", 
-                myCollator.compare("\u00e0\u0325", "a\u0325\u0300") == 0);
-    }
-    
-    class TestCollator extends Collator {
-
-        @Override
-        public int compare(String source, String target) {
-            return 0;
-        }
-
-        @Override
-        public CollationKey getCollationKey(String source) {
-            return null;
-        }
-
-        @Override
-        public int hashCode() {
-            return 0;
-        }
-        
-    }
+	/**
+	 * @tests java.text.Collator#setStrength(int)
+	 */
+	public void test_setStrengthI() {
+		assertTrue("Used to test", true);
+	}
 }
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java
index a0d9615..e3772c0 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java
@@ -63,6 +63,54 @@
     }
 
     /**
+     * @tests java.text.DateFormatSymbols#getAvailableLocales()
+     */
+    public void test_getAvailableLocales_no_provider() throws Exception {
+        Locale[] locales = DateFormatSymbols.getAvailableLocales();
+        assertNotNull(locales);
+        // must contain Locale.US
+        boolean flag = false;
+        for (Locale locale : locales) {
+            if (locale.equals(Locale.US)) {
+                flag = true;
+                break;
+            }
+        }
+        assertTrue(flag);
+    }
+
+    /**
+     * @tests java.text.DateFormatSymbols#getInstance()
+     */
+    public void test_getInstance() {
+        DateFormatSymbols.getInstance();
+        assertEquals(new DateFormatSymbols(), DateFormatSymbols.getInstance());
+        assertEquals(new DateFormatSymbols(Locale.getDefault()),
+                DateFormatSymbols.getInstance());
+
+        assertNotSame(DateFormatSymbols.getInstance(), DateFormatSymbols.getInstance());
+    }
+
+    public void test_getInstanceLjava_util_Locale() {
+        try {
+            DateFormatSymbols.getInstance(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        assertEquals(new DateFormatSymbols(Locale.GERMANY), DateFormatSymbols
+                .getInstance(Locale.GERMANY));
+
+        Locale locale = new Locale("not exist language", "not exist country");
+        DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
+        assertNotNull(symbols);
+        // BEGIN android-removed: this test is wrong, and confuses default locale with root locale.
+        // assertEquals(DateFormatSymbols.getInstance(), symbols);
+        // END android-removed
+    }
+
+    /**
      * @tests java.text.DateFormatSymbols#clone()
      */
     @TestTargetNew(
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
index 7a615d5..604f0ea 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
@@ -85,6 +85,56 @@
     }
 
     /**
+     * @tests java.text.DecimalFormatSymbols#getAvailableLocales()
+     */
+    public void test_getAvailableLocales_no_provider() throws Exception {
+        Locale[] locales = DecimalFormatSymbols.getAvailableLocales();
+        assertNotNull(locales);
+        // must contain Locale.US
+        boolean flag = false;
+        for (Locale locale : locales) {
+            if (locale.equals(Locale.US)) {
+                flag = true;
+                break;
+            }
+        }
+        assertTrue(flag);
+    }
+
+    /**
+     * @tests java.text.DecimalFormatSymbols#getInstance()
+     */
+    public void test_getInstance() {
+        assertEquals(new DecimalFormatSymbols(), DecimalFormatSymbols.getInstance());
+        assertEquals(new DecimalFormatSymbols(Locale.getDefault()),
+                DecimalFormatSymbols.getInstance());
+
+        assertNotSame(DecimalFormatSymbols.getInstance(), DecimalFormatSymbols.getInstance());
+    }
+
+    /**
+     * @tests java.text.DecimalFormatSymbols#getInstance(Locale)
+     */
+    public void test_getInstanceLjava_util_Locale() {
+        try {
+            DecimalFormatSymbols.getInstance(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        assertEquals(new DecimalFormatSymbols(Locale.GERMANY), DecimalFormatSymbols
+                .getInstance(Locale.GERMANY));
+
+        Locale locale = new Locale("not exist language", "not exist country");
+        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
+        assertNotNull(symbols);
+        // BEGIN android-removed: this test is wrong, and confuses default locale with root locale.
+        // assertEquals(DecimalFormatSymbols.getInstance(), symbols);
+        // END android-removed
+    }
+
+    /**
      * @tests java.text.DecimalFormatSymbols#clone() Test of method
      *        java.text.DecimalFormatSymbols#clone(). Case 1: Compare of
      *        internal variables of cloned objects. Case 2: Compare of clones.
@@ -259,6 +309,15 @@
     }
 
     /**
+     * @tests java.text.DecimalFormatSymbols#getExponentSeparator()
+     */
+    public void test_getExponentSeparator() {
+        dfs.setExponentSeparator("EE");
+        assertEquals("Returned incorrect Exponent Separator symbol", "EE", dfs
+                .getExponentSeparator());
+    }
+
+    /**
      * @tests java.text.DecimalFormatSymbols#getGroupingSeparator()
      */
     @TestTargetNew(
@@ -516,6 +575,30 @@
     }
 
     /**
+     * @tests java.text.DecimalFormatSymbols#setExponentSeparator(String)
+     */
+    public void test_setExponentSeparator() {
+        try {
+            dfs.setExponentSeparator(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected
+        }
+
+        dfs.setExponentSeparator("");
+        assertEquals("Returned incorrect Exponent Separator symbol", "", dfs
+                .getExponentSeparator());
+
+        dfs.setExponentSeparator("what ever you want");
+        assertEquals("Returned incorrect Exponent Separator symbol",
+                "what ever you want", dfs.getExponentSeparator());
+
+        dfs.setExponentSeparator(" E ");
+        assertEquals("Returned incorrect Exponent Separator symbol", " E ", dfs
+                .getExponentSeparator());
+    }
+
+    /**
      * @tests java.text.DecimalFormatSymbols#setGroupingSeparator(char)
      */
     @TestTargetNew(
@@ -554,7 +637,6 @@
         method = "setInternationalCurrencySymbol",
         args = {java.lang.String.class}
     )
-    @KnownFailure("getCurrency() doesn't return null for bogus currency code.")
     public void test_setInternationalCurrencySymbolLjava_lang_String() {
         Locale locale = Locale.CANADA;
         DecimalFormatSymbols dfs = ((DecimalFormat) NumberFormat
@@ -743,8 +825,6 @@
         method = "!SerializationGolden",
         args = {}
     )
-    @KnownFailure("Deserialized object is not equal to the original object." +
-            "Test passes on RI.")
     public void test_RIHarmony_compatible() throws Exception {
         ObjectInputStream i = null;
         try {
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
index 92945ee..c1f1808 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java
@@ -35,6 +35,7 @@
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.text.AttributedCharacterIterator;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
@@ -70,8 +71,6 @@
         method = "formatToCharacterIterator",
         args = {java.lang.Object.class}
     )
-    @KnownFailure("formatting numbers with more than ~300 digits doesn't work."
-            + " Also the third test doesn't round the string like the RI does")
     public void test_formatToCharacterIterator() throws Exception {
         AttributedCharacterIterator iterator;
         int[] runStarts;
@@ -277,7 +276,6 @@
         method = "parse",
         args = {java.lang.String.class, java.text.ParsePosition.class}
     )
-    @KnownFailure("Something seems wrong with Android implementation, here!")
     public void test_parseLjava_lang_String_Ljava_text_ParsePosition() {
         DecimalFormat form = (DecimalFormat) DecimalFormat
                 .getInstance(Locale.US);
@@ -1514,7 +1512,6 @@
         method = "format",
         args = {double.class, java.lang.StringBuffer.class, java.text.FieldPosition.class}
     )
-    @KnownFailure("Something seems wrong with Android implementation, here!")
     public void test_formatDLjava_lang_StringBufferLjava_text_FieldPosition() {
         new Support_DecimalFormat(
                 "test_formatDLjava_lang_StringBufferLjava_text_FieldPosition")
@@ -1752,7 +1749,6 @@
         method = "format",
         args = {long.class, java.lang.StringBuffer.class, java.text.FieldPosition.class}
     )
-    @KnownFailure("Something seems wrong with Android implementation, here!")
     public void test_formatJLjava_lang_StringBufferLjava_text_FieldPosition() {
         int failCount = 0;
         BitSet failures = new BitSet();
@@ -1831,6 +1827,7 @@
         method = "formatToCharacterIterator",
         args = {java.lang.Object.class}
     )
+    @KnownFailure("Fails in CTS but passes under run-core-tests")
     public void test_formatToCharacterIteratorLjava_lang_Object() {
         try {
             // Regression for HARMONY-466
@@ -1853,10 +1850,6 @@
         method = "format",
         args = {double.class}
     )
-    @KnownFailure("This test should take into account (inexact) double " +
-            "representation. Fails on Both RI and Android at different places." +
-            "There is ticket for this failure because of parseDouble method " +
-            "returns different values on Android and RI.")
     public void test_formatD() {
         DecimalFormat format = (DecimalFormat) NumberFormat
                 .getInstance(Locale.ENGLISH);
@@ -2144,7 +2137,6 @@
         method = "parse",
         args = {java.lang.String.class, java.text.ParsePosition.class}
     )
-    @KnownFailure("Something seems wrong with Android implementation, here!")
     public void test_parseLjava_lang_StringLjava_text_ParsePosition() {
         DecimalFormat format = (DecimalFormat) NumberFormat
                 .getNumberInstance(Locale.ENGLISH);
@@ -2573,119 +2565,321 @@
         DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance();
         format.setDecimalFormatSymbols(null);
     }
-
-    private void assertBigDecimalWithFraction(
-            BigDecimal bd,
-            String expectedResult,
-            int fraction) {
-        NumberFormat pf = NumberFormat.getPercentInstance();
-        pf.setMaximumFractionDigits(fraction);
-        assertEquals(expectedResult, pf.format(bd));
-    }
-
-    private void assertDecFmtWithMultiplierAndFraction(
-            String value,
-            int multiplier,
-            int fraction,
-            String expectedResult) {
-
-        DecimalFormat df = (DecimalFormat)NumberFormat.getInstance();
-        df.setMultiplier(multiplier);
-        df.setMaximumFractionDigits(fraction);
-        BigDecimal d = new BigDecimal(value);
-        assertEquals(expectedResult, df.format(d));
-    }
-
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-    )
-    public void testBigDecimalBug1897917() {
-        // Bug1897917 : BigDecimal does not take into account multiplier.
-        // So the BigDecimal 0.17 formatted in PercentInstance is 0% instead of 17%.
-
-        NumberFormat pf = NumberFormat.getPercentInstance();
-
-        // Test bug 1897917 case.
-        assertEquals("17%", pf.format(BigDecimal.valueOf(0.17)));
-
-        // Test long decimal formatted in PercentInstance with various fractions.
-        String longDec = "11.2345678901234567890123456789012345678901234567890";
-        BigDecimal bd = new BigDecimal(longDec);
-        assertBigDecimalWithFraction(bd, "1,123.46%", 2);
-        assertBigDecimalWithFraction(bd, "1,123.45678901%", 8);
-        assertBigDecimalWithFraction(bd, "1,123.4567890123%", 10);
-        assertBigDecimalWithFraction(bd, "1,123.45678901234567890123%", 20);
-        assertBigDecimalWithFraction(bd, "1,123.456789012345678901234567890123%", 30);
-
-        // Test trailing zeros.
-        assertDecFmtWithMultiplierAndFraction("3333.33333333", 3, 4, "10,000");
-        assertDecFmtWithMultiplierAndFraction("3333.33333333", -3, 4, "-10,000");
-        assertDecFmtWithMultiplierAndFraction("0.00333333", 3, 4, "0.01");
-        assertDecFmtWithMultiplierAndFraction("3330000000000000000000000000000000", 3, 4,
-                                               "9,990,000,000,000,000,000,000,000,000,000,000");
-    }
-
-    @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-    )
-    public void testBigDecimalTestBigIntWithMultiplier() {
-       // Big integer tests.
-       assertDecFmtWithMultiplierAndFraction("123456789012345", 10, 0, "1,234,567,890,123,450");
-       assertDecFmtWithMultiplierAndFraction("12345678901234567890", 10, 0,
-                                              "123,456,789,012,345,678,900");
-       assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", 10, 0,
-                                              "987,654,321,098,765,432,109,876,543,210");
-
-       assertDecFmtWithMultiplierAndFraction("123456789012345", -10, 0, "-1,234,567,890,123,450");
-       assertDecFmtWithMultiplierAndFraction("12345678901234567890", -10, 0,
-                                              "-123,456,789,012,345,678,900");
-       assertDecFmtWithMultiplierAndFraction("98765432109876543210987654321", -10, 0,
-                                              "-987,654,321,098,765,432,109,876,543,210");
-   }
-
-   @TestTargetNew(
-        level = TestLevel.ADDITIONAL,
-        notes = "Regression test for some existing bugs and crashes",
-        method = "format",
-        args = { String.class, Object[].class }
-   )
-   public void testBigDecimalICUConsistency() {
-       DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
-       df.setMaximumFractionDigits(2);
-       df.setMultiplier(2);
-       assertEquals(df.format(BigDecimal.valueOf(0.16)),
-                    df.format(BigDecimal.valueOf(0.16).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0.0293)),
-                    df.format(BigDecimal.valueOf(0.0293).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0.006)),
-                    df.format(BigDecimal.valueOf(0.006).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0.00283)),
-                    df.format(BigDecimal.valueOf(0.00283).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(1.60)),
-                    df.format(BigDecimal.valueOf(1.60).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(15)),
-                    df.format(BigDecimal.valueOf(15).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(170)),
-                    df.format(BigDecimal.valueOf(170).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(234.56)),
-                    df.format(BigDecimal.valueOf(234.56).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(0)),
-                    df.format(BigDecimal.valueOf(0).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(-1)),
-                    df.format(BigDecimal.valueOf(-1).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(-10000)),
-                    df.format(BigDecimal.valueOf(-10000).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(-0.001)),
-                    df.format(BigDecimal.valueOf(-0.001).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(1234567890.1234567)),
-                    df.format(BigDecimal.valueOf(1234567890.1234567).doubleValue()));
-       assertEquals(df.format(BigDecimal.valueOf(1.234567E100)),
-                    df.format(BigDecimal.valueOf(1.234567E100).doubleValue()));
+    
+    // BEGIN android-added: brought back from the harmony java6 branch.
+    public void test_SetRoudingMode_Ljava_math_RoundingMode() {
+        DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.US);
+        // ignore the fraction part of a given value
+        decimalFormat.setMaximumFractionDigits(0);
+        
+        // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+        String result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.6);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+        
+        // set RoundingMode.CEILING of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.CEILING);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+        
+        // set RoundingMode.DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.DOWN);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+        
+        // set RoundingMode.FLOOR of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+        
+        // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+        
+        // set RoundingMode.HALF_UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+        
+        // BEGIN android-changed: we're RI-compatible.
+        // the following assertion will fail on RI implementation, since the
+        // implementation of ICU and RI are not identical.
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+        // END android-changed
+        
+        // set RoundingMode.UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+        
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+        
+        // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+        
+        try {
+            // when rounding is needed but RoundingMode is set to RoundingMode.UNNECESSARY, throw ArithmeticException
+            result = decimalFormat.format(5.5);
+            fail("ArithmeticException expected: RoundingMode.UNNECESSARY");
+        } catch (ArithmeticException e) {
+            // expected
+        }
+        
+        result = decimalFormat.format(1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+        
+        result = decimalFormat.format(-1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
+        
+        try {
+            // when the given RoundingMode is null, throw NullPointerException
+            decimalFormat.setRoundingMode(null);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            // expected
+        }
+        
+        // set MaxFractionDigits to 3, test different DecimalFormat format
+        // function with differnt RoundingMode
+        decimalFormat.setMaximumFractionDigits(3);
+        
+        // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+        
+        result = decimalFormat.format(11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.565", result);
+        
+        result = decimalFormat.format(11.5656);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11.566", result);
+        
+        // set RoundingMode.CEILING of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.CEILING);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "11.566", result);
+        
+        result = decimalFormat.format(-11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11.565", result);
+        
+        // set RoundingMode.DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.DOWN);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11.565", result);
+        
+        result = decimalFormat.format(-11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11.565", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+        
+        // set RoundingMode.FLOOR of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11.565", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-11.566", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+        
+        // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.565", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-11.566", result);
+        
+        result = decimalFormat.format(11.5656);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "11.566", result);
+        
+        // set RoundingMode.HALF_UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.565", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-11.566", result);
+        
+        result = decimalFormat.format(11.5656);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "11.566", result);
+        
+        // set RoundingMode.UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UP);
+        result = decimalFormat.format(11.5653);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "11.566", result);
+        
+        result = decimalFormat.format(-11.5655);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-11.566", result);
+        
+        // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+        result = decimalFormat.format(-11.565);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-11.565", result);
+        
+        result = decimalFormat.format(11.565);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "11.565", result);
+        
+        // when setting MaxFractionDigits to negative value -2, default it as
+        // zero, test different DecimalFormat format
+        // function with differnt RoundingMode
+        decimalFormat.setMaximumFractionDigits(-2);
+        
+        // set RoundingMode.HALF_DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_DOWN);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "11", result);
+        
+        result = decimalFormat.format(11.6);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_DOWN", "12", result);
+        
+        // set RoundingMode.CEILING of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.CEILING);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "12", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.CEILING", "-11", result);
+        
+        // set RoundingMode.DOWN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.DOWN);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "-11", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.DOWN", "0", result);
+        
+        // set RoundingMode.FLOOR of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.FLOOR);
+        result = decimalFormat.format(11.3);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "11", result);
+        
+        result = decimalFormat.format(-11.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "-12", result);
+        
+        result = decimalFormat.format(0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.FLOOR", "0", result);
+        
+        // set RoundingMode.HALF_EVEN of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_EVEN", "0", result);
+        
+        // set RoundingMode.HALF_UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "0", result);
+        
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.HALF_UP", "-0", result);
+        
+        // set RoundingMode.UP of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UP);
+        result = decimalFormat.format(5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "6", result);
+        
+        result = decimalFormat.format(-5.5);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-6", result);
+        
+        result = decimalFormat.format(0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "1", result);
+        
+        result = decimalFormat.format(-0.2);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UP", "-1", result);
+        
+        // set RoundingMode.UNNECESSARY of this DecimalFormat and test its
+        // behavior
+        decimalFormat.setRoundingMode(RoundingMode.UNNECESSARY);
+        
+        result = decimalFormat.format(1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "1", result);
+        
+        result = decimalFormat.format(-1.0);
+        assertEquals("Incorrect RoundingMode behavior: RoundingMode.UNNECESSARY", "-1", result);
     }
 }
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatFieldTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatFieldTest.java
index 06c6922..e6c79cd 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatFieldTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/NumberFormatFieldTest.java
@@ -60,7 +60,6 @@
         method = "readResolve",
         args = {}
     )
-    @KnownFailure("readResolve does not work properly")
     public void test_readResolve() {
         // test for method java.lang.Object readResolve()
 
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
index 3c864a5..5b8146c 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
@@ -17,15 +17,6 @@
 
 package org.apache.harmony.text.tests.java.text;
 
-import dalvik.annotation.AndroidOnly;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
-import junit.framework.TestCase;
-
 import java.text.CharacterIterator;
 import java.text.CollationElementIterator;
 import java.text.CollationKey;
@@ -35,83 +26,24 @@
 import java.text.StringCharacterIterator;
 import java.util.Locale;
 
-@TestTargetClass(RuleBasedCollator.class) 
+import junit.framework.TestCase;
+
 public class RuleBasedCollatorTest extends TestCase {
 
-    /**
-     * @tests java.text.RuleBasedCollator#RuleBasedCollator(String)
-     */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "RuleBasedCollator",
-        args = {java.lang.String.class}
-    )
-    public void test_constrLRuleBasedCollatorLjava_lang_String() {
-        RuleBasedCollator rbc;
-        try {
-            rbc = new RuleBasedCollator("<a< b< c< d");
-            assertNotSame("RuleBasedCollator object is null", null, rbc);
-        } catch (java.text.ParseException pe) {
-            fail("java.text.ParseException is thrown for correct string");
-        }
-
-        try {
-            rbc = new RuleBasedCollator("<a< '&'b< \u0301< d");
-            assertNotSame("RuleBasedCollator object is null", null, rbc);
-        } catch (java.text.ParseException pe) {
-            fail("java.text.ParseException is thrown for correct string");
-        }
-
-        try {
-            new RuleBasedCollator(null);
-            fail("No Exception is thrown for correct string");
-        } catch (java.text.ParseException pe) {
-            fail("java.lang.NullPointerException is not thrown for correct string");
-        } catch (java.lang.NullPointerException npe) {
-
-        }
-
-// Commented since fails agains RI and Android, too:
-//
-//        // Android allows to pass empty rules to a collator. It results in
-//        // a collator with default UCA rules.
-//        try {
-//            new RuleBasedCollator("");
-//        } catch (java.text.ParseException pe) {
-//            fail("java.text.ParseException is thrown for empty string");
-//        }
-
-        try {
-            new RuleBasedCollator("1234567%$#845");
-            fail("java.text.ParseException is not thrown for wrong rules");
-        } catch (java.text.ParseException pe) {
-        }
-    }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Regression test. Doesn't verify positive functionality.",
-        method = "getCollationKey",
-        args = {java.lang.String.class}
-    )
-    public void test_getCollationKeyLjava_lang_String() {
-        // Regression test for HARMONY-28
-        String source = null;
-        RuleBasedCollator rbc = null;
-        try {
-            String Simple = "< a< b< c< d";
-            rbc = new RuleBasedCollator(Simple);
-        } catch (ParseException e) {
-            fail("Assert 0: Unexpected format exception " + e);
-        }
-        CollationKey ck = rbc.getCollationKey(source);
-        assertNull("Assert 1: getCollationKey (null) does not return null", ck);
-    }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "hashCode",
-        args = {}
-    )
+	public void test_getCollationKeyLjava_lang_String() {
+		// Regression test for HARMONY-28
+		String source = null;
+		RuleBasedCollator rbc = null;
+		try {
+			String Simple = "< a< b< c< d";
+			rbc = new RuleBasedCollator(Simple);
+		} catch (ParseException e) {
+			fail("Assert 0: Unexpected format exception " + e);
+		}
+		CollationKey ck = rbc.getCollationKey(source);
+		assertNull("Assert 1: getCollationKey (null) does not return null", ck);
+	}
+    
     public void testHashCode() throws ParseException {
         {
             String rule = "< a < b < c < d";
@@ -126,12 +58,7 @@
         }
 
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "clone",
-        args = {}
-    )
+
     public void testClone() throws ParseException {
         RuleBasedCollator coll = (RuleBasedCollator) Collator
                 .getInstance(Locale.US);
@@ -145,17 +72,12 @@
     /*
      * Class under test for boolean equals(java.lang.Object)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "equals",
-        args = {java.lang.Object.class}
-    )
     public void testEqualsObject() throws ParseException {
         String rule = "< a < b < c < d < e";
         RuleBasedCollator coll = new RuleBasedCollator(rule);
 
         assertEquals(Collator.TERTIARY, coll.getStrength());
-        assertEquals(Collator.CANONICAL_DECOMPOSITION, coll.getDecomposition());
+        assertEquals(Collator.NO_DECOMPOSITION, coll.getDecomposition());
         RuleBasedCollator other = new RuleBasedCollator(rule);
         assertTrue(coll.equals(other));
 
@@ -164,33 +86,18 @@
 
         coll.setStrength(Collator.TERTIARY);
         coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
-        assertTrue(coll.equals(other));
+        assertFalse(coll.equals(other));
     }
 
     /*
      * Class under test for int compare(java.lang.String, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "compare",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testCompareStringString() throws ParseException {
         String rule = "< c < b < a";
         RuleBasedCollator coll = new RuleBasedCollator(rule);
         assertEquals(-1, coll.compare("c", "a"));
-        assertEquals(-1, coll.compare("a", "d"));
-        assertEquals(1, coll.compare("3", "1"));
-        assertEquals(1, coll.compare("A", "1"));
-        assertEquals(0, coll.compare("A", "A"));
     }
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Doesn't verify null as a parameter.",
-        method = "getCollationKey",
-        args = {java.lang.String.class}
-    )
+
     public void testGetCollationKey() {
         RuleBasedCollator coll = (RuleBasedCollator) Collator
                 .getInstance(Locale.GERMAN);
@@ -204,12 +111,7 @@
         assertTrue(coll.compare(source, source2) > 0);
 
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getRules",
-        args = {}
-    )
+
     public void testGetRules() throws ParseException {
         String rule = "< a = b < c";
         RuleBasedCollator coll = new RuleBasedCollator(rule);
@@ -220,12 +122,6 @@
      * Class under test for java.text.CollationElementIterator
      * getCollationElementIterator(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCollationElementIterator",
-        args = {java.lang.String.class}
-    )
     public void testGetCollationElementIteratorString() throws Exception {
         {
             Locale locale = new Locale("es", "", "TRADITIONAL");
@@ -234,11 +130,11 @@
             String source = "cha";
             CollationElementIterator iterator = coll
                     .getCollationElementIterator(source);
-            int[] e_offset = { 0, 1, 2 };
+            int[] e_offset = { 0, 1, 2 ,3};
             int offset = iterator.getOffset();
             int i = 0;
             assertEquals(e_offset[i++], offset);
-            while (offset != source.length() - 1) {
+            while (offset != source.length()) {
                 iterator.next();
                 offset = iterator.getOffset();
                 assertEquals(e_offset[i++], offset);
@@ -262,12 +158,12 @@
                 assertEquals(e_offset[i++], offset);
             }
         }
-        // Regression for HARMONY-1352
+        //Regression for HARMONY-1352
         try {
             new RuleBasedCollator("< a< b< c< d").getCollationElementIterator((String)null);
             fail("NullPointerException expected");
         } catch (NullPointerException e) {
-            // expected
+            //expected
         }
     }
 
@@ -275,30 +171,24 @@
      * Class under test for java.text.CollationElementIterator
      * getCollationElementIterator(java.text.CharacterIterator)
      */
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getCollationElementIterator",
-        args = {java.text.CharacterIterator.class}
-    )
-    @KnownFailure("ICU seems to miss collation data")
     public void testGetCollationElementIteratorCharacterIterator() throws Exception {
         {
-            Locale locale = new Locale("cs", "CZ", "");
+            Locale locale = new Locale("es", "", "TRADITIONAL");
             RuleBasedCollator coll = (RuleBasedCollator) Collator
                     .getInstance(locale);
             String text = "cha";
             StringCharacterIterator source = new StringCharacterIterator(text);
             CollationElementIterator iterator = coll
                     .getCollationElementIterator(source);
-            int[] e_offset = { 0, 2 };
+            int[] e_offset = { 0, 1, 2, 3 };
             int offset = iterator.getOffset();
             int i = 0;
             assertEquals(e_offset[i++], offset);
-            while (offset != text.length() - 1) {
+            while (offset != text.length()) {
                 iterator.next();
                 offset = iterator.getOffset();
-                assertEquals(e_offset[i], offset);
-                i++;
+                // System.out.println(offset);
+                assertEquals(e_offset[i++], offset);
             }
         }
 
@@ -320,28 +210,15 @@
                 assertEquals(e_offset[i++], offset);
             }
         }
-        // Regression for HARMONY-1352
+        //Regression for HARMONY-1352
         try {
             new RuleBasedCollator("< a< b< c< d").getCollationElementIterator((CharacterIterator)null);
             fail("NullPointerException expected");
         } catch (NullPointerException e) {
-            // expected
+            //expected
         }
     }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Doesn't verify setStrength method with PRIMARY, SECONDARY, TERTIARY or IDENTICAL values as a parameter; doesn't verify thatsetStrength method can throw IllegalArgumentException.",
-            method = "setStrength",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.PARTIAL,
-            notes = "Doesn't verify setStrength method with PRIMARY, SECONDARY, TERTIARY or IDENTICAL values as a parameter; doesn't verify thatsetStrength method can throw IllegalArgumentException.",
-            method = "getStrength",
-            args = {}
-        )
-    })
+
     public void testStrength() {
         RuleBasedCollator coll = (RuleBasedCollator) Collator
                 .getInstance(Locale.US);
@@ -351,45 +228,16 @@
         }
 
     }
-    @TestTargets({
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "setDecomposition",
-            args = {int.class}
-        ),
-        @TestTargetNew(
-            level = TestLevel.COMPLETE,
-            notes = "",
-            method = "getDecomposition",
-            args = {}
-        )
-    })
+
     public void testDecomposition() {
         RuleBasedCollator coll = (RuleBasedCollator) Collator
                 .getInstance(Locale.US);
-        
-        int [] decompositions = {Collator.NO_DECOMPOSITION, 
-                                 Collator.CANONICAL_DECOMPOSITION}; 
-        
-        for (int decom:decompositions) {
-            coll.setDecomposition(decom);
-            assertEquals(decom, coll.getDecomposition());
-        }
-        
-        try {
-            coll.setDecomposition(-1);
-            fail("IllegalArgumentException was not thrown.");
-        } catch(IllegalArgumentException iae) {
-            //expected
+        for (int i = 0; i < 2; i++) {
+            coll.setDecomposition(i);
+            assertEquals(i, coll.getDecomposition());
         }
     }
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getInstance",
-        args = {}
-    )
+
     public void testCollator_GetInstance() {
         Collator coll = Collator.getInstance();
         Object obj1 = "a";
@@ -399,29 +247,15 @@
         Collator.getInstance();
         assertFalse(coll.equals("A", "\uFF21"));
     }
-    
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        method = "getAvailableLocales",
-        args = {}
-    )
-    public void testGetAvaiableLocales() {
-        Locale[] locales = Collator.getAvailableLocales();
-        boolean isUS = false;
-        for (int i = 0; i < locales.length; i++) {
-            if(locales[i].equals(Locale.US))
-                isUS = true;
-        }
-        assertTrue("No Locale.US in the array.", isUS);
+
+    public void testGetAvailableLocales() {
+        // Locale[] locales = Collator.getAvailableLocales();
+        // for (int i = 0; i < locales.length; i++) {
+        // Locale locale = locales[i];
+        // }
     }
 
     // Test CollationKey
-    @TestTargetNew(
-        level = TestLevel.COMPLETE,
-        notes = "",
-        method = "getCollationKey",
-        args = {java.lang.String.class}
-    )
     public void testCollationKey() {
         Collator coll = Collator.getInstance(Locale.US);
         String text = "abc";
@@ -436,14 +270,8 @@
     /**
      * @tests java.text.RuleBasedCollator.RuleBasedCollator(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Verifies RuleBasedCollator(java.lang.String) constructor with null as a parameter.",
-        method = "RuleBasedCollator",
-        args = {java.lang.String.class}
-    )
     public void testNullPointerException() throws Exception {
-        // Regression for HARMONY-241
+        //Regression for HARMONY-241
         try {
             new RuleBasedCollator(null);
             fail("Constructor RuleBasedCollator(null) "
@@ -454,14 +282,8 @@
     /**
      * @tests java.text.RuleBasedCollator.compare(java.lang.String, java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Verifies null as parameters.",
-        method = "compare",
-        args = {java.lang.String.class, java.lang.String.class}
-    )
     public void testCompareNull() throws Exception {
-        // Regression for HARMONY-836
+        //Regression for HARMONY-836
         try {
             new RuleBasedCollator("< a").compare(null, null);
             fail("RuleBasedCollator.compare(null, null) "
@@ -472,24 +294,16 @@
     /**
      * @tests java.text.RuleBasedCollator.RuleBasedCollator(java.lang.String)
      */
-    @TestTargetNew(
-        level = TestLevel.PARTIAL,
-        notes = "Verifies empty string as a parameter.",
-        method = "RuleBasedCollator",
-        args = {java.lang.String.class}
-    )
-    @AndroidOnly("Android uses icu for collating. " +
-            "Icu has default UCA rules it uses to collate. " +
-            "To create a default instance with these rules an empty " +
-            "rule has to be passed to icu. This behavior is different " +
-            "from the RI which would throw an exception.")
     public void testEmptyStringException() {
+        //Regression for HARMONY-241
         try {
-            RuleBasedCollator coll = new RuleBasedCollator("");
-            assertTrue(coll.equals(new RuleBasedCollator("")));
-        } catch (ParseException e) {
+            new RuleBasedCollator("");
             fail("Constructor RuleBasedCollator(\"\") "
-                    + "should NOT throw ParseException.");
+                    + "should throw ParseException");
+        } catch (ParseException e) {
+            assertEquals("java.text.ParseException", e.getClass().getName());
+            assertEquals(0, e.getErrorOffset());
         }
     }
+
 }
diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java
index f96410f..0f77270 100644
--- a/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java
+++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/SimpleDateFormatTest.java
@@ -468,10 +468,6 @@
         method = "format",
         args = {java.util.Date.class, java.lang.StringBuffer.class, java.text.FieldPosition.class}
     )
-    @KnownFailure("SimpleDateFormat.format(Date date, " +
-            "StringBuffer toAppendTo, FieldPosition pos) " +
-            "return incorrect week number for \" W\" pattern. " + 
-            "Also Android doesn't support formatting of PST, EST, ...")
     public void test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition() {
         // Test for method java.lang.StringBuffer
         // java.text.SimpleDateFormat.format(java.util.Date,
@@ -672,7 +668,6 @@
             args = {java.lang.String.class}
         )
     })
-    @KnownFailure("Android doesn't support formatting of PST, EST, ...")
     public void test_timeZoneFormatting() {
         // tests specific to formatting of timezones
         Date summerDate = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3,
diff --git a/text/src/test/java/tests/text/AllTests.java b/text/src/test/java/tests/text/AllTests.java
index a3eb66d..25066fb 100644
--- a/text/src/test/java/tests/text/AllTests.java
+++ b/text/src/test/java/tests/text/AllTests.java
@@ -25,13 +25,8 @@
  * 
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All Text test suites");
+        TestSuite suite = new TestSuite("All Text test suites");
         // $JUnit-BEGIN$
         suite.addTest(org.apache.harmony.text.tests.java.text.AllTests.suite());
         // $JUnit-END$
diff --git a/tools/runner/expectations.txt b/tools/runner/expectations/brokentests.txt
similarity index 87%
rename from tools/runner/expectations.txt
rename to tools/runner/expectations/brokentests.txt
index 4c9f8e1..caf92e7 100644
--- a/tools/runner/expectations.txt
+++ b/tools/runner/expectations/brokentests.txt
@@ -1,3 +1,14 @@
+# This file contains expectations for tests that we don't ever intend to fix.
+
+# We're retiring the security manager. Unfortunately, tests all over the place
+# need to check that they're secure, so they all fail when we refuse to install
+# a security manager. This suppresses all of these failures.
+# http://b/issue?id=2585285
+failure disable securityManager
+result EXEC_FAILED
+pattern .*java.lang.UnsupportedOperationException\s+at java.lang.System.setSecurityManager.*
+
+
 # The RI avoids blocking calls when '\r' is the last character. We don't
 # bother since that adds complexity to every other read call, and '\r' as the
 # last character will be diminishingly rare anyway.
@@ -18,14 +29,16 @@
 pattern .*Test failed: should get token \[, but get -1.*
 
 
-# These tests rely on Java 6 APIs
-test java.util.Arrays.Big
-result COMPILE_FAILED
-pattern .*cannot find symbol.*
+# These tests only pass if the root logger hasn't yet been initialized. They
+# incorrectly assume that resetting the LogManager will clear the root logger's
+# resource bundle; this isn't the case.
+test org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLoggerWithRes_InvalidResourceBundle
+result EXEC_FAILED
+pattern .*java.lang.IllegalArgumentException: Resource bundle name 'impossible_not_existing' is inconsistent.*
 
-test java.util.Arrays.CopyMethods
-result COMPILE_FAILED
-pattern .*cannot find symbol.*
+test org.apache.harmony.logging.tests.java.util.logging.LoggerTest#testGetLogger_Empty
+result EXEC_FAILED
+pattern .*junit.framework.AssertionFailedError.*
 
 
 # Dalvik doesn't include the "SunJCE" crypto provider
@@ -674,6 +687,7 @@
 test sun.security.smartcardio
 result UNSUPPORTED
 
+
 # Our exception messages don't match the RIs
 test java.lang.StringBuilder.Exceptions
 result EXEC_FAILED
@@ -684,60 +698,45 @@
 pattern .*got java\.lang\.StringIndexOutOfBoundsException: null - FAILED.*
 
 
-# We don't expose Java 6 APIs
-test java.lang.String.IsEmpty
-result COMPILE_FAILED
-pattern .*cannot find symbol.*method isEmpty\(\).*
-
-test java.lang.String.Exceptions
-result COMPILE_FAILED
-pattern .*cannot find symbol.*new String.*
-
-test java.lang.String.Encodings
-result COMPILE_FAILED
-pattern .*cannot find symbol.*new String.*
-
-test java.io.File.GetXSpace
-result COMPILE_FAILED
-pattern .*cannot find symbol.*method getTotalSpace\(\).*
-
-test java.io.File.MaxPathLength
-result COMPILE_FAILED
-pattern .*cannot find symbol.*method getTotalSpace\(\).*
-
-test java.io.File.SetAccess (from File)
-result COMPILE_FAILED
-pattern .*method setWritable\(boolean,boolean\).*
-
-test java.io.PipedInputStream.Constructors
-result COMPILE_FAILED
-pattern .*constructor PipedInputStream\(int\).*
-
-test java.io.PipedReader.Constructors
-result COMPILE_FAILED
-pattern .*constructor PipedReader\(int\).*
-
-test java.io.File.SetAccess
-result COMPILE_FAILED
-pattern .*cannot find symbol.*method setWritable\(boolean,boolean\).*
-
-test java.io.PipedWriter.WriteAfterReaderClose
-result COMPILE_FAILED
-pattern .*cannot find symbol.*method clearError().*
-
-test java.io.PrintWriter.ClearErrorWriter
-result COMPILE_FAILED
-pattern .*cannot find symbol.*method clearError().*
-
-
-# A low-impact bug that we're ignoring: "Shared FileDescriptors get closed too early"
-#   http://code.google.com/p/android/issues/detail?id=5923
-test java.io.FileDescriptor.Finalize
+# this test is invalid, proxy.equals isn't symmetric
+test org.apache.harmony.luni.tests.java.util.HashMapTest#test_proxies
 result EXEC_FAILED
-pattern .*java.io.IOException.*openCheck.*
+
+
+# this test is invalid, the mock map's entry set isn't to spec
+test org.apache.harmony.luni.tests.java.util.HashMapTest.test_putAllLjava_util_Map
+result EXEC_FAILED
 
 
 # We don't have AWT
 test java.io.File.isDirectory.Applet
 result COMPILE_FAILED
 pattern .*package java.applet does not exist.*
+
+# ICU doesn't like 3-letter names like CST because they're ambiguous.
+# Harmony prefers them because they're more human readable. We'll be
+# consistent with ICU, since that seems least fragile.
+# See https://issues.apache.org/jira/browse/HARMONY-5468
+# and http://bugs.icu-project.org/trac/ticket/6174
+test org.apache.harmony.luni.tests.java.util.DateTest#test_toString
+result EXEC_FAILED
+pattern .*GMT-07:00.*
+
+
+# These harmony tests are broken. The RI doesn't ship with es__TRADITIONAL, so
+# they have incorrect expectations.
+# http://b/2608750
+
+test org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testGetCollationElementIteratorCharacterIterator
+result EXEC_FAILED
+pattern .*expected:<1> but was:<2>.*
+
+test org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testGetCollationElementIteratorString
+result EXEC_FAILED
+pattern .*expected:<1> but was:<2>.*
+
+# This test fails because on Android, RuleBasedCollators default to
+# CANONICAL_DECOMPOSITION, not NO_DECOMPOSITION.
+test org.apache.harmony.text.tests.java.text.RuleBasedCollatorTest#testEqualsObject
+result EXEC_FAILED
+pattern .*expected:<0> but was:<1>.*
diff --git a/tools/runner/expectations/todo.txt b/tools/runner/expectations/todo.txt
new file mode 100644
index 0000000..f3341a7
--- /dev/null
+++ b/tools/runner/expectations/todo.txt
@@ -0,0 +1,99 @@
+# This file contains expectations for tests that we'd like to eventually fix.
+# Severe problems should be accompanied by a tracking bug.
+
+# Dalvik doesn't support XML Schemas, DTDs or validation
+# http://code.google.com/p/android/issues/detail?id=7395
+test tests.xml.DomTest#testEntityDeclarations
+result EXEC_FAILED
+pattern .*This implementation does not parse entity declarations.*
+
+test tests.xml.DomTest#testGetWholeTextWithEntityReference
+result EXEC_FAILED
+pattern .*This implementation doesn't resolve entity references in getWholeText.*
+
+test tests.xml.DomTest#testIsElementContentWhitespaceWithDeclaration
+result EXEC_FAILED
+pattern .*This implementation does not recognize element content whitespace.*
+
+test tests.xml.DomTest#testNotations
+result EXEC_FAILED
+pattern .*This implementation does not parse notations.*
+
+test tests.xml.DeclarationTest#testGetXmlEncoding
+result EXEC_FAILED
+pattern .*This implementation doesn't parse the encoding from the XML declaration expected:<ISO-8859-1> but was:<null>.*
+
+test tests.xml.DeclarationTest#testGetXmlStandalone
+pattern .*This implementation doesn't parse standalone from the XML declaration expected:<true> but was:<false>.*
+result EXEC_FAILED
+
+test tests.xml.DeclarationTest#testGetXmlVersion
+pattern .*This implementation doesn't parse the version from the XML declaration expected:<...1> but was:<...0>.*
+result EXEC_FAILED
+
+test tests.xml.NormalizeTest#testSchemaTypeDtd
+result EXEC_FAILED
+pattern .*This implementation's setParameter\(\) supports an unexpected value: schema-type=http://www.w3.org/TR/REC-xml.*
+
+test tests.api.javax.xml.parsers.DocumentBuilderTest#testSetEntityResolver
+result EXEC_FAILED
+pattern .*java.lang.ClassCastException: org.apache.harmony.xml.dom.EntityReferenceImpl.*
+
+
+# low-impact XML bugs:
+test tests.xml.DomTest#testAttributeNamedIdIsNotAnIdByDefault
+result EXEC_FAILED
+pattern .*This implementation incorrectly interprets the "id" attribute as an identifier by default.*
+
+test tests.xml.DomTest#testDocumentAddChild
+result EXEC_FAILED
+pattern .*Document nodes shouldn't accept child nodes.*
+
+test tests.xml.DomTest#testElementTraversalFeature
+result EXEC_FAILED
+pattern .*This implementation is expected to support ElementTraversal v. 1.0 but does not..*
+
+test tests.xml.DomTest#testLoadSaveFeature
+result EXEC_FAILED
+pattern .*This implementation is expected to support LS v. 3.0 but does not..*
+
+test tests.xml.SaxTest#testYesPrefixesYesNamespaces
+result EXEC_FAILED
+pattern .*The 'namespace-prefix' feature is not supported while the 'namespaces' feature is enabled..*
+
+test tests.api.javax.xml.parsers.SAXParserFactoryTest#test_newInstance
+result EXEC_FAILED
+pattern .*Expected FactoryConfigurationError was not thrown.*
+
+test tests.api.javax.xml.parsers.DocumentBuilderFactoryTest#test_isSetXIncludeAware
+result EXEC_FAILED
+pattern .*java.lang.UnsupportedOperationException: This parser does not support specification "Unknown" version "0.0".*
+
+test tests.api.javax.xml.parsers.DocumentBuilderTest#testIsXIncludeAware
+result EXEC_FAILED
+pattern .*java.lang.UnsupportedOperationException: This parser does not support specification "Unknown" version "0.0".*
+
+test tests.api.javax.xml.parsers.SAXParserFactoryTest#test_setIsXIncludeAware
+result EXEC_FAILED
+pattern .*java.lang.UnsupportedOperationException: This parser does not support specification "Unknown" version "0.0".*
+
+test tests.api.javax.xml.parsers.SAXParserTest#testIsXIncludeAware
+result EXEC_FAILED
+pattern .*java.lang.UnsupportedOperationException: This parser does not support specification "Unknown" version "0.0".*
+
+# a low-impact bug: "Shared FileDescriptors get closed too early"
+#   http://code.google.com/p/android/issues/detail?id=5923
+test java.io.FileDescriptor.Finalize
+result EXEC_FAILED
+pattern .*java.io.IOException.*openCheck.*
+
+
+# a low-impact bug, also present in Crockford's implementation of org.json
+test org.json.ParsingTest#test64BitHexValues
+result EXEC_FAILED
+pattern .*Large hex longs shouldn't be yield ints or strings expected:<-1> but was:<0xFFFFFFFFFFFFFFFF>.*
+
+
+# this test needs to be fixed. We supply optional qnames, but this test doesn't expect them
+test tests.api.javax.xml.parsers.SAXParserTest#test_parseLjava_io_InputStreamLorg_xml_sax_helpers_DefaultHandlerLjava_lang_String
+result EXEC_FAILED
diff --git a/tools/runner/java/dalvik/runner/ActivityMode.java b/tools/runner/java/dalvik/runner/ActivityMode.java
deleted file mode 100644
index 163c72a..0000000
--- a/tools/runner/java/dalvik/runner/ActivityMode.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.TimeoutException;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.logging.Logger;
-
-/**
- * Runs a test in the context of an android.app.Activity on a device
- */
-final class ActivityMode extends Mode {
-
-    private static final Logger logger = Logger.getLogger(ActivityMode.class.getName());
-
-    private static final String TEST_ACTIVITY_CLASS   = "dalvik.runner.TestActivity";
-
-    ActivityMode(Integer debugPort, long timeoutSeconds, File sdkJar, PrintStream tee, File localTemp,
-            boolean cleanBefore, boolean cleanAfter, File deviceRunnerDir) {
-        super(new EnvironmentDevice(cleanBefore, cleanAfter,
-                debugPort, localTemp, deviceRunnerDir),
-                timeoutSeconds, sdkJar, tee);
-    }
-
-    private EnvironmentDevice getEnvironmentDevice() {
-        return (EnvironmentDevice) environment;
-    }
-
-    @Override protected void prepare(Set<File> testRunnerJava, Classpath testRunnerClasspath) {
-        testRunnerJava.add(new File("dalvik/libcore/tools/runner/lib/TestActivity.java"));
-        super.prepare(testRunnerJava, testRunnerClasspath);
-    }
-
-    @Override protected void postCompileTestRunner() {
-    }
-
-    @Override protected void postCompileTest(TestRun testRun) {
-        logger.fine("aapt and push " + testRun.getQualifiedName());
-
-        // Some things of note:
-        // 1. we can't put multiple dex files in one apk
-        // 2. we can't just give dex multiple jars with conflicting class names
-        // 3. dex is slow if we give it too much to chew on
-        // 4. dex can run out of memory if given too much to chew on
-
-        // With that in mind, the APK packaging strategy is as follows:
-        // 1. make an empty classes temporary directory
-        // 2. add test runner classes
-        // 3. find original jar test came from, add contents to classes
-        // 4. add supported runner classes specified by finder
-        // 5. add latest test classes to output
-        // 6. dx to create a dex
-        // 7. aapt the dex to create apk
-        // 8. sign the apk
-        // 9. install the apk
-        File packagingDir = makePackagingDirectory(testRun);
-        addTestRunnerClasses(packagingDir);
-        List<File> found = new ArrayList<File>();
-        File originalTestJar = findOriginalTestJar(testRun);
-        if (originalTestJar != null) {
-            found.add(originalTestJar);
-        }
-        found.addAll(testRun.getRunnerClasspath().getElements());
-        extractJars(packagingDir, found);
-        addTestClasses(testRun, packagingDir);
-        File dex = createDex(testRun, packagingDir);
-        File apkUnsigned = createApk(testRun, dex);
-        File apkSigned = signApk(testRun, apkUnsigned);
-        installApk(testRun, apkSigned);
-    }
-
-    private File makePackagingDirectory(TestRun testRun) {
-        File packagingDir = new File(environment.testCompilationDir(testRun), "packaging");
-        new Rm().directoryTree(packagingDir);
-        new Mkdir().mkdirs(packagingDir);
-        return packagingDir;
-    }
-
-    private void addTestRunnerClasses(File packagingDir) {
-        new Command("rsync", "-a",
-                    environment.testRunnerClassesDir() + "/",
-                    packagingDir + "/").execute();
-    }
-
-    private File findOriginalTestJar(TestRun testRun) {
-        String testClass = testRun.getTestClass();
-        String testFile = testClass.replace('.', '/') + ".class";
-        for (File element : testClasspath.getElements()) {
-            try {
-                JarFile jar = new JarFile(element);
-                JarEntry jarEntry = jar.getJarEntry(testFile);
-                if (jarEntry != null) {
-                    return element;
-                }
-            } catch (IOException e) {
-                throw new RuntimeException(
-                        "Could not find element " + element +
-                        " of test class path " + testClasspath, e);
-            }
-        }
-        return null;
-    }
-
-    private static void extractJars(File packagingDir, List<File> jars) {
-        for (File jar : jars) {
-            new Command.Builder()
-                    .args("unzip")
-                    .args("-q")
-                    .args("-o")
-                    .args(jar)
-                    .args("-d")
-                    .args(packagingDir).execute();
-        }
-        new Rm().directoryTree(new File(packagingDir, "META-INF"));
-    }
-
-    private void addTestClasses(TestRun testRun, File packagingDir) {
-        File testClassesDir = environment.testClassesDir(testRun);
-        new Command("rsync", "-a",
-                    testClassesDir + "/",
-                    packagingDir + "/").execute();
-    }
-    private File createDex (TestRun testRun, File packagingDir) {
-        File testClassesDir = environment.testClassesDir(testRun);
-        File dex = new File(testClassesDir + ".dex");
-        new Dx().dex(dex, Classpath.of(packagingDir));
-        return dex;
-    }
-
-    /**
-     * According to android.content.pm.PackageParser, package name
-     * "must have at least one '.' separator" Since the qualified name
-     * may not contain a dot, we prefix containing one to ensure we
-     * are compliant.
-     */
-    private static String packageName(TestRun testRun) {
-        return "DalvikRunner." + testRun.getQualifiedName();
-    }
-
-    private File createApk (TestRun testRun, File dex) {
-        String androidManifest =
-            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
-            "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
-            "      package=\"" + packageName(testRun) + "\">\n" +
-            "    <uses-permission android:name=\"android.permission.INTERNET\" />\n" +
-            "    <application>\n" +
-            "        <activity android:name=\"" + TEST_ACTIVITY_CLASS + "\">\n" +
-            "            <intent-filter>\n" +
-            "                <action android:name=\"android.intent.action.MAIN\" />\n" +
-            "                <category android:name=\"android.intent.category.LAUNCHER\" />\n" +
-            "            </intent-filter>\n" +
-            "        </activity>\n" +
-            "    </application>\n" +
-            "</manifest>\n";
-        File androidManifestFile =
-                new File(environment.testCompilationDir(testRun),
-                        "AndroidManifest.xml");
-        try {
-            FileOutputStream androidManifestOut =
-                    new FileOutputStream(androidManifestFile);
-            androidManifestOut.write(androidManifest.getBytes("UTF-8"));
-            androidManifestOut.close();
-        } catch (IOException e) {
-            throw new RuntimeException("Problem writing " + androidManifestFile, e);
-        }
-
-        File testClassesDir = environment.testClassesDir(testRun);
-        File apkUnsigned = new File(testClassesDir + ".apk.unsigned");
-        new Aapt().apk(apkUnsigned, androidManifestFile);
-        new Aapt().add(apkUnsigned, dex);
-        new Aapt().add(apkUnsigned, new File(testClassesDir, TestProperties.FILE));
-        return apkUnsigned;
-    }
-
-    private File signApk(TestRun testRun, File apkUnsigned) {
-        File testClassesDir = environment.testClassesDir(testRun);
-        File apkSigned = new File(testClassesDir, testRun.getQualifiedName() + ".apk");
-        // TODO: we should be able to work with a shipping SDK, not depend on out/...
-        // TODO: we should be able to work without hardwired keys, not depend on build/...
-        new Command.Builder()
-                .args("java")
-                .args("-jar")
-                .args("out/host/linux-x86/framework/signapk.jar")
-                .args("build/target/product/security/testkey.x509.pem")
-                .args("build/target/product/security/testkey.pk8")
-                .args(apkUnsigned)
-                .args(apkSigned).execute();
-        new Rm().file(apkUnsigned);
-        return apkSigned;
-    }
-
-    private void installApk(TestRun testRun, File apkSigned) {
-        // install the local apk ona the device
-        getEnvironmentDevice().adb.uninstall(packageName(testRun));
-        getEnvironmentDevice().adb.install(apkSigned);
-    }
-
-    @Override protected void fillInProperties(Properties properties, TestRun testRun) {
-        super.fillInProperties(properties, testRun);
-        properties.setProperty(TestProperties.DEVICE_RUNNER_DIR, getEnvironmentDevice().runnerDir.getPath());
-    }
-
-    @Override protected List<String> runTestCommand(TestRun testRun)
-            throws TimeoutException {
-        new Command(
-            "adb", "shell", "am", "start",
-            "-a","android.intent.action.MAIN",
-            "-n", (packageName(testRun) + "/" + TEST_ACTIVITY_CLASS)).executeWithTimeout(timeoutSeconds);
-
-        File resultDir = new File(getEnvironmentDevice().runnerDir, testRun.getQualifiedName());
-        File resultFile = new File(resultDir, TestProperties.RESULT_FILE);
-        getEnvironmentDevice().adb.waitForFile(resultFile, timeoutSeconds);
-        return new Command.Builder()
-            .args("adb", "shell", "cat", resultFile.getPath())
-            .tee(tee)
-            .build().executeWithTimeout(timeoutSeconds);
-    }
-
-    @Override void cleanup(TestRun testRun) {
-        super.cleanup(testRun);
-        if (environment.cleanAfter) {
-            getEnvironmentDevice().adb.uninstall(testRun.getQualifiedName());
-        }
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/CaliperFinder.java b/tools/runner/java/dalvik/runner/CaliperFinder.java
deleted file mode 100644
index 3609471..0000000
--- a/tools/runner/java/dalvik/runner/CaliperFinder.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-
-/**
- * Create {@link TestRun}s for {@code .java} files with Caliper benchmarks in
- * them.
- */
-class CaliperFinder extends NamingPatternCodeFinder {
-
-    @Override protected boolean matches(File file) {
-        return file.getName().endsWith("Benchmark.java");
-    }
-
-    @Override protected String testName(File file) {
-        return "caliper";
-    }
-
-    public Class<? extends Runner> getRunnerClass() {
-        return CaliperRunner.class;
-    }
-
-    public File getRunnerJava() {
-        return new File(DalvikRunner.HOME_JAVA, "dalvik/runner/CaliperRunner.java");
-    }
-
-    public Classpath getRunnerClasspath() {
-        return new Classpath();
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/CodeFinder.java b/tools/runner/java/dalvik/runner/CodeFinder.java
deleted file mode 100644
index f770fa4..0000000
--- a/tools/runner/java/dalvik/runner/CodeFinder.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.util.Set;
-
-/**
- * A strategy for finding runnable things in a directory.
- */
-public interface CodeFinder {
-
-    /**
-     * Returns all test runs in the given file or directory. If the returned set
-     * is empty, no executable code of this kind were found.
-     */
-    public Set<TestRun> findTests(File file);
-
-    /**
-     * Return the class for the TestRunner
-     */
-    public Class<? extends Runner> getRunnerClass();
-
-    /**
-     * Return the Java file for the TestRunner
-     */
-    public File getRunnerJava();
-
-    /**
-     * Return the compile classpath for the TestRunner
-     */
-    public Classpath getRunnerClasspath();
-}
diff --git a/tools/runner/java/dalvik/runner/DalvikRunner.java b/tools/runner/java/dalvik/runner/DalvikRunner.java
deleted file mode 100644
index c78866e..0000000
--- a/tools/runner/java/dalvik/runner/DalvikRunner.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Formatter;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-
-/**
- * Command line interface for running benchmarks and tests on dalvik.
- */
-public final class DalvikRunner {
-
-    static final File HOME = new File("dalvik/libcore/tools/runner");
-    static final File HOME_JAVA = new File(HOME, "java");
-
-    private static class Options {
-
-        private final List<File> testFiles = new ArrayList<File>();
-
-        @Option(names = { "--expectations" })
-        private Set<File> expectationFiles = new LinkedHashSet<File>();
-        {
-            expectationFiles.add(new File("dalvik/libcore/tools/runner/expectations.txt"));
-        }
-
-        private static String MODE_DEVICE = "device";
-        private static String MODE_HOST = "host";
-        private static String MODE_ACTIVITY = "activity";
-        @Option(names = { "--mode" })
-        private String mode = MODE_DEVICE;
-
-        @Option(names = { "--timeout" })
-        private long timeoutSeconds = 10 * 60; // default is ten minutes;
-
-        @Option(names = { "--clean-before" })
-        private boolean cleanBefore = true;
-
-        @Option(names = { "--clean-after" })
-        private boolean cleanAfter = true;
-
-        @Option(names = { "--clean" })
-        private boolean clean = true;
-
-        @Option(names = { "--xml-reports-directory" })
-        private File xmlReportsDirectory;
-
-        @Option(names = { "--verbose" })
-        private boolean verbose;
-
-        @Option(names = { "--tee" })
-        private String teeName;
-        private PrintStream tee;
-
-        @Option(names = { "--debug" })
-        private Integer debugPort;
-
-        @Option(names = { "--device-runner-dir" })
-        private File deviceRunnerDir = new File("/sdcard/dalvikrunner");
-
-        @Option(names = { "--vm-arg" })
-        private List<String> vmArgs = new ArrayList<String>();
-
-        @Option(names = { "--java-home" })
-        private File javaHome;
-
-        @Option(names = { "--sdk" })
-        private File sdkJar = new File("/home/dalvik-prebuild/android-sdk-linux/platforms/android-2.0/android.jar");
-
-        private void printUsage() {
-            System.out.println("Usage: DalvikRunner [options]... <tests>...");
-            System.out.println();
-            System.out.println("  <tests>: a .java file containing a jtreg test, JUnit test,");
-            System.out.println("      Caliper benchmark, or a directory of such tests.");
-            System.out.println();
-            System.out.println("GENERAL OPTIONS");
-            System.out.println();
-            System.out.println("  --expectations <file>: include the specified file when looking for");
-            System.out.println("      test expectations. The file should include qualified test names");
-            System.out.println("      and the corresponding expected output.");
-            System.out.println("      Default is: " + expectationFiles);
-            System.out.println();
-            System.out.println("  --mode <device|host|activity>: specify which environment to run the");
-            System.out.println("      tests in. Options are on the device VM, on the host VM, and on");
-            System.out.println("      device within an android.app.Activity.");
-            System.out.println("      Default is: " + mode);
-            System.out.println();
-            System.out.println("  --clean-before: remove working directories before building and");
-            System.out.println("      running (default). Disable with --no-clean-before if you are");
-            System.out.println("      using interactively with your own temporary input files.");
-            System.out.println();
-            System.out.println("  --clean-after: remove temporary files after running (default).");
-            System.out.println("      Disable with --no-clean-after and use with --verbose if");
-            System.out.println("      you'd like to manually re-run commands afterwards.");
-            System.out.println();
-            System.out.println("  --clean: synonym for --clean-before and --clean-after (default).");
-            System.out.println("      Disable with --no-clean if you want no files removed.");
-            System.out.println();
-            System.out.println("  --tee <file>: emit test output to file during execution.");
-            System.out.println("      Specify '-' for stdout.");
-            System.out.println();
-            System.out.println("  --timeout-seconds <seconds>: maximum execution time of each");
-            System.out.println("      test before the runner aborts it.");
-            System.out.println("      Default is: " + timeoutSeconds);
-            System.out.println();
-            System.out.println("  --xml-reports-directory <path>: directory to emit JUnit-style");
-            System.out.println("      XML test results.");
-            System.out.println();
-            System.out.println("  --verbose: turn on verbose output");
-            System.out.println();
-            System.out.println("DEVICE OPTIONS");
-            System.out.println();
-            System.out.println("  --debug <port>: enable Java debugging on the specified port.");
-            System.out.println("      This port must be free both on the device and on the local");
-            System.out.println("      system.");
-            System.out.println();
-            System.out.println("  --device-runner-dir <directory>: use the specified directory for");
-            System.out.println("      on-device temporary files and code.");
-            System.out.println("      Default is: " + deviceRunnerDir);
-            System.out.println();
-            System.out.println("GENERAL VM OPTIONS");
-            System.out.println();
-            System.out.println("  --vm-arg <argument>: include the specified argument when spawning a");
-            System.out.println("      virtual machine. Examples: -Xint:fast, -ea, -Xmx16M");
-            System.out.println();
-            System.out.println("HOST VM OPTIONS");
-            System.out.println();
-            System.out.println("  --java-home <java_home>: execute the tests on the local workstation");
-            System.out.println("      using the specified java home directory. This does not impact");
-            System.out.println("      which javac gets used. When unset, java is used from the PATH.");
-            System.out.println();
-            System.out.println("COMPILE OPTIONS");
-            System.out.println();
-            System.out.println("  --sdk <android jar>: the API jar file to compile against.");
-            System.out.println("      Usually this is <SDK>/platforms/android-<X.X>/android.jar");
-            System.out.println("      where <SDK> is the path to an Android SDK path and <X.X> is");
-            System.out.println("      a release version like 1.5.");
-            System.out.println("      Default is: " + sdkJar);
-            System.out.println();
-        }
-
-        private boolean parseArgs(String[] args) {
-            final List<String> testFilenames;
-            try {
-                testFilenames = new OptionParser(this).parse(args);
-            } catch (RuntimeException e) {
-                System.out.println(e.getMessage());
-                return false;
-            }
-
-            //
-            // Semantic error validation
-            //
-
-            boolean device;
-            boolean vm;
-            if (mode.equals(MODE_DEVICE)) {
-                device = true;
-                vm = true;
-            } else if (mode.equals(MODE_HOST)) {
-                device = false;
-                vm = true;
-            } else if (mode.equals(MODE_ACTIVITY)) {
-                device = true;
-                vm = false;
-            } else {
-                System.out.println("Unknown mode: " + mode);
-                return false;
-            }
-
-
-            if (device) { // check device option consistency
-                if (javaHome != null) {
-                    System.out.println("java home " + javaHome + " should not be specified for mode " + mode);
-                    return false;
-                }
-
-            } else { // check host (!device) option consistency
-                if (javaHome != null && !new File(javaHome, "/bin/java").exists()) {
-                    System.out.println("Invalid java home: " + javaHome);
-                    return false;
-                }
-            }
-
-            // check vm option consistency
-            if (!vm) {
-                if (!vmArgs.isEmpty()) {
-                    System.out.println("vm args " + vmArgs + " should not be specified for mode " + mode);
-                    return false;
-                }
-            }
-
-            if (!sdkJar.exists()) {
-                System.out.println("Could not find SDK jar: " + sdkJar);
-                return false;
-            }
-
-            if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) {
-                System.out.println("Invalid XML reports directory: " + xmlReportsDirectory);
-                return false;
-            }
-
-            if (testFilenames.isEmpty()) {
-                System.out.println("No tests provided.");
-                return false;
-            }
-
-            if (!clean) {
-                cleanBefore = false;
-                cleanAfter = false;
-            }
-
-            //
-            // Post-processing arguments
-            //
-
-            for (String testFilename : testFilenames) {
-                testFiles.add(new File(testFilename));
-            }
-
-            if (teeName != null) {
-                if (teeName.equals("-")) {
-                    tee = System.out;
-                } else {
-                    try {
-                        tee = new PrintStream(new BufferedOutputStream(new FileOutputStream(teeName)));
-                    } catch (FileNotFoundException e) {
-                        System.out.println("Could not open file teeName: " + e);
-                        return false;
-                    }
-                }
-            }
-
-            if (verbose) {
-                Logger.getLogger("dalvik.runner").setLevel(Level.FINE);
-            }
-
-            return true;
-        }
-
-    }
-
-    private final Options options = new Options();
-    private final File localTemp = new File("/tmp/dalvikrunner/" + UUID.randomUUID());
-
-    private DalvikRunner() {}
-
-    private void prepareLogging() {
-        ConsoleHandler handler = new ConsoleHandler();
-        handler.setLevel(Level.ALL);
-        handler.setFormatter(new Formatter() {
-            @Override public String format(LogRecord r) {
-                return r.getMessage() + "\n";
-            }
-        });
-        Logger logger = Logger.getLogger("dalvik.runner");
-        logger.addHandler(handler);
-        logger.setUseParentHandlers(false);
-    }
-
-    private void run() {
-        Mode mode;
-        if (options.mode.equals(Options.MODE_DEVICE)) {
-            mode = new DeviceDalvikVm(
-                    options.debugPort,
-                    options.timeoutSeconds,
-                    options.sdkJar,
-                    options.tee,
-                    localTemp,
-                    options.vmArgs,
-                    options.cleanBefore,
-                    options.cleanAfter,
-                    options.deviceRunnerDir);
-        } else if (options.mode.equals(Options.MODE_HOST)) {
-            mode = new JavaVm(
-                    options.debugPort,
-                    options.timeoutSeconds,
-                    options.sdkJar,
-                    options.tee,
-                    localTemp,
-                    options.javaHome,
-                    options.vmArgs,
-                    options.cleanBefore,
-                    options.cleanAfter);
-        } else if (options.mode.equals(Options.MODE_ACTIVITY)) {
-            mode = new ActivityMode(
-                    options.debugPort,
-                    options.timeoutSeconds,
-                    options.sdkJar,
-                    options.tee,
-                    localTemp,
-                    options.cleanBefore,
-                    options.cleanAfter,
-                    options.deviceRunnerDir);
-        } else {
-            System.out.println("Unknown mode mode " + options.mode + ".");
-            return;
-        }
-
-        List<CodeFinder> codeFinders = Arrays.asList(
-                new JtregFinder(localTemp),
-                new JUnitFinder(),
-                new CaliperFinder(),
-                new MainFinder());
-        Driver driver = new Driver(
-                localTemp,
-                mode,
-                options.expectationFiles,
-                options.xmlReportsDirectory,
-                codeFinders);
-        try {
-            driver.loadExpectations();
-        } catch (IOException e) {
-            System.out.println("Problem loading expectations: " + e);
-            return;
-        }
-
-        driver.buildAndRunAllTests(options.testFiles);
-        mode.shutdown();
-    }
-
-    public static void main(String[] args) {
-        DalvikRunner dalvikRunner = new DalvikRunner();
-        if (!dalvikRunner.options.parseArgs(args)) {
-            dalvikRunner.options.printUsage();
-            return;
-        }
-        dalvikRunner.prepareLogging();
-        dalvikRunner.run();
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/DeviceDalvikVm.java b/tools/runner/java/dalvik/runner/DeviceDalvikVm.java
deleted file mode 100644
index 061e374..0000000
--- a/tools/runner/java/dalvik/runner/DeviceDalvikVm.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * Execute tests on a Dalvik VM using an Android device or emulator.
- */
-final class DeviceDalvikVm extends Vm {
-    private static final Logger logger = Logger.getLogger(DeviceDalvikVm.class.getName());
-
-    DeviceDalvikVm(Integer debugPort, long timeoutSeconds, File sdkJar, PrintStream tee,
-            File localTemp, List<String> additionalVmArgs,
-            boolean cleanBefore, boolean cleanAfter, File runnerDir) {
-        super(new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, localTemp, runnerDir),
-                timeoutSeconds, sdkJar, tee, additionalVmArgs);
-    }
-
-    private EnvironmentDevice getEnvironmentDevice() {
-        return (EnvironmentDevice) environment;
-    }
-
-    @Override protected void postCompileTestRunner() {
-        // TODO: does this really need to be a special case?
-        postCompile("testrunner", environment.testRunnerClassesDir());
-
-        // dex everything on the classpath and push it to the device.
-        for (File classpathElement : testClasspath.getElements()) {
-            String name = basenameOfJar(classpathElement);
-            logger.fine("dex and push " + name);
-            // make the local dex (inside a jar)
-            // TODO: this is *really* expensive. we need a cache!
-            File outputFile = getEnvironmentDevice().testDir(name + ".jar");
-            new Dx().dex(outputFile, Classpath.of(classpathElement));
-            // push the local dex to the device
-            getEnvironmentDevice().adb.push(outputFile, deviceDexFile(name));
-        }
-    }
-
-    private String basenameOfJar(File jarFile) {
-        return jarFile.getName().replaceAll("\\.jar$", "");
-    }
-
-    @Override protected void postCompileTest(TestRun testRun) {
-        postCompile(testRun.getQualifiedName(), environment.testClassesDir(testRun));
-    }
-
-    private void postCompile(String name, File dir) {
-        logger.fine("dex and push " + name);
-
-        // make the local dex (inside a jar)
-        File localDex = new File(dir.getPath() + ".jar");
-        new Dx().dex(localDex, Classpath.of(dir));
-
-        // post the local dex to the device
-        File deviceDex = deviceDexFile(name);
-        getEnvironmentDevice().adb.push(localDex, deviceDex);
-    }
-
-    private File deviceDexFile(String name) {
-        return new File(getEnvironmentDevice().runnerDir, name + ".jar");
-    }
-
-    @Override protected VmCommandBuilder newVmCommandBuilder(
-            File workingDirectory) {
-        // ignore the working directory; it's device-local and we can't easily
-        // set the working directory for commands run via adb shell.
-        // TODO: we only *need* to set ANDROID_DATA on production devices.
-        // We set "user.home" to /sdcard because code might reasonably assume it can write to
-        // that directory.
-        return new VmCommandBuilder()
-                .vmCommand("adb", "shell", "ANDROID_DATA=/sdcard", "dalvikvm")
-                .vmArgs("-Duser.home=/sdcard")
-                .vmArgs("-Duser.name=root")
-                .vmArgs("-Duser.language=en")
-                .vmArgs("-Duser.region=US")
-                .vmArgs("-Djavax.net.ssl.trustStore=/system/etc/security/cacerts.bks")
-                .temp(getEnvironmentDevice().testTemp);
-    }
-
-    @Override protected Classpath getRuntimeSupportClasspath(TestRun testRun) {
-        Classpath classpath = new Classpath();
-        classpath.addAll(deviceDexFile(testRun.getQualifiedName()));
-        classpath.addAll(deviceDexFile("testrunner"));
-        for (File testClasspathElement : testClasspath.getElements()) {
-            classpath.addAll(deviceDexFile(basenameOfJar(testClasspathElement)));
-        }
-        return classpath;
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/Driver.java b/tools/runner/java/dalvik/runner/Driver.java
deleted file mode 100644
index 574c8cb..0000000
--- a/tools/runner/java/dalvik/runner/Driver.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-
-/**
- * Compiles, installs, runs and reports tests.
- */
-final class Driver {
-
-    private static final Logger logger = Logger.getLogger(Driver.class.getName());
-
-    private final File localTemp;
-    private final Set<File> expectationFiles;
-    private final List<CodeFinder> codeFinders;
-    private final Mode mode;
-    private final File xmlReportsDirectory;
-    private final Map<String, ExpectedResult> expectedResults = new HashMap<String, ExpectedResult>();
-
-    /**
-     * The number of tests that weren't run because they aren't supported by
-     * this runner.
-     */
-    private int unsupportedTests = 0;
-
-    public Driver(File localTemp, Mode mode, Set<File> expectationFiles,
-            File xmlReportsDirectory, List<CodeFinder> codeFinders) {
-        this.localTemp = localTemp;
-        this.expectationFiles = expectationFiles;
-        this.mode = mode;
-        this.xmlReportsDirectory = xmlReportsDirectory;
-        this.codeFinders = codeFinders;
-    }
-
-    public void loadExpectations() throws IOException {
-        for (File f : expectationFiles) {
-            if (f.exists()) {
-                expectedResults.putAll(ExpectedResult.parse(f));
-            }
-        }
-    }
-
-    /**
-     * Builds and executes all tests in the test directory.
-     */
-    public void buildAndRunAllTests(Collection<File> testFiles) {
-        new Mkdir().mkdirs(localTemp);
-
-        Set<TestRun> tests = new LinkedHashSet<TestRun>();
-        for (File testFile : testFiles) {
-            Set<TestRun> testsForFile = Collections.emptySet();
-
-            for (CodeFinder codeFinder : codeFinders) {
-                testsForFile = codeFinder.findTests(testFile);
-
-                // break as soon as we find any match. We don't need multiple
-                // matches for the same file, since that would run it twice.
-                if (!testsForFile.isEmpty()) {
-                    break;
-                }
-            }
-
-            tests.addAll(testsForFile);
-        }
-
-        // compute TestRunner java and classpath to pass to mode.prepare
-        Set<File> testRunnerJava = new HashSet<File>();
-        Classpath testRunnerClasspath = new Classpath();
-        for (final TestRun testRun : tests) {
-            testRunnerJava.add(testRun.getRunnerJava());
-            testRunnerClasspath.addAll(testRun.getRunnerClasspath());
-        }
-
-        // mode.prepare before mode.buildAndInstall to ensure test
-        // runner is built. packaging of activity APK files needs the
-        // test runner along with the test specific files.
-        mode.prepare(testRunnerJava, testRunnerClasspath);
-
-        logger.info("Running " + tests.size() + " tests.");
-
-        // build and install tests in a background thread. Using lots of
-        // threads helps for packages that contain many unsupported tests
-        final BlockingQueue<TestRun> readyToRun = new ArrayBlockingQueue<TestRun>(4);
-
-        ExecutorService builders = Threads.threadPerCpuExecutor();
-        int t = 0;
-        for (final TestRun testRun : tests) {
-            final int runIndex = t++;
-            builders.submit(new Runnable() {
-                public void run() {
-                    try {
-                        ExpectedResult expectedResult = lookupExpectedResult(testRun);
-                        testRun.setExpectedResult(expectedResult);
-
-                        if (expectedResult.getResult() == Result.UNSUPPORTED) {
-                            testRun.setResult(Result.UNSUPPORTED, Collections.<String>emptyList());
-                            logger.fine("skipping test " + testRun
-                                    + " because the expectations file says it is unsupported.");
-
-                        } else {
-                            mode.buildAndInstall(testRun);
-                            logger.fine("installed test " + runIndex + "; "
-                                    + readyToRun.size() + " are ready to run");
-                        }
-
-                        readyToRun.put(testRun);
-                    } catch (Throwable throwable) {
-                        testRun.setResult(Result.ERROR, throwable);
-                    }
-                }
-            });
-        }
-        builders.shutdown();
-
-        List<TestRun> runs = new ArrayList<TestRun>(tests.size());
-        for (int i = 0; i < tests.size(); i++) {
-            logger.fine("executing test " + i + "; "
-                    + readyToRun.size() + " are ready to run");
-
-            // if it takes 5 minutes for build and install, something is broken
-            TestRun testRun;
-            try {
-                testRun = readyToRun.poll(5 * 60, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Unexpected interruption waiting for build and install", e);
-            }
-
-            if (testRun == null) {
-                throw new IllegalStateException("Expected " + tests.size() + " tests but found only " + i);
-            }
-
-            runs.add(testRun);
-            execute(testRun);
-            mode.cleanup(testRun);
-        }
-
-        if (unsupportedTests > 0) {
-            logger.info("Skipped " + unsupportedTests + " unsupported tests.");
-        }
-
-        if (xmlReportsDirectory != null) {
-            logger.info("Printing XML Reports... ");
-            int numFiles = new XmlReportPrinter().generateReports(xmlReportsDirectory, runs);
-            logger.info(numFiles + " XML files written.");
-        }
-    }
-
-    /**
-     * Finds the expected result for the specified test run. This strips off
-     * parts of the test's qualified name until it either finds a match or runs
-     * out of name.
-     */
-    private ExpectedResult lookupExpectedResult(TestRun testRun) {
-        String name = testRun.getQualifiedName();
-
-        while (true) {
-            ExpectedResult expectedResult = expectedResults.get(name);
-            if (expectedResult != null) {
-                return expectedResult;
-            }
-
-            int dot = name.lastIndexOf('.');
-            if (dot == -1) {
-                return ExpectedResult.SUCCESS;
-            }
-
-            name = name.substring(0, dot);
-        }
-    }
-
-    /**
-     * Executes a single test and then prints the result.
-     */
-    private void execute(TestRun testRun) {
-        if (testRun.getResult() == Result.UNSUPPORTED) {
-            logger.fine("skipping " + testRun.getQualifiedName());
-            unsupportedTests++;
-            return;
-        }
-
-        if (testRun.isRunnable()) {
-            mode.runTest(testRun);
-        }
-
-        printResult(testRun);
-    }
-
-    private void printResult(TestRun testRun) {
-        if (testRun.isExpectedResult()) {
-            logger.info("OK " + testRun.getQualifiedName() + " (" + testRun.getResult() + ")");
-            // In --verbose mode, show the output even on success.
-            logger.fine("  " + testRun.getFailureMessage().replace("\n", "\n  "));
-            return;
-        }
-
-        logger.info("FAIL " + testRun.getQualifiedName() + " (" + testRun.getResult() + ")");
-        String description = testRun.getDescription();
-        if (description != null) {
-            logger.info("  \"" + description + "\"");
-        }
-
-        logger.info("  " + testRun.getFailureMessage().replace("\n", "\n  "));
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/Environment.java b/tools/runner/java/dalvik/runner/Environment.java
deleted file mode 100644
index c284a37..0000000
--- a/tools/runner/java/dalvik/runner/Environment.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.util.logging.Logger;
-
-/**
- * A target runtime environment such as a remote device or the local host
- */
-abstract class Environment {
-    private static final Logger logger = Logger.getLogger(Environment.class.getName());
-
-    final boolean cleanBefore;
-    final boolean cleanAfter;
-    final Integer debugPort;
-    private final File localTemp;
-
-    Environment (boolean cleanBefore, boolean cleanAfter, Integer debugPort, File localTemp) {
-        this.cleanBefore = cleanBefore;
-        this.cleanAfter = cleanAfter;
-        this.debugPort = debugPort;
-        this.localTemp = localTemp;
-    }
-
-    /**
-     * Initializes the temporary directories and test harness necessary to run
-     * tests.
-     */
-    abstract void prepare();
-
-    /**
-     * Prepares the directory from which the test will be executed. Some tests
-     * expect to read data files from the current working directory; this step
-     * should ensure such files are available.
-     */
-    abstract void prepareUserDir(TestRun testRun);
-
-    /**
-     * Deletes files and releases any resources required for the execution of
-     * the given test.
-     */
-    void cleanup(TestRun testRun) {
-        if (cleanAfter) {
-            logger.fine("clean " + testRun.getQualifiedName());
-            new Rm().directoryTree(testCompilationDir(testRun));
-            new Rm().directoryTree(testUserDir(testRun));
-        }
-    }
-
-    final File testDir(String name) {
-        return new File(localTemp, name);
-    }
-
-    final File testRunnerDir(String name) {
-        return new File(testDir("testrunner"), name);
-    }
-
-    final File testRunnerClassesDir() {
-        return testRunnerDir("classes");
-    }
-
-    final File testCompilationDir(TestRun testRun) {
-        return new File(localTemp, testRun.getQualifiedName());
-    }
-
-    final File testClassesDir(TestRun testRun) {
-        return new File(testCompilationDir(testRun), "classes");
-    }
-
-    final File testUserDir(TestRun testRun) {
-        File testTemp = new File(localTemp, "userDir");
-        return new File(testTemp, testRun.getQualifiedName());
-    }
-
-    abstract void shutdown();
-}
diff --git a/tools/runner/java/dalvik/runner/EnvironmentDevice.java b/tools/runner/java/dalvik/runner/EnvironmentDevice.java
deleted file mode 100644
index 9ac1c64..0000000
--- a/tools/runner/java/dalvik/runner/EnvironmentDevice.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.util.logging.Logger;
-
-class EnvironmentDevice extends Environment {
-    private static final Logger logger = Logger.getLogger(EnvironmentDevice.class.getName());
-
-    final Adb adb = new Adb();
-    final File runnerDir;
-    final File testTemp;
-
-    EnvironmentDevice (boolean cleanBefore, boolean cleanAfter,
-            Integer debugPort, File localTemp, File runnerDir) {
-        super(cleanBefore, cleanAfter, debugPort, localTemp);
-        this.runnerDir = runnerDir;
-        this.testTemp = new File(runnerDir, "/tests.tmp");
-    }
-
-    @Override void prepare() {
-        adb.waitForDevice();
-        adb.waitForNonEmptyDirectory(runnerDir.getParentFile(), 5 * 60);
-        if (cleanBefore) {
-            adb.rm(runnerDir);
-        }
-        adb.mkdir(runnerDir);
-        adb.mkdir(testTemp);
-        adb.mkdir(new File("/sdcard/dalvik-cache")); // TODO: only necessary on production devices.
-        if (debugPort != null) {
-            adb.forwardTcp(debugPort, debugPort);
-        }
-    }
-
-    @Override protected void prepareUserDir(TestRun testRun) {
-        File testClassesDirOnDevice = testClassesDirOnDevice(testRun);
-        adb.mkdir(testClassesDirOnDevice);
-        adb.push(testRun.getTestDirectory(), testClassesDirOnDevice);
-        testRun.setUserDir(testClassesDirOnDevice);
-    }
-
-    private File testClassesDirOnDevice(TestRun testRun) {
-        return new File(runnerDir, testRun.getQualifiedName());
-    }
-
-    @Override void cleanup(TestRun testRun) {
-        super.cleanup(testRun);
-        if (cleanAfter) {
-            adb.rm(testClassesDirOnDevice(testRun));
-        }
-    }
-
-    @Override void shutdown() {
-        if (cleanAfter) {
-            adb.rm(runnerDir);
-        }
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/ExpectedResult.java b/tools/runner/java/dalvik/runner/ExpectedResult.java
deleted file mode 100644
index a0244ce..0000000
--- a/tools/runner/java/dalvik/runner/ExpectedResult.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The expected outcome of a test execution. This is typically encoded in the
- * expectations text file, which has the following format:
- * <pre>
- * test java.io.StreamTokenizer.Reset
- * result UNSUPPORTED
- * pattern .*should get token \[, but get -1.*
- *
- * # should we fix this?
- * test java.util.Arrays.CopyMethods
- * result COMPILE_FAILED
- * pattern .*cannot find symbol.*
- * </pre>
- */
-class ExpectedResult {
-
-    private static final Logger logger = Logger.getLogger(ExpectedResult.class.getName());
-
-    /** Matches lines in the file containing a key and value pair. */
-    private static final Pattern KEY_VALUE_PAIR_PATTERN = Pattern.compile("(\\w+)\\s+(.+)");
-
-    /** The pattern to use when no expected output is specified */
-    private static final Pattern MATCH_ALL_PATTERN
-            = Pattern.compile(".*", Pattern.MULTILINE | Pattern.DOTALL);
-
-    /** The expectation of a general successful test run. */
-    static final ExpectedResult SUCCESS = new ExpectedResult(Result.SUCCESS, null);
-
-    /** The test's expected result, such as {@code EXEC_FAILED}. */
-    private final Result result;
-
-    /** The pattern the expected output will match. */
-    private final Pattern pattern;
-
-    private ExpectedResult(Result result, String pattern) {
-        if (result == null) {
-            throw new IllegalArgumentException();
-        }
-
-        this.result = result;
-        this.pattern = pattern != null
-                ? Pattern.compile(pattern, Pattern.MULTILINE | Pattern.DOTALL)
-                : MATCH_ALL_PATTERN;
-    }
-
-    public Result getResult() {
-        return result;
-    }
-
-    public Pattern getPattern() {
-        return pattern;
-    }
-
-    public static Map<String, ExpectedResult> parse(File expectationsFile)
-            throws IOException {
-        logger.fine("loading expectations file " + expectationsFile);
-
-        BufferedReader reader = new BufferedReader(new FileReader(expectationsFile));
-        try {
-            Map<String, ExpectedResult> results = new HashMap<String, ExpectedResult>();
-            Matcher keyValuePairMatcher = KEY_VALUE_PAIR_PATTERN.matcher("");
-
-            // the fields of interest for the current element
-            String qualifiedName = null;
-            Result result = null;
-            String pattern = null;
-
-            String line;
-            while ((line = reader.readLine()) != null) {
-                line = line.trim();
-
-                if (line.length() == 0 || line.startsWith("#")) {
-                    continue; // skip comment and blank lines
-                }
-
-                keyValuePairMatcher.reset(line);
-                if (!keyValuePairMatcher.matches()) {
-                    throw new IllegalArgumentException("Unexpected line " + line
-                            + " in file " + expectationsFile);
-                }
-
-                String key = keyValuePairMatcher.group(1);
-                String value = keyValuePairMatcher.group(2);
-                if (key.equals("result") && result == null) {
-                    result = Result.valueOf(value);
-
-                } else if (key.equals("pattern") && pattern == null) {
-                    pattern = value;
-
-                } else if (key.equals("test")) {
-                    // when we encounter a new qualified name, the previous
-                    // element is complete. Add it to the results.
-                    if (qualifiedName != null) {
-                        ExpectedResult expectation = new ExpectedResult(result, pattern);
-                        ExpectedResult previous = results.put(qualifiedName, expectation);
-                        if (previous != null) {
-                            throw new IllegalArgumentException(
-                                    "Duplicate expectations for " + qualifiedName);
-                        }
-
-                        result = null;
-                        pattern = null;
-                    }
-
-                    qualifiedName = value;
-
-                } else {
-                    throw new IllegalArgumentException("Unexpected key " + key
-                            + " in file " + expectationsFile);
-                }
-            }
-
-            // add the last element in the file
-            if (qualifiedName != null) {
-                ExpectedResult expectation = new ExpectedResult(result, pattern);
-                ExpectedResult previous = results.put(qualifiedName, expectation);
-                if (previous != null) {
-                    throw new IllegalArgumentException(
-                            "Duplicate expectations for " + qualifiedName);
-                }
-            }
-
-            logger.fine("loaded " + results.size() + " expectations.");
-            return results;
-        } finally {
-            reader.close();
-        }
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/JUnitFinder.java b/tools/runner/java/dalvik/runner/JUnitFinder.java
deleted file mode 100644
index 131a8cf..0000000
--- a/tools/runner/java/dalvik/runner/JUnitFinder.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-
-/**
- * Create {@link TestRun}s for {@code .java} files with JUnit tests in them.
- */
-class JUnitFinder extends NamingPatternCodeFinder {
-
-    @Override protected boolean matches(File file) {
-        return file.getName().endsWith("Test.java");
-    }
-
-    // TODO: try to get names for each method?
-    @Override protected String testName(File file) {
-        return "junit";
-    }
-
-    public Class<? extends Runner> getRunnerClass() {
-        return JUnitRunner.class;
-    }
-
-    public File getRunnerJava() {
-        return new File(DalvikRunner.HOME_JAVA, "dalvik/runner/JUnitRunner.java");
-    }
-
-    public Classpath getRunnerClasspath() {
-        // TODO: we should be able to work with a shipping SDK, not depend on out/...
-        return Classpath.of(new File("out/host/common/obj/JAVA_LIBRARIES/junit_intermediates/javalib.jar").getAbsoluteFile());
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/JUnitRunner.java b/tools/runner/java/dalvik/runner/JUnitRunner.java
deleted file mode 100644
index 4891448..0000000
--- a/tools/runner/java/dalvik/runner/JUnitRunner.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import junit.framework.Test;
-import junit.framework.TestResult;
-import junit.runner.TestSuiteLoader;
-
-/**
- * Runs a JUnit test.
- */
-public final class JUnitRunner implements Runner {
-
-    private final junit.textui.TestRunner testRunner;
-    private Test junitTest;
-
-    public JUnitRunner() {
-        final TestSuiteLoader testSuiteLoader = new TestSuiteLoader() {
-            public Class load(String suiteClassName) throws ClassNotFoundException {
-                return JUnitRunner.class.getClassLoader().loadClass(suiteClassName);
-            }
-
-            public Class reload(Class c) {
-                return c;
-            }
-        };
-
-        testRunner = new junit.textui.TestRunner() {
-            @Override public TestSuiteLoader getLoader() {
-                return testSuiteLoader;
-            }
-        };
-    }
-
-    public void prepareTest(Class<?> testClass) {
-        junitTest = testRunner.getTest(testClass.getName());
-    }
-
-    public boolean test(Class<?> testClass) {
-        TestResult result = testRunner.doRun(junitTest);
-        return result.wasSuccessful();
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/JavaVm.java b/tools/runner/java/dalvik/runner/JavaVm.java
deleted file mode 100644
index 38e0386..0000000
--- a/tools/runner/java/dalvik/runner/JavaVm.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A local Java virtual machine like Harmony or the RI.
- */
-final class JavaVm extends Vm {
-
-    private final File javaHome;
-
-    JavaVm(Integer debugPort, long timeoutSeconds, File sdkJar, PrintStream tee,
-            File localTemp, File javaHome, List<String> additionalVmArgs,
-            boolean cleanBefore, boolean cleanAfter) {
-        super(new EnvironmentHost(cleanBefore, cleanAfter, debugPort, localTemp),
-                timeoutSeconds, sdkJar, tee, additionalVmArgs);
-        this.javaHome = javaHome;
-    }
-
-    @Override protected void postCompileTestRunner() {
-    }
-
-    @Override protected void postCompileTest(TestRun testRun) {
-    }
-
-    @Override protected VmCommandBuilder newVmCommandBuilder(
-            File workingDirectory) {
-        String java = javaHome == null ? "java" : new File(javaHome, "bin/java").getPath();
-        return new VmCommandBuilder()
-                .vmCommand(java)
-                .workingDir(workingDirectory);
-    }
-    @Override protected Classpath getRuntimeSupportClasspath(TestRun testRun) {
-        Classpath classpath = new Classpath();
-        classpath.addAll(environment.testClassesDir(testRun));
-        classpath.addAll(testClasspath);
-        classpath.addAll(environment.testRunnerClassesDir());
-        classpath.addAll(testRunnerClasspath);
-        return classpath;
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/Mode.java b/tools/runner/java/dalvik/runner/Mode.java
deleted file mode 100644
index 0ad7172..0000000
--- a/tools/runner/java/dalvik/runner/Mode.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.TimeoutException;
-import java.util.logging.Logger;
-import java.util.regex.Pattern;
-
-/**
- * A Mode for running tests. Examples including running in a virtual
- * machine either on the host or a device or within a specific context
- * such as within an Activity.
- */
-abstract class Mode {
-
-    private static final Pattern JAVA_TEST_PATTERN = Pattern.compile("\\/(\\w)+\\.java$");
-
-    private static final Logger logger = Logger.getLogger(Mode.class.getName());
-
-    protected final Environment environment;
-    protected final long timeoutSeconds;
-    protected final File sdkJar;
-    protected final PrintStream tee;
-
-    /**
-     * Set of Java files needed to built to tun the currently selected
-     * set of tests. We build a subset rather than all the files all
-     * the time to reduce dex packaging costs in the activity mode
-     * case.
-     */
-    protected final Set<File> testRunnerJava = new HashSet<File>();
-
-    /**
-     * Classpath of testRunner on the host side including any
-     * supporting libraries for testRunnerJava. Useful for compiling
-     * testRunnerJava as well as executing it on the host. Execution
-     * on the device requires further packaging typically done by
-     * postCompileTestRunner.
-     */
-    protected final Classpath testRunnerClasspath = new Classpath();
-
-    // TODO: this should be an immutable collection.
-    protected final Classpath testClasspath = Classpath.of(
-            new File("dalvik/libcore/tools/runner/lib/jsr305.jar"),
-            new File("dalvik/libcore/tools/runner/lib/guava.jar"),
-            new File("dalvik/libcore/tools/runner/lib/caliper.jar"),
-            // TODO: we should be able to work with a shipping SDK, not depend on out/...
-            // dalvik/libcore/**/test/ for junit
-            // TODO: jar up just the junit classes and drop the jar in our lib/ directory.
-            new File("out/target/common/obj/JAVA_LIBRARIES/core-tests_intermediates/classes.jar").getAbsoluteFile());
-
-    Mode(Environment environment, long timeoutSeconds, File sdkJar, PrintStream tee) {
-        this.environment = environment;
-        this.timeoutSeconds = timeoutSeconds;
-        this.sdkJar = sdkJar;
-        this.tee = tee;
-    }
-
-    /**
-     * Initializes the temporary directories and test harness necessary to run
-     * tests.
-     */
-    protected void prepare(Set<File> testRunnerJava, Classpath testRunnerClasspath) {
-        this.testRunnerJava.add(new File(DalvikRunner.HOME_JAVA, "dalvik/runner/TestRunner.java"));
-        this.testRunnerJava.addAll(dalvikAnnotationSourceFiles());
-        this.testRunnerJava.addAll(testRunnerJava);
-        this.testRunnerClasspath.addAll(testRunnerClasspath);
-        environment.prepare();
-        compileTestRunner();
-    }
-
-    private List<File> dalvikAnnotationSourceFiles() {
-        // Hopefully one day we'll strip the dalvik annotations out, but until then we need to make
-        // them available to javac(1).
-        File sourceDir = new File("dalvik/libcore/dalvik/src/main/java/dalvik/annotation");
-        File[] javaSourceFiles = sourceDir.listFiles(new FilenameFilter() {
-            public boolean accept(File dir, String filename) {
-                return filename.endsWith(".java");
-            }
-        });
-        return Arrays.asList(javaSourceFiles);
-    }
-
-    private void compileTestRunner() {
-        logger.fine("build testrunner");
-
-        Classpath classpath = new Classpath();
-        classpath.addAll(testClasspath);
-        classpath.addAll(testRunnerClasspath);
-
-        File base = environment.testRunnerClassesDir();
-        new Mkdir().mkdirs(base);
-        new Javac()
-                .bootClasspath(sdkJar)
-                .classpath(classpath)
-                .sourcepath(DalvikRunner.HOME_JAVA)
-                .destination(base)
-                .compile(testRunnerJava);
-        postCompileTestRunner();
-    }
-
-    /**
-     * Hook method called after TestRunner compilation.
-     */
-    abstract protected void postCompileTestRunner();
-
-    /**
-     * Compiles classes for the given test and makes them ready for execution.
-     * If the test could not be compiled successfully, it will be updated with
-     * the appropriate test result.
-     */
-    public void buildAndInstall(TestRun testRun) {
-        logger.fine("build " + testRun.getQualifiedName());
-
-        boolean testCompiled;
-        try {
-            testCompiled = compileTest(testRun);
-            if (!testCompiled) {
-                testRun.setResult(Result.UNSUPPORTED, Collections.<String>emptyList());
-                return;
-            }
-        } catch (CommandFailedException e) {
-            testRun.setResult(Result.COMPILE_FAILED, e.getOutputLines());
-            return;
-        } catch (IOException e) {
-            testRun.setResult(Result.ERROR, e);
-            return;
-        }
-        testRun.setTestCompiled(testCompiled);
-        environment.prepareUserDir(testRun);
-    }
-
-    /**
-     * Compiles the classes for the described test.
-     *
-     * @return the path to the compiled classes (directory or jar), or {@code
-     *      null} if the test could not be compiled.
-     * @throws CommandFailedException if javac fails
-     */
-    private boolean compileTest(TestRun testRun) throws IOException {
-        if (!JAVA_TEST_PATTERN.matcher(testRun.getTestJava().toString()).find()) {
-            return false;
-        }
-
-        String qualifiedName = testRun.getQualifiedName();
-        File testClassesDir = environment.testClassesDir(testRun);
-        new Mkdir().mkdirs(testClassesDir);
-        FileOutputStream propertiesOut = new FileOutputStream(
-                new File(testClassesDir, TestProperties.FILE));
-        Properties properties = new Properties();
-        fillInProperties(properties, testRun);
-        properties.store(propertiesOut, "generated by " + Mode.class.getName());
-        propertiesOut.close();
-
-        Classpath classpath = new Classpath();
-        classpath.addAll(testClasspath);
-        classpath.addAll(testRun.getRunnerClasspath());
-
-        Set<File> sourceFiles = new HashSet<File>();
-        sourceFiles.add(testRun.getTestJava());
-        sourceFiles.addAll(dalvikAnnotationSourceFiles());
-
-        // compile the test case
-        new Javac()
-                .bootClasspath(sdkJar)
-                .classpath(classpath)
-                .sourcepath(testRun.getTestDirectory())
-                .destination(testClassesDir)
-                .compile(sourceFiles);
-        postCompileTest(testRun);
-        return true;
-    }
-
-    /**
-     * Hook method called after test compilation.
-     *
-     * @param testRun The test being compiled
-     */
-    abstract protected void postCompileTest(TestRun testRun);
-
-
-    /**
-     * Fill in properties for running in this mode
-     */
-    protected void fillInProperties(Properties properties, TestRun testRun) {
-        properties.setProperty(TestProperties.TEST_CLASS, testRun.getTestClass());
-        properties.setProperty(TestProperties.QUALIFIED_NAME, testRun.getQualifiedName());
-        properties.setProperty(TestProperties.RUNNER_CLASS, testRun.getRunnerClass().getName());
-    }
-
-    /**
-     * Runs the test, and updates its test result.
-     */
-    void runTest(TestRun testRun) {
-        if (!testRun.isRunnable()) {
-            throw new IllegalArgumentException();
-        }
-
-        List<String> output;
-        try {
-            output = runTestCommand(testRun);
-        } catch (TimeoutException e) {
-            testRun.setResult(Result.EXEC_TIMEOUT,
-                Collections.singletonList("Exceeded timeout! (" + timeoutSeconds + "s)"));
-            return;
-        } catch (Exception e) {
-            testRun.setResult(Result.ERROR, e);
-            return;
-        }
-        // we only look at the output of the last command
-        if (output.isEmpty()) {
-            testRun.setResult(Result.ERROR,
-                    Collections.singletonList("No output returned!"));
-            return;
-        }
-
-        Result result = TestProperties.RESULT_SUCCESS.equals(output.get(output.size() - 1))
-                ? Result.SUCCESS
-                : Result.EXEC_FAILED;
-        testRun.setResult(result, output.subList(0, output.size() - 1));
-    }
-
-    /**
-     * Run the actual test to gather output
-     */
-    protected abstract List<String> runTestCommand(TestRun testRun)
-        throws TimeoutException;
-
-    /**
-     * Deletes files and releases any resources required for the execution of
-     * the given test.
-     */
-    void cleanup(TestRun testRun) {
-        environment.cleanup(testRun);
-    }
-
-    /**
-     * Cleans up after all test runs have completed.
-     */
-    void shutdown() {
-        environment.shutdown();
-    }
-}
diff --git a/tools/runner/java/dalvik/runner/TestRun.java b/tools/runner/java/dalvik/runner/TestRun.java
deleted file mode 100644
index c610b25..0000000
--- a/tools/runner/java/dalvik/runner/TestRun.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dalvik.runner;
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A test run and its outcome. This class tracks the complete lifecycle of a
- * single test run:
- * <ol>
- *   <li>the test source code (test directory, java file, test class)
- *   <li>the test identity (suite name, test name, qualified name)
- *   <li>the code to execute (test classes, user dir)
- *   <li>the result of execution (expected result, result, output lines)
- * </ol>
- */
-public final class TestRun {
-
-    private final File testDirectory;
-    private final File testJava;
-    private final String testClass;
-    private final Class<? extends Runner> runnerClass;
-    private final File runnerJava;
-    private final Classpath runnerClasspath;
-
-    private final String suiteName;
-    private final String testName;
-    private final String qualifiedName;
-    private final String description;
-
-    private boolean testCompiled;
-    private File userDir = new File(System.getProperty("user.dir"));
-
-    private ExpectedResult expectedResult = ExpectedResult.SUCCESS;
-    private Result result;
-    private List<String> outputLines;
-
-    public TestRun(File testDirectory, File testJava, String testClass,
-            String suiteName, String testName, String qualifiedName,
-            String description, Class<? extends Runner> runnerClass,
-            File runnerJava, Classpath runnerClasspath) {
-        this.qualifiedName = qualifiedName;
-        this.suiteName = suiteName;
-        this.testName = testName;
-        this.testDirectory = testDirectory;
-        this.testJava = testJava;
-        this.description = description;
-        this.testClass = testClass;
-        this.runnerClass = runnerClass;
-        this.runnerJava = runnerJava;
-        this.runnerClasspath = runnerClasspath;
-    }
-
-    /**
-     * Returns the local directory containing this test's java file.
-     */
-    public File getTestDirectory() {
-        return testDirectory;
-    }
-
-    public File getTestJava() {
-        return testJava;
-    }
-
-    /**
-     * Returns the executable test's classname, such as java.lang.IntegerTest
-     * or BitTwiddle.
-     */
-    public String getTestClass() {
-        return testClass;
-    }
-
-    /**
-     * Returns the test suite name, such as java.lang.Integer or
-     * java.lang.IntegerTest.
-     */
-    public String getSuiteName() {
-        return suiteName;
-    }
-
-    /**
-     * Returns the specific test name, such as BitTwiddle or testBitTwiddle.
-     */
-    public String getTestName() {
-        return testName;
-    }
-
-    /**
-     * Returns a unique identifier for this test.
-     */
-    public String getQualifiedName() {
-        return qualifiedName;
-    }
-
-    /**
-     * Returns an English description of this test, or null if no such
-     * description is known.
-     */
-    public String getDescription() {
-        return description;
-    }
-
-    public void setExpectedResult(ExpectedResult expectedResult) {
-        this.expectedResult = expectedResult;
-    }
-
-    /**
-     * Set when the test is successfully compiled.
-     */
-    public void setTestCompiled(boolean testCompiled) {
-        this.testCompiled = testCompiled;
-    }
-
-    public boolean getTestCompiled() {
-        return testCompiled;
-    }
-
-    /**
-     * Initializes the directory from which local files can be read by the test.
-     */
-    public void setUserDir(File base) {
-        this.userDir = base;
-    }
-
-    public File getUserDir() {
-        return userDir;
-    }
-
-    /**
-     * Returns true if this test is ready for execution. Such tests have their
-     * classpath prepared and have not yet been assigned a result.
-     */
-    public boolean isRunnable() {
-        return testCompiled && result == null;
-    }
-
-    public void setResult(Result result, Throwable e) {
-        setResult(result, throwableToLines(e));
-    }
-
-    public void setResult(Result result, List<String> outputLines) {
-        if (this.result != null) {
-            throw new IllegalStateException("result already set");
-        }
-
-        this.result = result;
-        this.outputLines = outputLines;
-    }
-
-    private static List<String> throwableToLines(Throwable t) {
-        StringWriter writer = new StringWriter();
-        PrintWriter out = new PrintWriter(writer);
-        t.printStackTrace(out);
-        return Arrays.asList(writer.toString().split("\\n"));
-    }
-
-    public Result getResult() {
-        return result;
-    }
-
-    public List<String> getOutputLines() {
-        return outputLines;
-    }
-
-    public Class<? extends Runner> getRunnerClass() {
-        return runnerClass;
-    }
-
-    public File getRunnerJava() {
-        return runnerJava;
-    }
-
-    public Classpath getRunnerClasspath() {
-        return runnerClasspath;
-    }
-
-    /**
-     * Returns true if the outcome of this run matches what was expected.
-     */
-    public boolean isExpectedResult() {
-        return result == expectedResult.getResult() && matchesExpectedPattern();
-    }
-
-    /**
-     * Returns true if the test's output matches the expected output.
-     */
-    private boolean matchesExpectedPattern() {
-        return expectedResult.getPattern()
-                .matcher(Strings.join(outputLines, "\n"))
-                .matches();
-    }
-
-    /**
-     * Returns the failure message for this failed test run. This message is
-     * intended to help to diagnose why the test result didn't match what was
-     * expected.
-     */
-    public String getFailureMessage() {
-        StringBuilder builder = new StringBuilder();
-
-        if (expectedResult.getResult() != Result.SUCCESS
-                && expectedResult.getResult() != result) {
-            builder.append("Expected result: ")
-                    .append(expectedResult.getResult())
-                    .append("\n");
-        }
-
-        if (!matchesExpectedPattern()) {
-            builder.append("Expected output to match \"")
-                    .append(expectedResult.getPattern().pattern())
-                    .append("\"\n");
-        }
-
-        for (String output : outputLines) {
-            builder.append(output).append("\n");
-        }
-
-        return builder.toString();
-    }
-
-    @Override public String toString() {
-        return qualifiedName;
-    }
-}
diff --git a/tools/runner/java/vogar/Action.java b/tools/runner/java/vogar/Action.java
new file mode 100644
index 0000000..5a562c7
--- /dev/null
+++ b/tools/runner/java/vogar/Action.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.File;
+
+/**
+ * A named job such as a test or benchmark run. This class tracks the resource
+ * files and classes for compiling and running a Java source file.
+ */
+public final class Action {
+
+    private final String name;
+    private final String actionClass;
+    private final File resourcesDirectory;
+    private final File javaFile;
+    private final RunnerSpec runnerSpec;
+    private File userDir = new File(System.getProperty("user.dir"));
+
+    public Action(String name, String actionClass, File resourcesDirectory,
+            File javaFile, RunnerSpec runnerSpec) {
+        this.name = name;
+        this.actionClass = actionClass;
+        this.resourcesDirectory = resourcesDirectory;
+        this.javaFile = javaFile;
+        this.runnerSpec = runnerSpec;
+    }
+
+    /**
+     * Returns the local directory containing this action's required resource
+     * files, or {@code null} if this action is standalone.
+     */
+    public File getResourcesDirectory() {
+        return resourcesDirectory;
+    }
+
+    /**
+     * Returns this action's java file, or {@code null} if this file wasn't
+     * built from source.
+     */
+    public File getJavaFile() {
+        return javaFile;
+    }
+
+    /**
+     * Returns the executable classname, such as java.lang.IntegerTest
+     * or BitTwiddle.
+     */
+    public String getTargetClass() {
+        return actionClass;
+    }
+
+    /**
+     * Returns a unique identifier for this action.
+     */
+    public String getName() {
+        return name;
+    }
+
+    public RunnerSpec getRunnerSpec() {
+        return runnerSpec;
+    }
+
+    /**
+     * Initializes the directory from which local files can be read by the
+     * action.
+     */
+    public void setUserDir(File base) {
+        this.userDir = base;
+    }
+
+    public File getUserDir() {
+        return userDir;
+    }
+
+    @Override public String toString() {
+        return name;
+    }
+}
diff --git a/tools/runner/java/vogar/ActivityMode.java b/tools/runner/java/vogar/ActivityMode.java
new file mode 100644
index 0000000..da49c89
--- /dev/null
+++ b/tools/runner/java/vogar/ActivityMode.java
@@ -0,0 +1,168 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Logger;
+import vogar.commands.Aapt;
+import vogar.commands.Command;
+import vogar.commands.Dx;
+import vogar.commands.Rm;
+
+/**
+ * Runs an action in the context of an android.app.Activity on a device
+ */
+final class ActivityMode extends Mode {
+
+    private static final Logger logger = Logger.getLogger(ActivityMode.class.getName());
+
+    private static final String TEST_ACTIVITY_CLASS   = "vogar.target.TestActivity";
+
+    ActivityMode(Integer debugPort, File sdkJar, List<String> javacArgs,
+            int monitorPort, File localTemp, boolean cleanBefore, boolean cleanAfter,
+            File deviceRunnerDir, Classpath classpath) {
+        super(new EnvironmentDevice(cleanBefore, cleanAfter,
+                debugPort, monitorPort, localTemp, deviceRunnerDir),
+                sdkJar, javacArgs, monitorPort, classpath);
+    }
+
+    private EnvironmentDevice getEnvironmentDevice() {
+        return (EnvironmentDevice) environment;
+    }
+
+    @Override protected void prepare(Set<RunnerSpec> runners) {
+        runnerJava.add(new File("dalvik/libcore/tools/runner/lib/TestActivity.java"));
+        super.prepare(runners);
+    }
+
+    @Override protected void postCompile(Action action, File jar) {
+        logger.fine("aapt and push " + action.getName());
+
+        // We can't put multiple dex files in one apk.
+        // We can't just give dex multiple jars with conflicting class names
+
+        // With that in mind, the APK packaging strategy is as follows:
+        // 1. dx to create a dex
+        // 2. aapt the dex to create apk
+        // 3. sign the apk
+        // 4. install the apk
+        File dex = createDex(action, jar);
+        File apkUnsigned = createApk(action, dex);
+        File apkSigned = signApk(action, apkUnsigned);
+        installApk(action, apkSigned);
+    }
+
+    /**
+     * Returns a single dexfile containing {@code action}'s classes and all
+     * dependencies.
+     */
+    private File createDex(Action action, File actionJar) {
+        File dex = environment.file(action, "classes.dex");
+        Classpath classesToDex = Classpath.of(actionJar);
+        classesToDex.addAll(this.classpath);
+        new Dx().dex(dex, classesToDex);
+        return dex;
+    }
+
+    /**
+     * According to android.content.pm.PackageParser, package name
+     * "must have at least one '.' separator" Since the qualified name
+     * may not contain a dot, we prefix containing one to ensure we
+     * are compliant.
+     */
+    private static String packageName(Action action) {
+        return "vogar.test." + action.getName();
+    }
+
+    private File createApk (Action action, File dex) {
+        String androidManifest =
+            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+            "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+            "      package=\"" + packageName(action) + "\">\n" +
+            "    <uses-permission android:name=\"android.permission.INTERNET\" />\n" +
+            "    <application>\n" +
+            "        <activity android:name=\"" + TEST_ACTIVITY_CLASS + "\">\n" +
+            "            <intent-filter>\n" +
+            "                <action android:name=\"android.intent.action.MAIN\" />\n" +
+            "                <category android:name=\"android.intent.category.LAUNCHER\" />\n" +
+            "            </intent-filter>\n" +
+            "        </activity>\n" +
+            "    </application>\n" +
+            "</manifest>\n";
+        File androidManifestFile = environment.file(action, "classes", "AndroidManifest.xml");
+        try {
+            FileOutputStream androidManifestOut =
+                    new FileOutputStream(androidManifestFile);
+            androidManifestOut.write(androidManifest.getBytes("UTF-8"));
+            androidManifestOut.close();
+        } catch (IOException e) {
+            throw new RuntimeException("Problem writing " + androidManifestFile, e);
+        }
+
+        File apkUnsigned = environment.file(action, action + ".apk.unsigned");
+        new Aapt().apk(apkUnsigned, androidManifestFile);
+        new Aapt().add(apkUnsigned, dex);
+        new Aapt().add(apkUnsigned, environment.file(action, "classes", TestProperties.FILE));
+        return apkUnsigned;
+    }
+
+    private File signApk(Action action, File apkUnsigned) {
+        File apkSigned = environment.file(action, action + ".apk");
+        // TODO: we should be able to work with a shipping SDK, not depend on out/...
+        // TODO: we should be able to work without hardwired keys, not depend on build/...
+        new Command.Builder()
+                .args("java")
+                .args("-jar")
+                .args("out/host/linux-x86/framework/signapk.jar")
+                .args("build/target/product/security/testkey.x509.pem")
+                .args("build/target/product/security/testkey.pk8")
+                .args(apkUnsigned)
+                .args(apkSigned).execute();
+        new Rm().file(apkUnsigned);
+        return apkSigned;
+    }
+
+    private void installApk(Action action, File apkSigned) {
+        // install the local apk ona the device
+        getEnvironmentDevice().adb.uninstall(packageName(action));
+        getEnvironmentDevice().adb.install(apkSigned);
+    }
+
+    @Override protected void fillInProperties(Properties properties, Action action) {
+        super.fillInProperties(properties, action);
+        properties.setProperty(TestProperties.DEVICE_RUNNER_DIR, getEnvironmentDevice().runnerDir.getPath());
+    }
+
+    @Override protected Command createActionCommand(Action action) {
+        return new Command(
+                "adb", "shell", "am", "start", "-W",
+                "-a", "android.intent.action.MAIN",
+                "-n", (packageName(action) + "/" + TEST_ACTIVITY_CLASS));
+    }
+
+    @Override void cleanup(Action action) {
+        super.cleanup(action);
+        if (environment.cleanAfter) {
+            getEnvironmentDevice().adb.uninstall(action.getName());
+        }
+    }
+}
diff --git a/tools/runner/java/vogar/CaliperSpec.java b/tools/runner/java/vogar/CaliperSpec.java
new file mode 100644
index 0000000..f0c0e39
--- /dev/null
+++ b/tools/runner/java/vogar/CaliperSpec.java
@@ -0,0 +1,51 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import vogar.target.CaliperRunner;
+import vogar.target.Runner;
+
+/**
+ * Create {@link Action}s for {@code .java} files with Caliper benchmarks in
+ * them.
+ */
+class CaliperSpec extends NamingPatternRunnerSpec {
+
+    @Override protected boolean matches(File file) {
+        return super.matches(file) && file.getName().endsWith("Benchmark.java");
+    }
+
+    public boolean supports(String className) {
+        return className.endsWith("Benchmark");
+    }
+
+    public Class<? extends Runner> getRunnerClass() {
+        return CaliperRunner.class;
+    }
+
+    public File getSource() {
+        return new File(Vogar.HOME_JAVA, "vogar/target/CaliperRunner.java");
+    }
+
+    public Classpath getClasspath() {
+        return Classpath.of(
+                new File("dalvik/libcore/tools/runner/lib/jsr305.jar"),
+                new File("dalvik/libcore/tools/runner/lib/guava.jar"),
+                new File("dalvik/libcore/tools/runner/lib/caliper.jar"));
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/Classpath.java b/tools/runner/java/vogar/Classpath.java
similarity index 96%
rename from tools/runner/java/dalvik/runner/Classpath.java
rename to tools/runner/java/vogar/Classpath.java
index 607615a..cd83409 100644
--- a/tools/runner/java/dalvik/runner/Classpath.java
+++ b/tools/runner/java/vogar/Classpath.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -25,7 +25,7 @@
 /**
  * A list of jar files and directories.
  */
-final class Classpath {
+public final class Classpath {
 
     private final List<File> elements = new ArrayList<File>();
 
diff --git a/tools/runner/java/vogar/Console.java b/tools/runner/java/vogar/Console.java
new file mode 100644
index 0000000..54c8f51
--- /dev/null
+++ b/tools/runner/java/vogar/Console.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+/**
+ * Controls, formats and emits output to the command line. Command line output
+ * can be generated both by java.util.logging and by direct calls to this class.
+ */
+public class Console {
+
+    private final boolean stream;
+    private final boolean color;
+    private final String indent;
+
+    private String currentName;
+    private CurrentLine currentLine = CurrentLine.NEW;
+    private final StringBuilder bufferedOutput = new StringBuilder();
+
+    public Console(boolean stream, String indent, boolean color) {
+        this.stream = stream;
+        this.indent = indent;
+        this.color = color;
+    }
+
+    public void configureJavaLogging(boolean verbose) {
+        ConsoleHandler handler = new ConsoleHandler();
+        handler.setLevel(Level.ALL);
+        handler.setFormatter(new Formatter() {
+            @Override public String format(LogRecord r) {
+                return logRecordToString(r);
+            }
+        });
+
+        Logger logger = Logger.getLogger("vogar");
+        logger.setLevel(verbose ? Level.FINE : Level.INFO);
+        logger.addHandler(handler);
+        logger.setUseParentHandlers(false);
+    }
+
+    /**
+     * Formats a sequence of regular log messages with the output streamed from
+     * a foreign process.
+     */
+    private String logRecordToString(LogRecord logRecord) {
+        String message = logRecord.getMessage();
+
+        if (logRecord.getThrown() != null) {
+            StringWriter writer = new StringWriter();
+            writer.write(message);
+            writer.write("\n");
+            logRecord.getThrown().printStackTrace(new PrintWriter(writer));
+            message = writer.toString();
+        }
+
+        newLine();
+        return message + "\n";
+    }
+
+    public void action(String name) {
+        newLine();
+        System.out.print("Action " + name);
+        currentName = name;
+        currentLine = CurrentLine.NAME;
+    }
+
+    /**
+     * Prints the beginning of the named outcome.
+     */
+    public void outcome(String name) {
+        // if the outcome and action names are the same, omit the outcome name
+        if (name.equals(currentName)) {
+            return;
+        }
+
+        currentName = name;
+        newLine();
+        System.out.print(indent + name);
+        currentLine = CurrentLine.NAME;
+    }
+
+    /**
+     * Appends the action output immediately to the stream when streaming is on,
+     * or to a buffer when streaming is off. Buffered output will be held and
+     * printed only if the outcome is unsuccessful.
+     */
+    public void streamOutput(String output) {
+        if (stream) {
+            printOutput(output);
+        } else {
+            bufferedOutput.append(output);
+        }
+    }
+
+    /**
+     * Writes the action's outcome.
+     */
+    public void printResult(Result result, boolean ok) {
+        if (ok) {
+            String prefix = (currentLine == CurrentLine.NAME) ? " " : "\n" + indent;
+            System.out.println(prefix + green("OK (" + result + ")"));
+
+        } else {
+            if (bufferedOutput.length() > 0) {
+                printOutput(bufferedOutput.toString());
+                bufferedOutput.delete(0, bufferedOutput.length());
+            }
+
+            newLine();
+            System.out.println(indent + red("FAIL (" + result + ")"));
+        }
+
+        currentName = null;
+        currentLine = CurrentLine.NEW;
+    }
+
+    public void summarizeFailures(List<String> failureNames) {
+        System.out.println("Failure summary:");
+        for (String failureName : failureNames) {
+            System.out.println(red(failureName));
+        }
+    }
+
+    /**
+     * Prints the action output with appropriate indentation.
+     */
+    private void printOutput(String streamedOutput) {
+        String[] lines = messageToLines(streamedOutput);
+
+        if (currentLine != CurrentLine.STREAMED_OUTPUT) {
+            newLine();
+            System.out.print(indent);
+            System.out.print(indent);
+        }
+        System.out.print(lines[0]);
+        currentLine = CurrentLine.STREAMED_OUTPUT;
+
+        for (int i = 1; i < lines.length; i++) {
+            newLine();
+
+            if (lines[i].length() > 0) {
+                System.out.print(indent);
+                System.out.print(indent);
+                System.out.print(lines[i]);
+                currentLine = CurrentLine.STREAMED_OUTPUT;
+            }
+        }
+    }
+
+    /**
+     * Inserts a linebreak if necessary.
+     */
+    private void newLine() {
+        if (currentLine == CurrentLine.NEW) {
+            return;
+        }
+
+        System.out.println();
+        currentLine = CurrentLine.NEW;
+    }
+
+    /**
+     * Status of a currently-in-progress line of output.
+     */
+    enum CurrentLine {
+
+        /**
+         * The line is blank.
+         */
+        NEW,
+
+        /**
+         * The line contains streamed application output. Additional streamed
+         * output may be appended without additional line separators or
+         * indentation.
+         */
+        STREAMED_OUTPUT,
+
+        /**
+         * The line contains the name of an action or outcome. The outcome's
+         * result (such as "OK") can be appended without additional line
+         * separators or indentation.
+         */
+        NAME,
+    }
+
+    /**
+     * Returns an array containing the lines of the given text.
+     */
+    private String[] messageToLines(String message) {
+        // pass Integer.MAX_VALUE so split doesn't trim trailing empty strings.
+        return message.split("\r\n|\r|\n", Integer.MAX_VALUE);
+    }
+
+    private String green(String message) {
+        return color ? ("\u001b[32;1m" + message + "\u001b[0m") : message;
+    }
+
+    private String red(String message) {
+        return color ? ("\u001b[31;1m" + message + "\u001b[0m") : message;
+    }
+}
diff --git a/tools/runner/java/vogar/DeviceDalvikVm.java b/tools/runner/java/vogar/DeviceDalvikVm.java
new file mode 100644
index 0000000..dfbfada
--- /dev/null
+++ b/tools/runner/java/vogar/DeviceDalvikVm.java
@@ -0,0 +1,111 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+import vogar.commands.Dx;
+
+/**
+ * Execute actions on a Dalvik VM using an Android device or emulator.
+ */
+final class DeviceDalvikVm extends Vm {
+    private static final Logger logger = Logger.getLogger(DeviceDalvikVm.class.getName());
+
+    /** A list of generic names that we avoid when naming generated files. */
+    private static final Set<String> BANNED_NAMES = new HashSet<String>();
+    static {
+        BANNED_NAMES.add("classes");
+        BANNED_NAMES.add("javalib");
+    }
+
+    DeviceDalvikVm(Integer debugPort, File sdkJar, List<String> javacArgs,
+            int monitorPort, File localTemp, List<String> additionalVmArgs,
+            List<String> targetArgs, boolean cleanBefore, boolean cleanAfter,
+            File runnerDir, Classpath classpath) {
+        super(new EnvironmentDevice(cleanBefore, cleanAfter, debugPort, monitorPort, localTemp,
+                runnerDir), sdkJar, javacArgs, additionalVmArgs, targetArgs, monitorPort, classpath);
+    }
+
+    private EnvironmentDevice getEnvironmentDevice() {
+        return (EnvironmentDevice) environment;
+    }
+
+    @Override protected void installRunner() {
+        // dex everything on the classpath and push it to the device.
+        for (File classpathElement : classpath.getElements()) {
+            dexAndPush(basenameOfJar(classpathElement), classpathElement);
+        }
+    }
+
+    private String basenameOfJar(File file) {
+        String name = file.getName().replaceAll("\\.jar$", "");
+        while (BANNED_NAMES.contains(name)) {
+            file = file.getParentFile();
+            name = file.getName();
+        }
+        return name;
+    }
+
+    @Override protected void postCompile(Action action, File jar) {
+        dexAndPush(action.getName(), jar);
+    }
+
+    private void dexAndPush(String name, File jar) {
+        logger.fine("dex and push " + name);
+
+        // make the local dex (inside a jar)
+        File localDex = environment.file(name, name + ".dx.jar");
+        new Dx().dex(localDex, Classpath.of(jar));
+
+        // post the local dex to the device
+        getEnvironmentDevice().adb.push(localDex, deviceDexFile(name));
+    }
+
+    private File deviceDexFile(String name) {
+        return new File(getEnvironmentDevice().runnerDir, name + ".jar");
+    }
+
+    @Override protected VmCommandBuilder newVmCommandBuilder(
+            File workingDirectory) {
+        // ignore the working directory; it's device-local and we can't easily
+        // set the working directory for commands run via adb shell.
+        // TODO: we only *need* to set ANDROID_DATA on production devices.
+        // We set "user.home" to /sdcard because code might reasonably assume it can write to
+        // that directory.
+        return new VmCommandBuilder()
+                .vmCommand("adb", "shell", "ANDROID_DATA=/sdcard", "dalvikvm")
+                .vmArgs("-Duser.home=/sdcard")
+                .vmArgs("-Duser.name=root")
+                .vmArgs("-Duser.language=en")
+                .vmArgs("-Duser.region=US")
+                .vmArgs("-Djavax.net.ssl.trustStore=/system/etc/security/cacerts.bks")
+                .temp(getEnvironmentDevice().vogarTemp);
+    }
+
+    @Override protected Classpath getRuntimeClasspath(Action action) {
+        Classpath result = new Classpath();
+        result.addAll(deviceDexFile(action.getName()));
+        for (File classpathElement : classpath.getElements()) {
+            result.addAll(deviceDexFile(basenameOfJar(classpathElement)));
+        }
+        return result;
+    }
+}
diff --git a/tools/runner/java/vogar/Driver.java b/tools/runner/java/vogar/Driver.java
new file mode 100644
index 0000000..aaf0cf6
--- /dev/null
+++ b/tools/runner/java/vogar/Driver.java
@@ -0,0 +1,300 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Logger;
+import vogar.commands.Command;
+import vogar.commands.CommandFailedException;
+import vogar.commands.Mkdir;
+
+/**
+ * Compiles, installs, runs and reports on actions.
+ */
+final class Driver implements HostMonitor.Handler {
+
+    private static final Logger logger = Logger.getLogger(Driver.class.getName());
+
+    private final File localTemp;
+    private final ExpectationStore expectationStore;
+    private final List<RunnerSpec> runnerSpecs;
+    private final Mode mode;
+    private final XmlReportPrinter reportPrinter;
+    private final Console console;
+    private final int monitorPort;
+    private final HostMonitor monitor;
+    private final long timeoutSeconds;
+    private int successes = 0;
+    private int failures = 0;
+    private List<String> failureNames = new ArrayList<String>();
+
+    private Timer actionTimeoutTimer = new Timer("action timeout", true);
+
+    private final Set<RunnerSpec> runnerSpecsBearingActions = new HashSet<RunnerSpec>();
+    private final Map<String, Action> actions = Collections.synchronizedMap(
+            new LinkedHashMap<String, Action>());
+    private final Map<String, Outcome> outcomes = Collections.synchronizedMap(
+            new LinkedHashMap<String, Outcome>());
+
+    /**
+     * The number of tests that weren't run because they aren't supported by
+     * this runner.
+     */
+    private int unsupportedActions = 0;
+
+    public Driver(File localTemp, Mode mode, ExpectationStore expectationStore,
+            List<RunnerSpec> runnerSpecs, XmlReportPrinter reportPrinter,
+            Console console, HostMonitor monitor, int monitorPort, long timeoutSeconds) {
+        this.localTemp = localTemp;
+        this.expectationStore = expectationStore;
+        this.mode = mode;
+        this.console = console;
+        this.runnerSpecs = runnerSpecs;
+        this.reportPrinter = reportPrinter;
+        this.monitor = monitor;
+        this.monitorPort = monitorPort;
+        this.timeoutSeconds = timeoutSeconds;
+    }
+
+    /**
+     * Builds and executes the actions in the given files.
+     */
+    public void buildAndRun(Collection<File> files, Collection<String> classes) {
+        if (!actions.isEmpty()) {
+            throw new IllegalStateException("Drivers are not reusable");
+        }
+
+        new Mkdir().mkdirs(localTemp);
+
+        filesToActions(files);
+        classesToActions(classes);
+
+        if (actions.isEmpty()) {
+            logger.info("Nothing to do.");
+            return;
+        }
+
+        logger.info("Actions: " + actions.size());
+
+        // mode.prepare before mode.buildAndInstall to ensure the runner is
+        // built. packaging of activity APK files needs the runner along with
+        // the action-specific files.
+        mode.prepare(runnerSpecsBearingActions);
+
+        // build and install actions in a background thread. Using lots of
+        // threads helps for packages that contain many unsupported actions
+        final BlockingQueue<Action> readyToRun = new ArrayBlockingQueue<Action>(4);
+
+        ExecutorService builders = Threads.threadPerCpuExecutor();
+        int t = 0;
+
+        for (final Action action : actions.values()) {
+            final String name = action.getName();
+            final int runIndex = t++;
+            builders.submit(new Runnable() {
+                public void run() {
+                    try {
+                        logger.fine("installing action " + runIndex + "; "
+                                + readyToRun.size() + " are runnable");
+
+                        if (expectationStore.get(name).getResult() == Result.UNSUPPORTED) {
+                            outcomes.put(name, new Outcome(name, Result.UNSUPPORTED,
+                                    "Unsupported according to expectations file"));
+
+                        } else {
+                            Outcome outcome = mode.buildAndInstall(action);
+                            if (outcome != null) {
+                                outcomes.put(name, outcome);
+                            }
+                        }
+
+                        readyToRun.put(action);
+                    } catch (InterruptedException e) {
+                        outcomes.put(name, new Outcome(name, Result.ERROR, e));
+                    }
+                }
+            });
+        }
+        builders.shutdown();
+
+        for (int i = 0; i < actions.size(); i++) {
+            logger.fine("executing action " + i + "; "
+                    + readyToRun.size() + " are ready to run");
+
+            // if it takes 5 minutes for build and install, something is broken
+            Action action;
+            try {
+                action = readyToRun.poll(5 * 60, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Unexpected interruption waiting for build and install", e);
+            }
+
+            if (action == null) {
+                outcome(new Outcome("vogar.Vogar", Result.ERROR,
+                        "Expected " + actions.size() + " actions but found only " + i));
+                break;
+            }
+
+            execute(action);
+            mode.cleanup(action);
+        }
+
+        if (reportPrinter != null) {
+            logger.info("Printing XML Reports... ");
+            int numFiles = reportPrinter.generateReports(outcomes.values());
+            logger.info(numFiles + " XML files written.");
+        }
+
+        mode.shutdown();
+
+        if (failures > 0 || unsupportedActions > 0) {
+            Collections.sort(failureNames);
+            console.summarizeFailures(failureNames);
+            logger.info(String.format("Outcomes: %s. Passed: %d, Failed: %d, Skipped: %d",
+                    (successes + failures), successes, failures, unsupportedActions));
+        } else {
+            logger.info(String.format("Outcomes: %s. All successful.", 
+                    (successes + failures)));
+        }
+    }
+
+    private void classesToActions(Collection<String> classes) {
+        for (String clazz : classes) {
+            for (RunnerSpec runnerSpec : runnerSpecs) {
+                if (runnerSpec.supports(clazz)) {
+                    runnerSpecsBearingActions.add(runnerSpec);
+                    Action action = new Action(clazz, clazz, null, null, runnerSpec);
+                    actions.put(action.getName(), action);
+                    break;
+                }
+            }
+        }
+    }
+
+    private void filesToActions(Collection<File> files) {
+        for (File file : files) {
+            Set<Action> actionsForFile = Collections.emptySet();
+
+            for (RunnerSpec runnerSpec : runnerSpecs) {
+                actionsForFile = runnerSpec.findActions(file);
+
+                // break as soon as we find any match. We don't need multiple
+                // matches for the same file, since that would run it twice.
+                if (!actionsForFile.isEmpty()) {
+                    runnerSpecsBearingActions.add(runnerSpec);
+                    break;
+                }
+            }
+
+            for (Action action : actionsForFile) {
+                actions.put(action.getName(), action);
+            }
+        }
+    }
+
+    /**
+     * Executes a single action and then prints the result.
+     */
+    private void execute(final Action action) {
+        console.action(action.getName());
+
+        Outcome earlyFailure = outcomes.get(action.getName());
+        if (earlyFailure == null) {
+            final Command command = mode.createActionCommand(action);
+            Future<List<String>> consoleOut = command.executeLater();
+            final AtomicReference<Result> result = new AtomicReference<Result>();
+
+            actionTimeoutTimer.schedule(new TimerTask() {
+                @Override public void run() {
+                    if (result.compareAndSet(null, Result.EXEC_TIMEOUT)) {
+                        logger.fine("killing " + action.getName() + " because it "
+                                + "timed out after " + timeoutSeconds + " seconds");
+                        command.destroy();
+                    }
+                }
+            }, timeoutSeconds * 1000);
+
+            boolean completedNormally = monitor.monitor(monitorPort, this);
+            if (completedNormally) {
+                if (result.compareAndSet(null, Result.SUCCESS)) {
+                    command.destroy();
+                }
+                return; // outcomes will have been reported via outcome()
+            }
+
+            if (result.compareAndSet(null, Result.ERROR)) {
+                command.destroy();
+            }
+            try {
+                earlyFailure = new Outcome(action.getName(), action.getName(),
+                        result.get(), consoleOut.get());
+            } catch (Exception e) {
+                if (e.getCause() instanceof CommandFailedException) {
+                    earlyFailure = new Outcome(action.getName(), action.getName(), result.get(),
+                            ((CommandFailedException) e.getCause()).getOutputLines());
+                } else {
+                    earlyFailure = new Outcome(action.getName(), result.get(), e);
+                }
+            }
+        }
+
+        if (earlyFailure.getResult() == Result.UNSUPPORTED) {
+            logger.fine("skipping " + action.getName());
+            unsupportedActions++;
+        } else {
+            for (String line : earlyFailure.getOutputLines()) {
+                console.streamOutput(line + "\n");
+            }
+            outcome(earlyFailure);
+        }
+    }
+
+    public void outcome(Outcome outcome) {
+        outcomes.put(outcome.getName(), outcome);
+        Expectation expectation = expectationStore.get(outcome);
+        boolean ok = expectation.matches(outcome);
+        if (ok) {
+            successes++;
+        } else {
+            failures++;
+            failureNames.add(outcome.getName());
+        }
+        console.outcome(outcome.getName());
+        console.printResult(outcome.getResult(), ok);
+    }
+
+    public void output(String outcomeName, String output) {
+        console.outcome(outcomeName);
+        console.streamOutput(output);
+    }
+}
diff --git a/tools/runner/java/vogar/Environment.java b/tools/runner/java/vogar/Environment.java
new file mode 100644
index 0000000..fc5c3ea
--- /dev/null
+++ b/tools/runner/java/vogar/Environment.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.File;
+import java.util.logging.Logger;
+import vogar.commands.Rm;
+
+/**
+ * A target runtime environment such as a remote device or the local host
+ */
+abstract class Environment {
+    private static final Logger logger = Logger.getLogger(Environment.class.getName());
+
+    final boolean cleanBefore;
+    final boolean cleanAfter;
+    final Integer debugPort;
+    private final File localTemp;
+
+    Environment (boolean cleanBefore, boolean cleanAfter, Integer debugPort, File localTemp) {
+        this.cleanBefore = cleanBefore;
+        this.cleanAfter = cleanAfter;
+        this.debugPort = debugPort;
+        this.localTemp = localTemp;
+    }
+
+    /**
+     * Initializes the temporary directories and harness necessary to run
+     * actions.
+     */
+    abstract void prepare();
+
+    /**
+     * Prepares the directory from which the action will be executed. Some
+     * actions expect to read data files from the current working directory;
+     * this step should ensure such files are available.
+     */
+    abstract void prepareUserDir(Action action);
+
+    /**
+     * Deletes files and releases any resources required for the execution of
+     * the given action.
+     */
+    void cleanup(Action action) {
+        if (cleanAfter) {
+            logger.fine("clean " + action.getName());
+            new Rm().directoryTree(file(action));
+        }
+    }
+
+    final File file(Object... path) {
+        return new File(localTemp + "/" + Strings.join(path, "/"));
+    }
+
+    final File hostJar(Object nameOrAction) {
+        return file(nameOrAction, nameOrAction + ".jar");
+    }
+
+    final File actionUserDir(Action action) {
+        File testTemp = new File(localTemp, "userDir");
+        return new File(testTemp, action.getName());
+    }
+
+    void shutdown() {
+        if (cleanAfter) {
+            new Rm().directoryTree(localTemp);
+        }
+    }
+}
diff --git a/tools/runner/java/vogar/EnvironmentDevice.java b/tools/runner/java/vogar/EnvironmentDevice.java
new file mode 100644
index 0000000..eddde8d
--- /dev/null
+++ b/tools/runner/java/vogar/EnvironmentDevice.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.File;
+import vogar.commands.Adb;
+
+class EnvironmentDevice extends Environment {
+    final Adb adb = new Adb();
+    final File runnerDir;
+    final File vogarTemp;
+    final int monitorPort;
+
+    EnvironmentDevice (boolean cleanBefore, boolean cleanAfter,
+            Integer debugPort, int monitorPort, File localTemp, File runnerDir) {
+        super(cleanBefore, cleanAfter, debugPort, localTemp);
+        this.runnerDir = runnerDir;
+        this.vogarTemp = new File(runnerDir, "/vogar.tmp");
+        this.monitorPort = monitorPort;
+    }
+
+    @Override void prepare() {
+        adb.waitForDevice();
+        adb.waitForNonEmptyDirectory(runnerDir.getParentFile(), 5 * 60);
+        if (cleanBefore) {
+            adb.rm(runnerDir);
+        }
+        adb.mkdir(runnerDir);
+        adb.mkdir(vogarTemp);
+        adb.mkdir(new File("/sdcard/dalvik-cache")); // TODO: only necessary on production devices.
+        adb.forwardTcp(monitorPort, monitorPort);
+        if (debugPort != null) {
+            adb.forwardTcp(debugPort, debugPort);
+        }
+    }
+
+    @Override protected void prepareUserDir(Action action) {
+        File actionClassesDirOnDevice = actionClassesDirOnDevice(action);
+        adb.mkdir(actionClassesDirOnDevice);
+        File resourcesDirectory = action.getResourcesDirectory();
+        if (resourcesDirectory != null) {
+            adb.push(resourcesDirectory, actionClassesDirOnDevice);
+        }
+        action.setUserDir(actionClassesDirOnDevice);
+    }
+
+    private File actionClassesDirOnDevice(Action action) {
+        return new File(runnerDir, action.getName());
+    }
+
+    @Override void cleanup(Action action) {
+        super.cleanup(action);
+        if (cleanAfter) {
+            adb.rm(actionClassesDirOnDevice(action));
+        }
+    }
+
+    @Override void shutdown() {
+        super.shutdown();
+        if (cleanAfter) {
+            adb.rm(runnerDir);
+        }
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/EnvironmentHost.java b/tools/runner/java/vogar/EnvironmentHost.java
similarity index 62%
rename from tools/runner/java/dalvik/runner/EnvironmentHost.java
rename to tools/runner/java/vogar/EnvironmentHost.java
index d02ea55..7942332 100644
--- a/tools/runner/java/dalvik/runner/EnvironmentHost.java
+++ b/tools/runner/java/vogar/EnvironmentHost.java
@@ -14,9 +14,11 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
+import vogar.commands.Command;
+import vogar.commands.Mkdir;
 
 class EnvironmentHost extends Environment {
 
@@ -27,19 +29,23 @@
 
     @Override void prepare() {}
 
-    @Override protected void prepareUserDir(TestRun testRun) {
-        File testUserDir = testUserDir(testRun);
+    @Override protected void prepareUserDir(Action action) {
+        File actionUserDir = actionUserDir(action);
 
         // if the user dir exists, cp would copy the files to the wrong place
-        if (testUserDir.exists()) {
+        if (actionUserDir.exists()) {
             throw new IllegalStateException();
         }
 
-        new Mkdir().mkdirs(testUserDir.getParentFile());
-        new Command("cp", "-r", testRun.getTestDirectory().toString(),
-                testUserDir.toString()).execute();
-        testRun.setUserDir(testUserDir);
-    }
+        File resourcesDirectory = action.getResourcesDirectory();
+        if (resourcesDirectory != null) {
+            new Mkdir().mkdirs(actionUserDir.getParentFile());
+            new Command("cp", "-r", resourcesDirectory.toString(),
+                    actionUserDir.toString()).execute();
+        } else {
+            new Mkdir().mkdirs(actionUserDir);
+        }
 
-    @Override void shutdown() {}
+        action.setUserDir(actionUserDir);
+    }
 }
diff --git a/tools/runner/java/vogar/Expectation.java b/tools/runner/java/vogar/Expectation.java
new file mode 100644
index 0000000..d997709
--- /dev/null
+++ b/tools/runner/java/vogar/Expectation.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.util.regex.Pattern;
+
+/**
+ * The expected result of an action execution. This is typically encoded in the
+ * expectations text file, which has the following format:
+ * <pre>
+ * test java.io.StreamTokenizer.Reset
+ * result UNSUPPORTED
+ * pattern .*should get token \[, but get -1.*
+ *
+ * # should we fix this?
+ * test java.util.Arrays.CopyMethods
+ * result COMPILE_FAILED
+ * pattern .*cannot find symbol.*
+ * </pre>
+ */
+final class Expectation {
+
+    /** The pattern to use when no expected output is specified */
+    private static final Pattern MATCH_ALL_PATTERN
+            = Pattern.compile(".*", Pattern.MULTILINE | Pattern.DOTALL);
+
+    /** The expectation of a general successful run. */
+    static final Expectation SUCCESS = new Expectation(Result.SUCCESS, null);
+
+    /** The action's expected result, such as {@code EXEC_FAILED}. */
+    private final Result result;
+
+    /** The pattern the expected output will match. */
+    private final Pattern pattern;
+
+    public Expectation(Result result, String pattern) {
+        if (result == null) {
+            throw new IllegalArgumentException();
+        }
+
+        this.result = result;
+        this.pattern = pattern != null
+                ? Pattern.compile(pattern, Pattern.MULTILINE | Pattern.DOTALL)
+                : MATCH_ALL_PATTERN;
+    }
+
+    public Result getResult() {
+        return result;
+    }
+
+    /**
+     * Returns true if {@code outcome} matches this expectation.
+     */
+    public boolean matches(Outcome outcome) {
+        return result == outcome.getResult() && patternMatches(outcome);
+    }
+
+    private boolean patternMatches(Outcome outcome) {
+        return pattern.matcher(Strings.join(outcome.getOutputLines(), "\n")).matches();
+    }
+}
diff --git a/tools/runner/java/vogar/ExpectationStore.java b/tools/runner/java/vogar/ExpectationStore.java
new file mode 100644
index 0000000..7d5a758
--- /dev/null
+++ b/tools/runner/java/vogar/ExpectationStore.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A database of expected outcomes. Entries in this database come in two forms.
+ * <ul>
+ *   <li>Outcome expectations name an outcome (or its prefix, such as
+ *       "java.util"), its expected result, and an optional pattern to match
+ *       the expected output.
+ *   <li>Failure expectations include a pattern that may match the output of any
+ *       outcome. These expectations are useful for hiding failures caused by
+ *       cross-cutting features that aren't supported.
+ * </ul>
+ *
+ * <p>If an outcome matches both an outcome expectation and a failure
+ * expectation, the outcome expectation will be returned.
+ */
+final class ExpectationStore {
+
+    private static final Logger logger = Logger.getLogger(ExpectationStore.class.getName());
+
+    /** Matches lines in the file containing a key and value pair. */
+    private static final Pattern KEY_VALUE_PAIR_PATTERN = Pattern.compile("(\\w+)\\s+(.+)");
+
+    private final Map<String, Expectation> outcomes = new HashMap<String, Expectation>();
+    private final Map<String, Expectation> failures = new HashMap<String, Expectation>();
+
+    private ExpectationStore() {}
+
+    /**
+     * Finds the expected result for the specified action or outcome name. This
+     * returns a value for all names, even if no explicit expectation was set.
+     */
+    public Expectation get(String name) {
+        Expectation byName = getByName(name);
+        return byName != null ? byName : Expectation.SUCCESS;
+    }
+
+    /**
+     * Finds the expected result for the specified outcome after it has
+     * completed. Unlike {@code get()}, this also takes into account the
+     * outcome's output.
+     */
+    public Expectation get(Outcome outcome) {
+        Expectation byName = getByName(outcome.getName());
+        if (byName != null) {
+            return byName;
+        }
+
+        for (Map.Entry<String, Expectation> entry : failures.entrySet()) {
+            if (entry.getValue().matches(outcome)) {
+                return entry.getValue();
+            }
+        }
+
+        return Expectation.SUCCESS;
+    }
+
+    private Expectation getByName(String name) {
+        while (true) {
+            Expectation expectation = outcomes.get(name);
+            if (expectation != null) {
+                return expectation;
+            }
+
+            int dot = name.lastIndexOf('.');
+            if (dot == -1) {
+                return null;
+            }
+
+            name = name.substring(0, dot);
+        }
+    }
+
+    public static ExpectationStore parse(Set<File> expectationFiles) throws IOException {
+        ExpectationStore result = new ExpectationStore();
+        for (File f : expectationFiles) {
+            if (f.exists()) {
+                result.parse(f);
+            }
+        }
+        return result;
+    }
+
+    public void parse(File expectationsFile) throws IOException {
+        logger.fine("loading expectations file " + expectationsFile);
+
+        BufferedReader reader = new BufferedReader(new FileReader(expectationsFile));
+        int count = 0;
+        try {
+            Matcher keyValuePairMatcher = KEY_VALUE_PAIR_PATTERN.matcher("");
+
+            // the fields of interest for the current element
+            String type = null;
+            String qualifiedName = null;
+            Result result = null;
+            String pattern = null;
+
+            String line;
+            while ((line = reader.readLine()) != null) {
+                line = line.trim();
+
+                if (line.length() == 0 || line.startsWith("#")) {
+                    continue; // skip comment and blank lines
+                }
+
+                keyValuePairMatcher.reset(line);
+                if (!keyValuePairMatcher.matches()) {
+                    throw new IllegalArgumentException("Unexpected line " + line
+                            + " in file " + expectationsFile);
+                }
+
+                String key = keyValuePairMatcher.group(1);
+                String value = keyValuePairMatcher.group(2);
+                if (key.equals("result") && result == null) {
+                    result = Result.valueOf(value);
+
+                } else if (key.equals("pattern") && pattern == null) {
+                    pattern = value;
+
+                } else if (key.equals("test") || key.equals("failure")) {
+                    // when we encounter a new qualified name, the previous
+                    // element is complete. Add it to the results.
+                    if (qualifiedName != null) {
+                        count++;
+                        put(type, qualifiedName, result, pattern);
+                        result = null;
+                        pattern = null;
+                    }
+                    type = key;
+                    qualifiedName = value;
+
+                } else {
+                    throw new IllegalArgumentException("Unexpected key " + key
+                            + " in file " + expectationsFile);
+                }
+            }
+
+            // add the last element in the file
+            if (qualifiedName != null) {
+                count++;
+                put(type, qualifiedName, result, pattern);
+            }
+
+            logger.fine("loaded " + count + " expectations from " + expectationsFile);
+        } finally {
+            reader.close();
+        }
+    }
+
+    void put(String type, String qualifiedName, Result result, String pattern) {
+        Expectation expectation = new Expectation(result, pattern);
+        Map<String, Expectation> map = "test".equals(type) ? outcomes : failures;
+        if (map.put(qualifiedName, expectation) != null) {
+            throw new IllegalArgumentException(
+                    "Duplicate expectations for " + qualifiedName);
+        }
+    }
+}
diff --git a/tools/runner/java/vogar/HostMonitor.java b/tools/runner/java/vogar/HostMonitor.java
new file mode 100644
index 0000000..d94b6c0
--- /dev/null
+++ b/tools/runner/java/vogar/HostMonitor.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ConnectException;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Connects to a target process to monitor its action.
+ */
+class HostMonitor {
+
+    private static final Logger logger = Logger.getLogger(HostMonitor.class.getName());
+
+    private final long monitorTimeoutSeconds;
+
+    HostMonitor(long monitorTimeoutSeconds) {
+        this.monitorTimeoutSeconds = monitorTimeoutSeconds;
+    }
+
+    /**
+     * Connect to the target process on the given port, read all of its
+     * outcomes into {@code handler}, and disconnect.
+     */
+    public boolean monitor(int port, Handler handler) {
+        Socket socket;
+        InputStream in;
+        int attempt = 0;
+        do {
+            try {
+                socket = new Socket("localhost", port);
+                in = new BufferedInputStream(socket.getInputStream());
+                if (checkStream(in)) {
+                    break;
+                }
+                in.close();
+                socket.close();
+            } catch (ConnectException recoverable) {
+            } catch (IOException e) {
+                logger.log(Level.WARNING, "Failed to connect to localhost:" + port, e);
+                return false;
+            }
+
+            if (attempt++ == monitorTimeoutSeconds) {
+                logger.warning("Exceeded " + monitorTimeoutSeconds
+                        + " attempts to connect to localhost:" + port);
+                return false;
+            }
+
+            logger.fine("connection " + attempt + " to localhost:" + port
+                    + " failed; retrying in 1s");
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+        } while (true);
+
+        logger.fine("action monitor connected to " + socket.getRemoteSocketAddress());
+
+        try {
+            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+            InputSource inputSource = new InputSource(in);
+            parser.parse(inputSource, new ClientXmlHandler(handler));
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            logger.log(Level.WARNING, "Connection error from localhost:" + port, e);
+            return false;
+        } catch (SAXException e) {
+            logger.log(Level.WARNING, "Received bad XML from localhost:" + port + " " + e);
+            return false;
+        }
+
+        try {
+            socket.close();
+        } catch (IOException ignored) {
+        }
+
+        return true;
+    }
+
+    /**
+     * Somewhere between the host and client process, broken socket connections
+     * are being accepted. Before we try to do any work on such a connection,
+     * check it to make sure it's not dead!
+     *
+     * TODO: file a bug (against adb?) for this
+     */
+    private boolean checkStream(InputStream in) throws IOException {
+        in.mark(1);
+        if (in.read() == -1) {
+            return false;
+        } else {
+            in.reset();
+            return true;
+        }
+    }
+
+    /**
+     * Handles updates on the outcomes of a target process.
+     */
+    public interface Handler {
+
+        /**
+         * Receive a completed outcome.
+         */
+        void outcome(Outcome outcome);
+
+        /**
+         * Receive partial output from an action being executed.
+         */
+        void output(String outcomeName, String output);
+    }
+
+    class ClientXmlHandler extends DefaultHandler {
+        private final Handler handler;
+
+        private String currentOutcomeName;
+        private String currentActionName;
+        private Result currentResult;
+        private StringBuilder output = new StringBuilder();
+
+        ClientXmlHandler(Handler handler) {
+            this.handler = handler;
+        }
+
+        /*
+         * Our XML wire format looks like this:
+         *
+         * <?xml version='1.0' encoding='UTF-8' ?>
+         * <vogar-monitor>
+         *   <outcome name="java.util.FormatterTest" action="java.util.FormatterTest">
+         *     test output
+         *     more test output
+         *     <result value="SUCCESS" />
+         *   </outcome>
+         * </vogar-monitor>
+         */
+
+        @Override public void startElement(String uri, String localName,
+                String qName, Attributes attributes) throws SAXException {
+            if (qName.equals("outcome")) {
+                if (currentOutcomeName != null) {
+                    throw new IllegalStateException();
+                }
+
+                currentOutcomeName = attributes.getValue("name");
+                currentActionName = attributes.getValue("action");
+                return;
+
+            } else if (qName.equals("result")) {
+                currentResult = Result.valueOf(attributes.getValue("value"));
+                return;
+
+            } else if (!qName.equals("vogar-monitor")) {
+                throw new IllegalArgumentException("Unrecognized: " + qName);
+            }
+        }
+
+        @Override public void characters(char[] ch, int start, int length)
+                throws SAXException {
+            if (currentOutcomeName != null) {
+                String text = new String(ch, start, length);
+                output.append(text);
+                handler.output(currentOutcomeName, text);
+            }
+        }
+
+        @Override public void endElement(String uri, String localName, String qName)
+                throws SAXException {
+            if (qName.equals("outcome")) {
+                handler.outcome(new Outcome(currentOutcomeName, currentActionName,
+                        currentResult, Collections.singletonList(output.toString())));
+                currentOutcomeName = null;
+                currentActionName = null;
+                currentResult = null;
+                output.delete(0, output.length());
+            }
+        }
+    }
+}
diff --git a/tools/runner/java/vogar/JUnitSpec.java b/tools/runner/java/vogar/JUnitSpec.java
new file mode 100644
index 0000000..626efcb
--- /dev/null
+++ b/tools/runner/java/vogar/JUnitSpec.java
@@ -0,0 +1,54 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import vogar.target.JUnitRunner;
+import vogar.target.Runner;
+
+/**
+ * Create {@link Action}s for {@code .java} files with JUnit tests in them.
+ */
+class JUnitSpec extends NamingPatternRunnerSpec {
+
+    @Override protected boolean matches(File file) {
+        String filename = file.getName();
+        return super.matches(file) && (filename.endsWith("Test.java")
+                || filename.endsWith("TestSuite.java")
+                || filename.contains("Tests"));
+    }
+
+    public boolean supports(String className) {
+        return className.endsWith("Test")
+                || className.endsWith("TestSuite")
+                || className.contains("Tests");
+    }
+
+    public Class<? extends Runner> getRunnerClass() {
+        return JUnitRunner.class;
+    }
+
+    public File getSource() {
+        return new File(Vogar.HOME_JAVA, "vogar/target/JUnitRunner.java");
+    }
+
+    public Classpath getClasspath() {
+        // TODO: jar up just the junit classes and drop the jar in our lib/ directory.
+        return Classpath.of(
+                new File("out/host/common/obj/JAVA_LIBRARIES/junit_intermediates/javalib.jar").getAbsoluteFile());
+    }
+}
diff --git a/tools/runner/java/vogar/JavaVm.java b/tools/runner/java/vogar/JavaVm.java
new file mode 100644
index 0000000..f8bdd56
--- /dev/null
+++ b/tools/runner/java/vogar/JavaVm.java
@@ -0,0 +1,61 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * A local Java virtual machine like Harmony or the RI.
+ */
+final class JavaVm extends Vm {
+
+    private final File javaHome;
+
+    JavaVm(Integer debugPort, File sdkJar, List<String> javacArgs, int monitorPort,
+            File localTemp, File javaHome, List<String> additionalVmArgs,
+            List<String> targetArgs, boolean cleanBefore, boolean cleanAfter,
+            Classpath classpath) {
+        super(new EnvironmentHost(cleanBefore, cleanAfter, debugPort, localTemp),
+                sdkJar, javacArgs, additionalVmArgs, targetArgs, monitorPort, classpath);
+        this.javaHome = javaHome;
+    }
+
+    @Override protected VmCommandBuilder newVmCommandBuilder(File workingDirectory) {
+        String java = javaHome == null ? "java" : new File(javaHome, "bin/java").getPath();
+        return new VmCommandBuilder()
+                .vmCommand(java)
+                .workingDir(workingDirectory);
+    }
+
+    @Override protected Classpath getRuntimeClasspath(Action action) {
+        Classpath result = new Classpath();
+        result.addAll(classpath);
+        result.addAll(environment.hostJar(action));
+
+        /*
+         * For javax.net.ssl tests dependency on Bouncy Castle for
+         * creating a self-signed X509 certificate. Needs to be run
+         * with an openjdk, not a sunjdk, which expects a signed jar
+         * to authenticate security providers. For example:
+         *
+         * --java-home /usr/lib/jvm/java-6-openjdk
+         */
+        result.addAll(new File("/usr/share/java/bcprov.jar"));
+        return result;
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/Javac.java b/tools/runner/java/vogar/Javac.java
similarity index 90%
rename from tools/runner/java/dalvik/runner/Javac.java
rename to tools/runner/java/vogar/Javac.java
index 26e8bb9..83ef8f0 100644
--- a/tools/runner/java/dalvik/runner/Javac.java
+++ b/tools/runner/java/vogar/Javac.java
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import vogar.commands.Command;
 
 /**
  * A javac command.
@@ -29,7 +30,7 @@
     private final Command.Builder builder = new Command.Builder();
 
     Javac() {
-        builder.args("javac", "-Xmaxerrs", "1");
+        builder.args("javac");
     }
 
     public Javac bootClasspath(File... path) {
@@ -56,6 +57,11 @@
         return this;
     }
 
+    public Javac extra(List<String> extra) {
+        builder.args(extra);
+        return this;
+    }
+
     public List<String> compile(Collection<File> files) {
         return builder.args(Strings.objectsToStrings(files))
                 .execute();
diff --git a/tools/runner/java/dalvik/runner/JtregFinder.java b/tools/runner/java/vogar/JtregSpec.java
similarity index 81%
rename from tools/runner/java/dalvik/runner/JtregFinder.java
rename to tools/runner/java/vogar/JtregSpec.java
index d846ae2..8c06cc8 100644
--- a/tools/runner/java/dalvik/runner/JtregFinder.java
+++ b/tools/runner/java/vogar/JtregSpec.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import com.sun.javatest.TestDescription;
 import com.sun.javatest.TestResult;
@@ -22,23 +22,25 @@
 import com.sun.javatest.TestSuite;
 import com.sun.javatest.WorkDirectory;
 import com.sun.javatest.regtest.RegressionTestSuite;
-
 import java.io.File;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.logging.Logger;
+import vogar.commands.Mkdir;
+import vogar.target.JtregRunner;
+import vogar.target.Runner;
 
 /**
- * Create {@link TestRun}s for {@code .java} files with jtreg tests in them.
+ * Create {@link Action}s for {@code .java} files with jtreg tests in them.
  */
-class JtregFinder implements CodeFinder {
+class JtregSpec implements RunnerSpec {
 
     // TODO: add support for the  @library directive, as seen in
     //   test/com/sun/crypto/provider/Cipher/AES/TestKATForECB_VT.java
 
-    private static final Logger logger = Logger.getLogger(JtregFinder.class.getName());
+    private static final Logger logger = Logger.getLogger(JtregSpec.class.getName());
 
     /**
      * The subpath of a platform implementation under which tests live. Used to
@@ -49,14 +51,14 @@
 
     private final File localTemp;
 
-    JtregFinder(File localTemp) {
+    JtregSpec(File localTemp) {
         this.localTemp = localTemp;
     }
 
     /**
      * Returns the tests in {@code directoryToScan}.
      */
-    public Set<TestRun> findTests(File directoryToScan) {
+    public Set<Action> findActions(File directoryToScan) {
         // for now, jtreg doesn't know how to scan anything but directories
         if (!directoryToScan.isDirectory()) {
             return Collections.emptySet();
@@ -77,18 +79,13 @@
             WorkDirectory wd = WorkDirectory.convert(workDirectory, testSuite);
             TestResultTable resultTable = wd.getTestResultTable();
 
-            Set<TestRun> result = new LinkedHashSet<TestRun>();
+            Set<Action> result = new LinkedHashSet<Action>();
             for (Iterator i = resultTable.getIterator(); i.hasNext(); ) {
                 TestResult testResult = (TestResult) i.next();
                 TestDescription description = testResult.getDescription();
                 String qualifiedName = qualifiedName(description);
-                String suiteName = suiteName(description);
-                String testName = description.getName();
                 String testClass = description.getName();
-                result.add(new TestRun(description.getDir(), description.getFile(),
-                        testClass, suiteName, testName, qualifiedName,
-                        description.getTitle(),
-                        getRunnerClass(), getRunnerJava(), getRunnerClasspath()));
+                result.add(new Action(qualifiedName, testClass, description.getDir(), description.getFile(), this));
             }
             return result;
         } catch (Exception jtregFailure) {
@@ -97,6 +94,11 @@
         }
     }
 
+    public boolean supports(String className) {
+        // the jtreg runner cannot run prebuilt classes
+        return false;
+    }
+
     /**
      * Returns a fully qualified name of the form {@code
      * java.lang.Math.PowTests} from the given test description. The returned
@@ -129,11 +131,11 @@
         return JtregRunner.class;
     }
 
-    public File getRunnerJava() {
-        return new File(DalvikRunner.HOME_JAVA, "dalvik/runner/JtregRunner.java");
+    public File getSource() {
+        return new File(Vogar.HOME_JAVA, "vogar/target/JtregRunner.java");
     }
 
-    public Classpath getRunnerClasspath() {
+    public Classpath getClasspath() {
         return new Classpath();
     }
 }
diff --git a/tools/runner/java/dalvik/runner/MainFinder.java b/tools/runner/java/vogar/MainSpec.java
similarity index 61%
rename from tools/runner/java/dalvik/runner/MainFinder.java
rename to tools/runner/java/vogar/MainSpec.java
index 282969f..5a0bcf5 100644
--- a/tools/runner/java/dalvik/runner/MainFinder.java
+++ b/tools/runner/java/vogar/MainSpec.java
@@ -14,32 +14,30 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
+import vogar.target.MainRunner;
+import vogar.target.Runner;
 
 /**
- * Create {@link TestRun}s for {@code .java} files with main methods in them.
+ * Create {@link Action}s for {@code .java} files with main methods in them.
  */
-class MainFinder extends NamingPatternCodeFinder {
+class MainSpec extends NamingPatternRunnerSpec {
 
-    @Override protected boolean matches(File file) {
-        return file.getName().endsWith(".java");
-    }
-
-    @Override protected String testName(File file) {
-        return "main";
+    public boolean supports(String className) {
+        return true;
     }
 
     public Class<? extends Runner> getRunnerClass() {
         return MainRunner.class;
     }
 
-    public File getRunnerJava() {
-        return new File(DalvikRunner.HOME_JAVA, "dalvik/runner/MainRunner.java");
+    public File getSource() {
+        return new File(Vogar.HOME_JAVA, "vogar/target/MainRunner.java");
     }
 
-    public Classpath getRunnerClasspath() {
+    public Classpath getClasspath() {
         return new Classpath();
     }
 }
diff --git a/tools/runner/java/dalvik/runner/Md5Cache.java b/tools/runner/java/vogar/Md5Cache.java
similarity index 97%
rename from tools/runner/java/dalvik/runner/Md5Cache.java
rename to tools/runner/java/vogar/Md5Cache.java
index f6ba85d..2855ae8 100644
--- a/tools/runner/java/dalvik/runner/Md5Cache.java
+++ b/tools/runner/java/vogar/Md5Cache.java
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.security.MessageDigest;
 import java.util.logging.Logger;
+import vogar.commands.Command;
+import vogar.commands.Mkdir;
 
 /**
  * Caches content by MD5.
diff --git a/tools/runner/java/vogar/Mode.java b/tools/runner/java/vogar/Mode.java
new file mode 100644
index 0000000..7009adb
--- /dev/null
+++ b/tools/runner/java/vogar/Mode.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import vogar.commands.Command;
+import vogar.commands.CommandFailedException;
+import vogar.commands.Mkdir;
+
+/**
+ * A Mode for running actions. Examples including running in a virtual machine
+ * either on the host or a device or within a specific context such as within an
+ * Activity.
+ */
+abstract class Mode {
+
+    private static final Pattern JAVA_SOURCE_PATTERN = Pattern.compile("\\/(\\w)+\\.java$");
+
+    private static final Logger logger = Logger.getLogger(Mode.class.getName());
+
+    protected final Environment environment;
+    protected final File sdkJar;
+    protected final List<String> javacArgs;
+    protected final int monitorPort;
+
+    /**
+     * Set of Java files needed to built to tun the currently selected set of
+     * actions. We build a subset rather than all the files all the time to
+     * reduce dex packaging costs in the activity mode case.
+     */
+    protected final Set<File> runnerJava = new HashSet<File>();
+
+    /**
+     * User classes that need to be included in the classpath for both
+     * compilation and execution. Also includes dependencies of all active
+     * runners.
+     */
+    protected final Classpath classpath = new Classpath();
+
+    Mode(Environment environment, File sdkJar, List<String> javacArgs,
+            int monitorPort, Classpath classpath) {
+        this.environment = environment;
+        this.sdkJar = sdkJar;
+        this.javacArgs = javacArgs;
+        this.monitorPort = monitorPort;
+        this.classpath.addAll(classpath);
+    }
+
+    /**
+     * Initializes the temporary directories and harness necessary to run
+     * actions.
+     */
+    protected void prepare(Set<RunnerSpec> runners) {
+        for (RunnerSpec runnerSpec : runners) {
+            runnerJava.add(runnerSpec.getSource());
+            classpath.addAll(runnerSpec.getClasspath());
+        }
+        runnerJava.add(new File(Vogar.HOME_JAVA, "vogar/target/TestRunner.java"));
+        environment.prepare();
+        classpath.addAll(compileRunner());
+        installRunner();
+    }
+
+    private List<File> dalvikAnnotationSourceFiles() {
+        // Hopefully one day we'll strip the dalvik annotations out, but until then we need to make
+        // them available to javac(1).
+        File sourceDir = new File("dalvik/libcore/dalvik/src/main/java/dalvik/annotation");
+        File[] javaSourceFiles = sourceDir.listFiles(new FilenameFilter() {
+            public boolean accept(File dir, String filename) {
+                return filename.endsWith(".java");
+            }
+        });
+        return Arrays.asList(javaSourceFiles);
+    }
+
+    /**
+     * Returns a .jar file containing the compiled runner .java files.
+     */
+    private File compileRunner() {
+        logger.fine("build runner");
+        File classes = environment.file("runner", "classes");
+        File jar = environment.hostJar("runner");
+        new Mkdir().mkdirs(classes);
+        new Javac()
+                .bootClasspath(sdkJar)
+                .classpath(classpath)
+                .sourcepath(Vogar.HOME_JAVA)
+                .destination(classes)
+                .extra(javacArgs)
+                .compile(runnerJava);
+        new Command("jar", "cvfM", jar.getPath(),
+                 "-C", classes.getPath(), "./").execute();
+        return jar;
+    }
+
+    /**
+     * Compiles classes for the given action and makes them ready for execution.
+     *
+     * @return null if the compilation succeeded, or an outcome describing the
+     *      failure otherwise.
+     */
+    public Outcome buildAndInstall(Action action) {
+        logger.fine("build " + action.getName());
+
+        try {
+            File jar = compile(action);
+            postCompile(action, jar);
+        } catch (CommandFailedException e) {
+            return new Outcome(action.getName(), action.getName(),
+                    Result.COMPILE_FAILED, e.getOutputLines());
+        } catch (IOException e) {
+            return new Outcome(action.getName(), Result.ERROR, e);
+        }
+        environment.prepareUserDir(action);
+        return null;
+    }
+
+    /**
+     * Returns the .jar file containing the action's compiled classes.
+     *
+     * @throws CommandFailedException if javac fails
+     */
+    private File compile(Action action) throws IOException {
+        File classesDir = environment.file(action, "classes");
+        new Mkdir().mkdirs(classesDir);
+        FileOutputStream propertiesOut = new FileOutputStream(
+                new File(classesDir, TestProperties.FILE));
+        Properties properties = new Properties();
+        fillInProperties(properties, action);
+        properties.store(propertiesOut, "generated by " + Mode.class.getName());
+        propertiesOut.close();
+
+        Javac javac = new Javac();
+
+        Set<File> sourceFiles = new HashSet<File>();
+        sourceFiles.addAll(dalvikAnnotationSourceFiles());
+
+        File javaFile = action.getJavaFile();
+        if (javaFile != null) {
+            if (!JAVA_SOURCE_PATTERN.matcher(javaFile.toString()).find()) {
+                throw new CommandFailedException(Collections.<String>emptyList(),
+                        Collections.singletonList("Cannot compile: " + javaFile));
+            }
+            sourceFiles.add(javaFile);
+            javac.sourcepath(javaFile.getParentFile());
+        }
+
+        javac.bootClasspath(sdkJar)
+                .classpath(classpath)
+                .destination(classesDir)
+                .extra(javacArgs)
+                .compile(sourceFiles);
+
+        File jar = environment.hostJar(action);
+        new Command("jar", "cvfM", jar.getPath(),
+                "-C", classesDir.getPath(), "./").execute();
+        return jar;
+    }
+
+    /**
+     * Fill in properties for running in this mode
+     */
+    protected void fillInProperties(Properties properties, Action action) {
+        properties.setProperty(TestProperties.TEST_CLASS, action.getTargetClass());
+        properties.setProperty(TestProperties.QUALIFIED_NAME, action.getName());
+        properties.setProperty(TestProperties.RUNNER_CLASS, action.getRunnerSpec().getRunnerClass().getName());
+        properties.setProperty(TestProperties.MONITOR_PORT, String.valueOf(monitorPort));
+    }
+
+    /**
+     * Hook method called after runner compilation.
+     */
+    protected void installRunner() {}
+
+    /**
+     * Hook method called after action compilation.
+     */
+    protected void postCompile(Action action, File jar) {}
+
+    /**
+     * Create the command that executes the action.
+     */
+    protected abstract Command createActionCommand(Action action);
+
+    /**
+     * Deletes files and releases any resources required for the execution of
+     * the given action.
+     */
+    void cleanup(Action action) {
+        environment.cleanup(action);
+    }
+
+    /**
+     * Cleans up after all actions have completed.
+     */
+    void shutdown() {
+        environment.shutdown();
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java b/tools/runner/java/vogar/NamingPatternRunnerSpec.java
similarity index 78%
rename from tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java
rename to tools/runner/java/vogar/NamingPatternRunnerSpec.java
index 19c9df2..429bab9 100644
--- a/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java
+++ b/tools/runner/java/vogar/NamingPatternRunnerSpec.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
 import java.io.IOException;
@@ -27,32 +27,31 @@
  * A code finder that traverses through the directory tree looking for matching
  * naming patterns.
  */
-abstract class NamingPatternCodeFinder implements CodeFinder {
+abstract class NamingPatternRunnerSpec implements RunnerSpec {
 
     private final String PACKAGE_PATTERN = "(?m)^\\s*package\\s+(\\S+)\\s*;";
 
     private final String TYPE_DECLARATION_PATTERN
             = "(?m)\\b(?:public|private)\\s+(?:final\\s+)?(?:interface|class|enum)\\b";
 
-    public Set<TestRun> findTests(File testDirectory) {
-        Set<TestRun> result = new LinkedHashSet<TestRun>();
-        findTestsRecursive(result, testDirectory);
+    public Set<Action> findActions(File searchDirectory) {
+        Set<Action> result = new LinkedHashSet<Action>();
+        findActionsRecursive(result, searchDirectory);
         return result;
     }
 
     /**
-     * Returns true if {@code file} contains a test class of this type.
+     * Returns true if {@code file} contains a action class of this type.
      */
     protected boolean matches(File file) {
-        return file.getName().endsWith(".java");
+        return (!file.getName().startsWith(".")
+                && file.getName().endsWith(".java"));
     }
 
-    protected abstract String testName(File file);
-
-    private void findTestsRecursive(Set<TestRun> sink, File file) {
+    private void findActionsRecursive(Set<Action> sink, File file) {
         if (file.isDirectory()) {
             for (File child : file.listFiles()) {
-                findTestsRecursive(sink, child);
+                findActionsRecursive(sink, child);
             }
             return;
         }
@@ -62,12 +61,7 @@
         }
 
         String className = fileToClass(file);
-        File testDirectory = file.getParentFile();
-        String testName = testName(file);
-        String testDescription = null;
-        sink.add(new TestRun(testDirectory, file, className, className,
-                testName, className, testDescription,
-                getRunnerClass(), getRunnerJava(), getRunnerClasspath()));
+        sink.add(new Action(className, className, null, file, this));
     }
 
     /**
diff --git a/tools/runner/java/dalvik/runner/Option.java b/tools/runner/java/vogar/Option.java
similarity index 97%
rename from tools/runner/java/dalvik/runner/Option.java
rename to tools/runner/java/vogar/Option.java
index 779aa63..a73fbbf 100644
--- a/tools/runner/java/dalvik/runner/Option.java
+++ b/tools/runner/java/vogar/Option.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git a/tools/runner/java/dalvik/runner/OptionParser.java b/tools/runner/java/vogar/OptionParser.java
similarity index 99%
rename from tools/runner/java/dalvik/runner/OptionParser.java
rename to tools/runner/java/vogar/OptionParser.java
index 3516264..d031316 100644
--- a/tools/runner/java/dalvik/runner/OptionParser.java
+++ b/tools/runner/java/vogar/OptionParser.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
 import java.lang.reflect.Field;
diff --git a/tools/runner/java/vogar/Outcome.java b/tools/runner/java/vogar/Outcome.java
new file mode 100644
index 0000000..471f937
--- /dev/null
+++ b/tools/runner/java/vogar/Outcome.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * An outcome of an action. Some actions may have multiple outcomes. For
+ * example, JUnit tests have one outcome for each test method.
+ */
+final class Outcome {
+
+    private final String outcomeName;
+    private final String actionName;
+    private final Result result;
+    private final List<String> outputLines;
+
+    public Outcome(String outcomeName, String actionName, Result result,
+            List<String> outputLines) {
+        this.outcomeName = outcomeName;
+        this.actionName = actionName;
+        this.result = result;
+        this.outputLines = outputLines;
+    }
+
+    public Outcome(String actionName, Result result, String outputLine) {
+        this.outcomeName = actionName;
+        this.actionName = actionName;
+        this.result = result;
+        this.outputLines = Collections.singletonList(outputLine);
+    }
+
+    public Outcome(String actionName, Result result, Throwable throwable) {
+        this.outcomeName = actionName;
+        this.actionName = actionName;
+        this.result = result;
+        this.outputLines = throwableToLines(throwable);
+    }
+
+    public String getName() {
+        return outcomeName;
+    }
+
+    public String getActionName() {
+        return actionName;
+    }
+
+    public Result getResult() {
+        return result;
+    }
+
+    public List<String> getOutputLines() {
+        return outputLines;
+    }
+
+    private static List<String> throwableToLines(Throwable t) {
+        StringWriter writer = new StringWriter();
+        PrintWriter out = new PrintWriter(writer);
+        t.printStackTrace(out);
+        return Arrays.asList(writer.toString().split("\\n"));
+    }
+
+    /**
+     * Returns the action's suite name, such as java.lang.Integer or
+     * java.lang.IntegerTest.
+     */
+    public String getSuiteName() {
+        int split = split(outcomeName);
+        return split == -1 ? "defaultpackage" : outcomeName.substring(0, split);
+    }
+
+    /**
+     * Returns the specific action name, such as BitTwiddle or testBitTwiddle.
+     */
+    public String getTestName() {
+        int split = split(outcomeName);
+        return split == -1 ? outcomeName : outcomeName.substring(split + 1);
+    }
+
+    private static int split(String name) {
+        int lastHash = name.indexOf('#');
+        return lastHash == -1 ? name.lastIndexOf('.') : lastHash;
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/Result.java b/tools/runner/java/vogar/Result.java
similarity index 89%
rename from tools/runner/java/dalvik/runner/Result.java
rename to tools/runner/java/vogar/Result.java
index 461f102..45c88ce 100644
--- a/tools/runner/java/dalvik/runner/Result.java
+++ b/tools/runner/java/vogar/Result.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 /**
  * The result of a test or benchmark execution.
@@ -22,7 +22,7 @@
 public enum Result {
 
     /**
-     * A test that cannot be run by this harness, such as a shell script.
+     * An action that cannot be run by this harness, such as a shell script.
      */
     UNSUPPORTED,
 
diff --git a/tools/runner/java/vogar/RunnerSpec.java b/tools/runner/java/vogar/RunnerSpec.java
new file mode 100644
index 0000000..8054b89
--- /dev/null
+++ b/tools/runner/java/vogar/RunnerSpec.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar;
+
+import java.io.File;
+import java.util.Set;
+import vogar.target.Runner;
+
+/**
+ * Defines a runner for a type of Java code, such as a JUnit test, benchmark,
+ * or class with main method.
+ */
+public interface RunnerSpec {
+
+    /**
+     * Returns all actions in the given file or directory. If the returned set
+     * is empty, no executable code of this kind were found.
+     */
+    Set<Action> findActions(File file);
+
+    /**
+     * Returns true if this runner can exercise {@code clazz}.
+     *
+     * @param className a fully qualified classname.
+     */
+    boolean supports(String className);
+
+    /**
+     * Return the class for the TestRunner
+     */
+    Class<? extends Runner> getRunnerClass();
+
+    /**
+     * Return the Java file for the TestRunner
+     */
+    File getSource();
+
+    /**
+     * Return the compile classpath for the TestRunner
+     */
+    Classpath getClasspath();
+}
diff --git a/tools/runner/java/dalvik/runner/Strings.java b/tools/runner/java/vogar/Strings.java
similarity index 84%
rename from tools/runner/java/dalvik/runner/Strings.java
rename to tools/runner/java/vogar/Strings.java
index e696841..d46d860 100644
--- a/tools/runner/java/dalvik/runner/Strings.java
+++ b/tools/runner/java/vogar/Strings.java
@@ -15,7 +15,7 @@
  */
 
 
-package dalvik.runner;
+package vogar;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -31,7 +31,7 @@
  */
 public class Strings {
 
-    static String readFile(File f) throws IOException {
+    public static String readFile(File f) throws IOException {
         StringBuilder result = new StringBuilder();
         BufferedReader in =
                 new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8"));
@@ -44,11 +44,11 @@
         return result.toString();
     }
 
-    static String join(Object[] objects, String delimiter) {
+    public static String join(Object[] objects, String delimiter) {
         return join(Arrays.asList(objects), delimiter);
     }
 
-    static String join(Iterable<?> objects, String delimiter) {
+    public static String join(Iterable<?> objects, String delimiter) {
         Iterator<?> i = objects.iterator();
         if (!i.hasNext()) {
             return "";
@@ -62,7 +62,7 @@
         return result.toString();
     }
 
-    static String[] objectsToStrings(Object[] objects) {
+    public static String[] objectsToStrings(Object[] objects) {
         String[] result = new String[objects.length];
         int i = 0;
         for (Object o : objects) {
@@ -71,7 +71,7 @@
         return result;
     }
 
-    static String[] objectsToStrings(Collection<?> objects) {
+    public static String[] objectsToStrings(Collection<?> objects) {
         return objectsToStrings(objects.toArray());
     }
 }
diff --git a/tools/runner/java/dalvik/runner/TestProperties.java b/tools/runner/java/vogar/TestProperties.java
similarity index 74%
rename from tools/runner/java/dalvik/runner/TestProperties.java
rename to tools/runner/java/vogar/TestProperties.java
index 1e90799..d9a5b7b 100644
--- a/tools/runner/java/dalvik/runner/TestProperties.java
+++ b/tools/runner/java/vogar/TestProperties.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 /**
  * TestProperties is a common class of constants shared between the
- * DalvikRunner on the host and TestRunner classes potentially running
+ * Vogar on the host and TestRunner classes potentially running
  * on other devices.
  */
 final public class TestProperties {
@@ -52,28 +52,10 @@
      */
     public static final String DEVICE_RUNNER_DIR = "deviceRunnerDir";
 
-
     /**
-     * The output file written by TestActivity
+     * Port to accept monitor connections on.
      */
-    public static final String RESULT_FILE = "result.txt";
+    public static final String MONITOR_PORT = "monitorPort";
 
-    /**
-     * Result value for successful test
-     */
-    public static final String RESULT_SUCCESS = "SUCCESS";
-
-    /**
-     * Result value for failed test
-     */
-    public static final String RESULT_FAILURE = "FAILURE";
-
-    public static String result(boolean success) {
-        return success ? RESULT_SUCCESS : RESULT_FAILURE;
-    }
-
-    /**
-     * This class should not be instantiated
-     */
     private TestProperties() {}
 }
diff --git a/tools/runner/java/dalvik/runner/Threads.java b/tools/runner/java/vogar/Threads.java
similarity index 96%
rename from tools/runner/java/dalvik/runner/Threads.java
rename to tools/runner/java/vogar/Threads.java
index 58b075b..35cc3ab 100644
--- a/tools/runner/java/dalvik/runner/Threads.java
+++ b/tools/runner/java/vogar/Threads.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -23,7 +23,7 @@
 /**
  * Utility methods for working with threads.
  */
-class Threads {
+public class Threads {
 
     public static ThreadFactory daemonThreadFactory() {
         return new ThreadFactory() {
diff --git a/tools/runner/java/dalvik/runner/Vm.java b/tools/runner/java/vogar/Vm.java
similarity index 76%
rename from tools/runner/java/dalvik/runner/Vm.java
rename to tools/runner/java/vogar/Vm.java
index 8ff5858..350b861 100644
--- a/tools/runner/java/dalvik/runner/Vm.java
+++ b/tools/runner/java/vogar/Vm.java
@@ -14,64 +14,58 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar;
 
 import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.TimeoutException;
-import java.util.logging.Logger;
+import vogar.commands.Command;
+import vogar.target.TestRunner;
 
 /**
  * A Java-like virtual machine for compiling and running tests.
  */
 public abstract class Vm extends Mode {
 
-    private static final Logger logger = Logger.getLogger(Vm.class.getName());
-
     protected final List<String> additionalVmArgs;
+    protected final List<String> targetArgs;
 
-    Vm(Environment environment, long timeoutSeconds, File sdkJar,
-           PrintStream tee, List<String> additionalVmArgs) {
-        super(environment, timeoutSeconds, sdkJar, tee);
+    Vm(Environment environment, File sdkJar, List<String> javacArgs,
+            List<String> additionalVmArgs, List<String> targetArgs, int monitorPort,
+            Classpath classpath) {
+        super(environment, sdkJar, javacArgs, monitorPort, classpath);
         this.additionalVmArgs = additionalVmArgs;
+        this.targetArgs = targetArgs;
     }
 
     /**
-     * Returns a VM for test execution.
+     * Returns a VM for action execution.
      */
-    @Override protected List<String> runTestCommand(TestRun testRun)
-            throws TimeoutException {
-        Command command = newVmCommandBuilder(testRun.getUserDir())
-                .classpath(getRuntimeSupportClasspath(testRun))
-                .userDir(testRun.getUserDir())
+    @Override protected Command createActionCommand(Action action) {
+        return newVmCommandBuilder(action.getUserDir())
+                .classpath(getRuntimeClasspath(action))
+                .userDir(action.getUserDir())
                 .debugPort(environment.debugPort)
                 .vmArgs(additionalVmArgs)
                 .mainClass(TestRunner.class.getName())
-                .output(tee)
+                .args(targetArgs)
                 .build();
-        return command.executeWithTimeout(timeoutSeconds);
     }
 
     /**
-     * Returns a VM for test execution.
+     * Returns a VM for action execution.
      */
     protected abstract VmCommandBuilder newVmCommandBuilder(File workingDirectory);
 
     /**
      * Returns the classpath containing JUnit and the dalvik annotations
-     * required for test execution.
+     * required for action execution.
      */
-    protected abstract Classpath getRuntimeSupportClasspath(TestRun testRun);
+    protected abstract Classpath getRuntimeClasspath(Action action);
 
     /**
      * Builds a virtual machine command.
@@ -86,6 +80,7 @@
         private PrintStream output;
         private List<String> vmCommand = Collections.singletonList("java");
         private List<String> vmArgs = new ArrayList<String>();
+        private List<String> args = new ArrayList<String>();
 
         public VmCommandBuilder vmCommand(String... vmCommand) {
             this.vmCommand = Arrays.asList(vmCommand.clone());
@@ -136,6 +131,15 @@
             return this;
         }
 
+        public VmCommandBuilder args(String... args) {
+            return args(Arrays.asList(args));
+        }
+
+        public VmCommandBuilder args(Collection<String> args) {
+            this.args.addAll(args);
+            return this;
+        }
+
         public Command build() {
             Command.Builder builder = new Command.Builder();
             builder.args(vmCommand);
@@ -156,6 +160,7 @@
 
             builder.args(vmArgs);
             builder.args(mainClass);
+            builder.args(args);
 
             builder.tee(output);
 
diff --git a/tools/runner/java/vogar/Vogar.java b/tools/runner/java/vogar/Vogar.java
new file mode 100644
index 0000000..1f6ef96
--- /dev/null
+++ b/tools/runner/java/vogar/Vogar.java
@@ -0,0 +1,414 @@
+/*
+ * 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 vogar;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.regex.Pattern;
+
+/**
+ * Command line interface for running benchmarks and tests on dalvik.
+ */
+public final class Vogar {
+
+    static final File HOME = new File("dalvik/libcore/tools/runner");
+    static final File HOME_JAVA = new File(HOME, "java");
+
+    static final Pattern CLASS_NAME_PATTERN
+            = Pattern.compile("(\\w+)(\\.\\w+)*\\.[A-Z]\\w*");
+
+    private static class Options {
+
+        private final Classpath classpath = Classpath.of(
+            // TODO: we should be able to work with a shipping SDK, not depend on out/...
+            new File("out/host/common/obj/JAVA_LIBRARIES/kxml2-2.3.0_intermediates/javalib.jar").getAbsoluteFile());
+
+        private final List<File> actionFiles = new ArrayList<File>();
+        private final List<String> actionClasses = new ArrayList<String>();
+        private final List<String> targetArgs = new ArrayList<String>();
+
+        @Option(names = { "--expectations" })
+        private Set<File> expectationFiles = new LinkedHashSet<File>();
+        {
+            File[] files = new File("dalvik/libcore/tools/runner/expectations").listFiles();
+            if (files != null) {
+                expectationFiles.addAll(Arrays.asList(files));
+            }
+        }
+
+        private static String MODE_DEVICE = "device";
+        private static String MODE_HOST = "host";
+        private static String MODE_ACTIVITY = "activity";
+        @Option(names = { "--mode" })
+        private String mode = MODE_DEVICE;
+
+        @Option(names = { "--timeout" })
+        private long timeoutSeconds = 10 * 60; // default is ten minutes;
+
+        @Option(names = { "--monitor-timeout" })
+        private long monitorTimeout = 10;
+
+        @Option(names = { "--clean-before" })
+        private boolean cleanBefore = true;
+
+        @Option(names = { "--clean-after" })
+        private boolean cleanAfter = true;
+
+        @Option(names = { "--clean" })
+        private boolean clean = true;
+
+        @Option(names = { "--xml-reports-directory" })
+        private File xmlReportsDirectory;
+
+        @Option(names = { "--indent" })
+        private String indent = "  ";
+
+        @Option(names = { "--verbose" })
+        private boolean verbose;
+
+        @Option(names = { "--stream" })
+        private boolean stream;
+
+        @Option(names = { "--color" })
+        private boolean color = true;
+
+        @Option(names = { "--debug" })
+        private Integer debugPort;
+
+        @Option(names = { "--device-runner-dir" })
+        private File deviceRunnerDir = new File("/sdcard/dalvikrunner");
+
+        @Option(names = { "--vm-arg" })
+        private List<String> vmArgs = new ArrayList<String>();
+
+        @Option(names = { "--java-home" })
+        private File javaHome;
+
+        @Option(names = { "--javac-arg" })
+        private List<String> javacArgs = new ArrayList<String>();
+
+        @Option(names = { "--sdk" })
+        private File sdkJar = new File("/home/dalvik-prebuild/android-sdk-linux/platforms/android-2.0/android.jar");
+
+        private void printUsage() {
+            System.out.println("Usage: Vogar [options]... <actions>... [target args]...");
+            System.out.println();
+            System.out.println("  <actions>: .java files, .jar files, directories, or class names.");
+            System.out.println("      These should be JUnit tests, jtreg tests, Caliper benchmarks");
+            System.out.println("      or executable Java classes.");
+            System.out.println();
+            System.out.println("  [args]: arguments passed to the target process. This is only useful when");
+            System.out.println("      the target process is a Caliper benchmark or main method.");
+            System.out.println();
+            System.out.println("GENERAL OPTIONS");
+            System.out.println();
+            System.out.println("  --mode <device|host|activity>: specify which environment to run the");
+            System.out.println("      actions in. Options are on the device VM, on the host VM, and on");
+            System.out.println("      device within an android.app.Activity.");
+            System.out.println("      Default is: " + mode);
+            System.out.println();
+            System.out.println("  --clean: synonym for --clean-before and --clean-after (default).");
+            System.out.println("      Disable with --no-clean if you want no files removed.");
+            System.out.println();
+            System.out.println("  --stream: stream output as it is emitted.");
+            System.out.println();
+            System.out.println("  --timeout <seconds>: maximum execution time of each action before the");
+            System.out.println("      runner aborts it. Specifying zero seconds or using --debug will");
+            System.out.println("      disable the execution timeout.");
+            System.out.println("      Default is: " + timeoutSeconds);
+            System.out.println();
+            System.out.println("  --xml-reports-directory <path>: directory to emit JUnit-style");
+            System.out.println("      XML test results.");
+            System.out.println();
+            System.out.println("  --sdk <android jar>: the API jar file to compile against.");
+            System.out.println("      Usually this is <SDK>/platforms/android-<X.X>/android.jar");
+            System.out.println("      where <SDK> is the path to an Android SDK path and <X.X> is");
+            System.out.println("      a release version like 1.5.");
+            System.out.println();
+            System.out.println("      To test against APIs added since the latest SDK, use");
+            System.out.println("      out/target/common/obj/JAVA_LIBRARIES/core_intermediates/classes.jar");
+            System.out.println();
+            System.out.println("      Default is: " + sdkJar);
+            System.out.println();
+            System.out.println("  --verbose: turn on verbose output");
+            System.out.println();
+            System.out.println("TARGET OPTIONS");
+            System.out.println();
+            System.out.println("  --debug <port>: enable Java debugging on the specified port.");
+            System.out.println("      This port must be free both on the device and on the local");
+            System.out.println("      system. Disables the timeout specified by --timeout-seconds.");
+            System.out.println();
+            System.out.println("  --device-runner-dir <directory>: use the specified directory for");
+            System.out.println("      on-device temporary files and code.");
+            System.out.println("      Default is: " + deviceRunnerDir);
+            System.out.println();
+            System.out.println("  --vm-arg <argument>: include the specified argument when spawning a");
+            System.out.println("      virtual machine. Examples: -Xint:fast, -ea, -Xmx16M");
+            System.out.println();
+            System.out.println("  --java-home <java_home>: execute the actions on the local workstation");
+            System.out.println("      using the specified java home directory. This does not impact");
+            System.out.println("      which javac gets used. When unset, java is used from the PATH.");
+            System.out.println();
+            System.out.println("EXOTIC OPTIONS");
+            System.out.println();
+            System.out.println("  --clean-before: remove working directories before building and");
+            System.out.println("      running (default). Disable with --no-clean-before if you are");
+            System.out.println("      using interactively with your own temporary input files.");
+            System.out.println();
+            System.out.println("  --clean-after: remove temporary files after running (default).");
+            System.out.println("      Disable with --no-clean-after and use with --verbose if");
+            System.out.println("      you'd like to manually re-run commands afterwards.");
+            System.out.println();
+            System.out.println("  --color: format output in technicolor.");
+            System.out.println();
+            System.out.println("  --expectations <file>: include the specified file when looking for");
+            System.out.println("      action expectations. The file should include qualified action names");
+            System.out.println("      and the corresponding expected output.");
+            System.out.println("      Default is: " + expectationFiles);
+            System.out.println();
+            System.out.println("  --ident: amount to indent action result output. Can be set to ''");
+            System.out.println("      (aka empty string) to simplify output parsing.");
+            System.out.println("      Default is: '" + indent + "'");
+            System.out.println();
+            System.out.println("  --javac-arg <argument>: include the specified argument when invoking");
+            System.out.println("      javac. Examples: --javac-arg -Xmaxerrs --javac-arg 1");
+            System.out.println();
+            System.out.println("  --monitor-timeout <seconds>: number of seconds to wait for the target");
+            System.out.println("      process to launch. This can be used to prevent connection failures");
+            System.out.println("      when dexopt is slow.");
+            System.out.println();
+        }
+
+        private boolean parseArgs(String[] args) {
+            List<String> actionsAndTargetArgs;
+            try {
+                actionsAndTargetArgs = new OptionParser(this).parse(args);
+            } catch (RuntimeException e) {
+                System.out.println(e.getMessage());
+                return false;
+            }
+
+            //
+            // Semantic error validation
+            //
+
+            boolean device;
+            boolean vm;
+            if (mode.equals(MODE_DEVICE)) {
+                device = true;
+                vm = true;
+            } else if (mode.equals(MODE_HOST)) {
+                device = false;
+                vm = true;
+            } else if (mode.equals(MODE_ACTIVITY)) {
+                device = true;
+                vm = false;
+            } else {
+                System.out.println("Unknown mode: " + mode);
+                return false;
+            }
+
+
+            if (device) { // check device option consistency
+                if (javaHome != null) {
+                    System.out.println("java home " + javaHome + " should not be specified for mode " + mode);
+                    return false;
+                }
+
+            } else { // check host (!device) option consistency
+                if (javaHome != null && !new File(javaHome, "/bin/java").exists()) {
+                    System.out.println("Invalid java home: " + javaHome);
+                    return false;
+                }
+            }
+
+            // check vm option consistency
+            if (!vm) {
+                if (!vmArgs.isEmpty()) {
+                    System.out.println("vm args " + vmArgs + " should not be specified for mode " + mode);
+                    return false;
+                }
+            }
+
+            if (!sdkJar.exists()) {
+                System.out.println("Could not find SDK jar: " + sdkJar);
+                return false;
+            }
+
+            if (xmlReportsDirectory != null && !xmlReportsDirectory.isDirectory()) {
+                System.out.println("Invalid XML reports directory: " + xmlReportsDirectory);
+                return false;
+            }
+
+            if (!clean) {
+                cleanBefore = false;
+                cleanAfter = false;
+            }
+
+            //
+            // Post-processing arguments
+            //
+
+            // disable timeout when debugging
+            if (debugPort != null) {
+                timeoutSeconds = 0;
+            }
+
+            // separate the actions and the target args
+            int index = 0;
+            for (; index < actionsAndTargetArgs.size(); index++) {
+                String arg = actionsAndTargetArgs.get(index);
+                if (arg.equals("--")) {
+                    index++;
+                    break;
+                }
+
+                File file = new File(arg);
+                if (file.exists()) {
+                    if (arg.endsWith(".jar")) {
+                        classpath.addAll(file);
+                    } else {
+                        actionFiles.add(file);
+                    }
+                } else if (CLASS_NAME_PATTERN.matcher(arg).matches()) {
+                    actionClasses.add(arg);
+                } else {
+                    break;
+                }
+            }
+
+            targetArgs.addAll(actionsAndTargetArgs.subList(index, actionsAndTargetArgs.size()));
+
+            if (actionFiles.isEmpty() && actionClasses.isEmpty()) {
+                System.out.println("No actions provided.");
+                return false;
+            }
+
+            if (!targetArgs.isEmpty() && mode.equals(Options.MODE_ACTIVITY)) {
+                System.out.println("Target args not supported with --mode activity");
+                return false;
+            }
+
+            return true;
+        }
+    }
+
+    private final Options options = new Options();
+    private final File localTemp = new File("/tmp/dalvikrunner/" + UUID.randomUUID());
+
+    private Vogar() {}
+
+    private void run() {
+        Console console = new Console(options.stream, options.indent, options.color);
+        console.configureJavaLogging(options.verbose);
+
+        int monitorPort;
+        Mode mode;
+        if (options.mode.equals(Options.MODE_DEVICE)) {
+            monitorPort = 8787;
+            mode = new DeviceDalvikVm(
+                    options.debugPort,
+                    options.sdkJar,
+                    options.javacArgs,
+                    monitorPort,
+                    localTemp,
+                    options.vmArgs,
+                    options.targetArgs,
+                    options.cleanBefore,
+                    options.cleanAfter,
+                    options.deviceRunnerDir,
+                    options.classpath);
+        } else if (options.mode.equals(Options.MODE_HOST)) {
+            monitorPort = 8788;
+            mode = new JavaVm(
+                    options.debugPort,
+                    options.sdkJar,
+                    options.javacArgs,
+                    monitorPort,
+                    localTemp,
+                    options.javaHome,
+                    options.vmArgs,
+                    options.targetArgs,
+                    options.cleanBefore,
+                    options.cleanAfter,
+                    options.classpath);
+        } else if (options.mode.equals(Options.MODE_ACTIVITY)) {
+            monitorPort = 8787;
+            mode = new ActivityMode(
+                    options.debugPort,
+                    options.sdkJar,
+                    options.javacArgs,
+                    monitorPort,
+                    localTemp,
+                    options.cleanBefore,
+                    options.cleanAfter,
+                    options.deviceRunnerDir,
+                    options.classpath);
+        } else {
+            System.out.println("Unknown mode mode " + options.mode + ".");
+            return;
+        }
+
+        HostMonitor monitor = new HostMonitor(options.monitorTimeout);
+
+        List<RunnerSpec> runnerSpecs = Arrays.asList(
+                new JtregSpec(localTemp),
+                new JUnitSpec(),
+                new CaliperSpec(),
+                new MainSpec());
+
+        ExpectationStore expectationStore;
+        try {
+            expectationStore = ExpectationStore.parse(options.expectationFiles);
+        } catch (IOException e) {
+            System.out.println("Problem loading expectations: " + e);
+            return;
+        }
+
+        XmlReportPrinter xmlReportPrinter = options.xmlReportsDirectory != null
+                ? new XmlReportPrinter(options.xmlReportsDirectory, expectationStore)
+                : null;
+
+        Driver driver = new Driver(
+                localTemp,
+                mode,
+                expectationStore,
+                runnerSpecs,
+                xmlReportPrinter,
+                console,
+                monitor,
+                monitorPort,
+                options.timeoutSeconds);
+
+        driver.buildAndRun(options.actionFiles, options.actionClasses);
+    }
+
+    public static void main(String[] args) {
+        Vogar vogar = new Vogar();
+        if (!vogar.options.parseArgs(args)) {
+            vogar.options.printUsage();
+            return;
+        }
+        vogar.run();
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/XmlReportPrinter.java b/tools/runner/java/vogar/XmlReportPrinter.java
similarity index 78%
rename from tools/runner/java/dalvik/runner/XmlReportPrinter.java
rename to tools/runner/java/vogar/XmlReportPrinter.java
index 669a26c..59db75d 100644
--- a/tools/runner/java/dalvik/runner/XmlReportPrinter.java
+++ b/tools/runner/java/vogar/XmlReportPrinter.java
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
-
-import org.kxml2.io.KXmlSerializer;
+package vogar;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -29,6 +27,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
+import org.kxml2.io.KXmlSerializer;
 
 
 /**
@@ -52,7 +51,6 @@
     private static final String ATTR_FAILURES = "failures";
     private static final String ATTR_TESTS = "tests";
     private static final String ATTR_TYPE = "type";
-    private static final String ATTR_MESSAGE = "message";
     private static final String PROPERTIES = "properties";
     private static final String ATTR_CLASSNAME = "classname";
     private static final String TIMESTAMP = "timestamp";
@@ -61,10 +59,18 @@
     /** the XML namespace */
     private static final String ns = null;
 
+    private final File directory;
+    private final ExpectationStore expectationStore;
+
+    public XmlReportPrinter(File directory, ExpectationStore expectationStore) {
+        this.directory = directory;
+        this.expectationStore = expectationStore;
+    }
+
     /**
      * Populates the directory with the report data from the completed tests.
      */
-    public int generateReports(File directory, Collection<TestRun> results) {
+    public int generateReports(Collection<Outcome> results) {
         Map<String, Suite> suites = testsToSuites(results);
 
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
@@ -100,24 +106,25 @@
         return suites.size();
     }
 
-    private Map<String, Suite> testsToSuites(Collection<TestRun> testRuns) {
+    private Map<String, Suite> testsToSuites(Collection<Outcome> outcomes) {
         Map<String, Suite> result = new LinkedHashMap<String, Suite>();
-        for (TestRun testRun : testRuns) {
-            if (testRun.getResult() == Result.UNSUPPORTED) {
+        for (Outcome outcome : outcomes) {
+            if (outcome.getResult() == Result.UNSUPPORTED) {
                 continue;
             }
 
-            String suiteName = testRun.getSuiteName();
+            String suiteName = outcome.getSuiteName();
             Suite suite = result.get(suiteName);
             if (suite == null) {
                 suite = new Suite(suiteName);
                 result.put(suiteName, suite);
             }
 
-            suite.tests.add(testRun);
+            suite.outcomes.add(outcome);
 
-            if (!testRun.isExpectedResult()) {
-                if (testRun.getResult() == Result.EXEC_FAILED) {
+            Expectation expectation = expectationStore.get(outcome);
+            if (!expectation.matches(outcome)) {
+                if (outcome.getResult() == Result.EXEC_FAILED) {
                     suite.failuresCount++;
                 } else {
                     suite.errorsCount++;
@@ -127,9 +134,9 @@
         return result;
     }
 
-    static class Suite {
+    class Suite {
         private final String name;
-        private final List<TestRun> tests = new ArrayList<TestRun>();
+        private final List<Outcome> outcomes = new ArrayList<Outcome>();
         private int failuresCount;
         private int errorsCount;
 
@@ -140,7 +147,7 @@
         void print(KXmlSerializer serializer, String timestamp) throws IOException {
             serializer.startTag(ns, TESTSUITE);
             serializer.attribute(ns, ATTR_NAME, name);
-            serializer.attribute(ns, ATTR_TESTS, Integer.toString(tests.size()));
+            serializer.attribute(ns, ATTR_TESTS, Integer.toString(outcomes.size()));
             serializer.attribute(ns, ATTR_FAILURES, Integer.toString(failuresCount));
             serializer.attribute(ns, ATTR_ERRORS, Integer.toString(errorsCount));
             serializer.attribute(ns, ATTR_TIME, "0");
@@ -149,28 +156,25 @@
             serializer.startTag(ns, PROPERTIES);
             serializer.endTag(ns, PROPERTIES);
 
-            for (TestRun testRun : tests) {
-                print(serializer, testRun);
+            for (Outcome outcome : outcomes) {
+                print(serializer, outcome);
             }
 
             serializer.endTag(ns, TESTSUITE);
         }
 
-        void print(KXmlSerializer serializer, TestRun testRun) throws IOException {
+        void print(KXmlSerializer serializer, Outcome outcome) throws IOException {
             serializer.startTag(ns, TESTCASE);
-            serializer.attribute(ns, ATTR_NAME, testRun.getTestName());
-            serializer.attribute(ns, ATTR_CLASSNAME, testRun.getSuiteName());
+            serializer.attribute(ns, ATTR_NAME, outcome.getTestName());
+            serializer.attribute(ns, ATTR_CLASSNAME, outcome.getSuiteName());
             serializer.attribute(ns, ATTR_TIME, "0");
 
-            if (!testRun.isExpectedResult()) {
-                String result = testRun.getResult() == Result.EXEC_FAILED ? FAILURE : ERROR;
+            Expectation expectation = expectationStore.get(outcome);
+            if (!expectation.matches(outcome)) {
+                String result = outcome.getResult() == Result.EXEC_FAILED ? FAILURE : ERROR;
                 serializer.startTag(ns, result);
-                String title = testRun.getDescription();
-                if (title != null && title.length() > 0) {
-                    serializer.attribute(ns, ATTR_MESSAGE, title);
-                }
-                serializer.attribute(ns, ATTR_TYPE, testRun.getResult().toString());
-                String text = sanitize(Strings.join(testRun.getOutputLines(), "\n"));
+                serializer.attribute(ns, ATTR_TYPE, outcome.getResult().toString());
+                String text = sanitize(Strings.join(outcome.getOutputLines(), "\n"));
                 serializer.text(text);
                 serializer.endTag(ns, result);
             }
@@ -185,4 +189,4 @@
             return text.replace("\0", "<\\0>");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tools/runner/java/dalvik/runner/Aapt.java b/tools/runner/java/vogar/commands/Aapt.java
similarity index 96%
rename from tools/runner/java/dalvik/runner/Aapt.java
rename to tools/runner/java/vogar/commands/Aapt.java
index 4d1a873..3778586 100644
--- a/tools/runner/java/dalvik/runner/Aapt.java
+++ b/tools/runner/java/vogar/commands/Aapt.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.io.File;
 
 /**
  * An aapt (Android Asset Packaging Tool) command.
  */
-final class Aapt {
+public final class Aapt {
 
     public void apk(File apk, File manifest) {
 
diff --git a/tools/runner/java/dalvik/runner/Adb.java b/tools/runner/java/vogar/commands/Adb.java
similarity index 98%
rename from tools/runner/java/dalvik/runner/Adb.java
rename to tools/runner/java/vogar/commands/Adb.java
index c982058..fd746fa 100644
--- a/tools/runner/java/dalvik/runner/Adb.java
+++ b/tools/runner/java/vogar/commands/Adb.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.io.File;
 import java.util.List;
@@ -23,7 +23,7 @@
 /**
  * An adb command.
  */
-final class Adb {
+public final class Adb {
 
     public void mkdir(File name) {
         new Command("adb", "shell", "mkdir", name.getPath()).execute();
diff --git a/tools/runner/java/dalvik/runner/Command.java b/tools/runner/java/vogar/commands/Command.java
similarity index 77%
rename from tools/runner/java/dalvik/runner/Command.java
rename to tools/runner/java/vogar/commands/Command.java
index 88ba38e..b861503 100644
--- a/tools/runner/java/dalvik/runner/Command.java
+++ b/tools/runner/java/vogar/commands/Command.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -34,11 +34,13 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.logging.Logger;
+import vogar.Strings;
+import vogar.Threads;
 
 /**
  * An out of process executable.
  */
-final class Command {
+public final class Command {
 
     private final Logger logger = Logger.getLogger(Command.class.getName());
 
@@ -46,13 +48,13 @@
     private final File workingDirectory;
     private final boolean permitNonZeroExitStatus;
     private final PrintStream tee;
-    private Process process;
+    private volatile Process process;
 
-    Command(String... args) {
+    public Command(String... args) {
         this(Arrays.asList(args));
     }
 
-    Command(List<String> args) {
+    public Command(List<String> args) {
         this.args = new ArrayList<String>(args);
         this.workingDirectory = null;
         this.permitNonZeroExitStatus = false;
@@ -70,7 +72,7 @@
         return Collections.unmodifiableList(args);
     }
 
-    public synchronized void start() throws IOException {
+    public void start() throws IOException {
         if (isStarted()) {
             throw new IllegalStateException("Already started!");
         }
@@ -91,15 +93,7 @@
         return process != null;
     }
 
-    public Process getProcess() {
-        if (!isStarted()) {
-            throw new IllegalStateException("Not started!");
-        }
-
-        return process;
-    }
-
-    public synchronized List<String> gatherOutput()
+    public List<String> gatherOutput()
             throws IOException, InterruptedException {
         if (!isStarted()) {
             throw new IllegalStateException("Not started!");
@@ -127,7 +121,7 @@
         return outputLines;
     }
 
-    public synchronized List<String> execute() {
+    public List<String> execute() {
         try {
             start();
             return gatherOutput();
@@ -139,38 +133,58 @@
     }
 
     /**
-     * Executes a command with a specified timeout. Output is returned
-     * if the command succeeds. If Otherwise null is returned if the
-     * command timed out.
+     * Executes a command with a specified timeout. If the process does not
+     * complete normally before the timeout has elapsed, it will be destroyed.
+     *
+     * @param timeoutSeconds how long to wait, or 0 to wait indefinitely
+     * @return the command's output, or null if the command timed out
      */
     public List<String> executeWithTimeout(long timeoutSeconds)
             throws TimeoutException {
-        ExecutorService outputReader
-            = Executors.newFixedThreadPool(1, Threads.daemonThreadFactory());
+        if (timeoutSeconds == 0) {
+            return execute();
+        }
+
         try {
-            start();
-            // run on a different thread to allow a timeout
-            Future<List<String>> future = outputReader.submit(new Callable<List<String>>() {
-                    public List<String> call() throws Exception {
-                        return gatherOutput();
-                    }
-                });
-            return future.get(timeoutSeconds, TimeUnit.SECONDS);
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to execute process: " + args, e);
+            return executeLater().get(timeoutSeconds, TimeUnit.SECONDS);
         } catch (InterruptedException e) {
             throw new RuntimeException("Interrupted while executing process: " + args, e);
         } catch (ExecutionException e) {
             throw new RuntimeException(e);
         } finally {
-            if (isStarted()) {
-                getProcess().destroy(); // to release the output reader
-            }
-            outputReader.shutdown();
+            destroy();
         }
     }
 
-    static class Builder {
+    /**
+     * Executes the command on a new background thread. This method returns
+     * immediately.
+     *
+     * @return a future to retrieve the command's output.
+     */
+    public Future<List<String>> executeLater() {
+        ExecutorService executor = Executors.newFixedThreadPool(
+                1, Threads.daemonThreadFactory());
+        Future<List<String>> result = executor.submit(new Callable<List<String>>() {
+            public List<String> call() throws Exception {
+                start();
+                return gatherOutput();
+            }
+        });
+        executor.shutdown();
+        return result;
+    }
+
+    /**
+     * Destroys the underlying process and closes its associated streams.
+     */
+    public void destroy() {
+        if (process != null) {
+            process.destroy();
+        }
+    }
+
+    public static class Builder {
         private final List<String> args = new ArrayList<String>();
         private File workingDirectory;
         private boolean permitNonZeroExitStatus = false;
diff --git a/tools/runner/java/dalvik/runner/CommandFailedException.java b/tools/runner/java/vogar/commands/CommandFailedException.java
similarity index 94%
rename from tools/runner/java/dalvik/runner/CommandFailedException.java
rename to tools/runner/java/vogar/commands/CommandFailedException.java
index d16a279..8d1fa33 100644
--- a/tools/runner/java/dalvik/runner/CommandFailedException.java
+++ b/tools/runner/java/vogar/commands/CommandFailedException.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.util.List;
 
 /**
  * Thrown when an out of process executable does not return normally.
  */
-class CommandFailedException extends RuntimeException {
+public class CommandFailedException extends RuntimeException {
 
     private final List<String> args;
     private final List<String> outputLines;
diff --git a/tools/runner/java/dalvik/runner/Dx.java b/tools/runner/java/vogar/commands/Dx.java
similarity index 92%
rename from tools/runner/java/dalvik/runner/Dx.java
rename to tools/runner/java/vogar/commands/Dx.java
index 393b70d..d2e3d00 100644
--- a/tools/runner/java/dalvik/runner/Dx.java
+++ b/tools/runner/java/vogar/commands/Dx.java
@@ -14,15 +14,18 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.io.File;
 import java.util.logging.Logger;
+import vogar.Classpath;
+import vogar.Md5Cache;
+import vogar.Strings;
 
 /**
  * A dx command.
  */
-final class Dx {
+public final class Dx {
     private static final Logger logger = Logger.getLogger(Dx.class.getName());
     private static final Md5Cache DEX_CACHE = new Md5Cache("dex");
 
@@ -30,6 +33,7 @@
      * Converts all the .class files on 'classpath' into a dex file written to 'output'.
      */
     public void dex(File output, Classpath classpath) {
+        output.getParentFile().mkdirs();
         File key = DEX_CACHE.makeKey(classpath);
         if (key != null && key.exists()) {
             logger.fine("dex cache hit for " + classpath);
diff --git a/tools/runner/java/dalvik/runner/Mkdir.java b/tools/runner/java/vogar/commands/Mkdir.java
similarity index 93%
rename from tools/runner/java/dalvik/runner/Mkdir.java
rename to tools/runner/java/vogar/commands/Mkdir.java
index 46dcf08..fc08f1b 100644
--- a/tools/runner/java/dalvik/runner/Mkdir.java
+++ b/tools/runner/java/vogar/commands/Mkdir.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.io.File;
 
 /**
  * A mkdir command.
  */
-final class Mkdir {
+public final class Mkdir {
 
     public void mkdirs(File directory) {
         new Command("mkdir", "-p", directory.getPath()).execute();
diff --git a/tools/runner/java/dalvik/runner/Rm.java b/tools/runner/java/vogar/commands/Rm.java
similarity index 95%
rename from tools/runner/java/dalvik/runner/Rm.java
rename to tools/runner/java/vogar/commands/Rm.java
index 1fc11d9..425bb5d 100644
--- a/tools/runner/java/dalvik/runner/Rm.java
+++ b/tools/runner/java/vogar/commands/Rm.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.commands;
 
 import java.io.File;
 
 /**
  * A rm command.
  */
-final class Rm {
+public final class Rm {
 
     public void file(File file) {
         new Command.Builder()
diff --git a/tools/runner/java/dalvik/runner/CaliperRunner.java b/tools/runner/java/vogar/target/CaliperRunner.java
similarity index 62%
rename from tools/runner/java/dalvik/runner/CaliperRunner.java
rename to tools/runner/java/vogar/target/CaliperRunner.java
index b30644b..3336716 100644
--- a/tools/runner/java/dalvik/runner/CaliperRunner.java
+++ b/tools/runner/java/vogar/target/CaliperRunner.java
@@ -14,24 +14,31 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.target;
 
 import com.google.caliper.Benchmark;
 import com.google.caliper.Runner;
+import vogar.Result;
 
 /**
  * Runs a <a href="http://code.google.com/p/caliper/">Caliper</a> benchmark.
  */
-public final class CaliperRunner implements dalvik.runner.Runner {
+public final class CaliperRunner implements vogar.target.Runner {
 
-    public void prepareTest(Class<?> testClass) {}
+    private TargetMonitor monitor;
 
-    public boolean test(Class<?> testClass) {
+    public void init(TargetMonitor monitor, String actionName,
+            Class<?> testClass) {
+        this.monitor = monitor;
+    }
+
+    public void run(String actionName, Class<?> testClass, String[] args) {
+        monitor.outcomeStarted(actionName, actionName);
         try {
-            Runner.main(testClass.asSubclass(Benchmark.class), new String[0]);
+            Runner.main(testClass.asSubclass(Benchmark.class), args);
         } catch (Exception ex) {
             ex.printStackTrace();
         }
-        return false; // always print benchmarking results
+        monitor.outcomeFinished(Result.SUCCESS);
     }
 }
diff --git a/tools/runner/java/vogar/target/JUnitRunner.java b/tools/runner/java/vogar/target/JUnitRunner.java
new file mode 100644
index 0000000..f15cad3
--- /dev/null
+++ b/tools/runner/java/vogar/target/JUnitRunner.java
@@ -0,0 +1,130 @@
+/*
+ * 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 vogar.target;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestResult;
+import junit.runner.BaseTestRunner;
+import junit.runner.TestSuiteLoader;
+import junit.textui.ResultPrinter;
+import vogar.Result;
+
+/**
+ * Adapts a JUnit test for use by vogar.
+ */
+public final class JUnitRunner implements Runner {
+
+    private static final Pattern NAME_THEN_TEST_CLASS = Pattern.compile("(.*)\\(([\\w\\.$]+)\\)");
+
+    private junit.textui.TestRunner testRunner;
+    private Test junitTest;
+
+    public void init(TargetMonitor monitor, String actionName, Class<?> testClass) {
+        final TestSuiteLoader testSuiteLoader = new TestSuiteLoader() {
+            public Class load(String suiteClassName) throws ClassNotFoundException {
+                return JUnitRunner.class.getClassLoader().loadClass(suiteClassName);
+            }
+
+            public Class reload(Class c) {
+                return c;
+            }
+        };
+
+        testRunner = new junit.textui.TestRunner(
+                new MonitoringResultPrinter(monitor, actionName)) {
+            @Override public TestSuiteLoader getLoader() {
+                return testSuiteLoader;
+            }
+        };
+
+        this.junitTest = testRunner.getTest(testClass.getName());
+    }
+
+    public void run(String actionName, Class<?> testClass, String[] args) {
+        testRunner.doRun(junitTest);
+    }
+
+    /**
+     * Returns the vogar name like {@code tests.xml.DomTest#testFoo} for a test
+     * with a JUnit name like {@code testFoo(tests.xml.DomTest)}.
+     */
+    private String getOutcomeName(Test test) {
+        String testToString = test.toString();
+
+        Matcher matcher = NAME_THEN_TEST_CLASS.matcher(testToString);
+        if (matcher.matches()) {
+            return matcher.group(2) + "#" + matcher.group(1);
+        }
+
+        return testToString;
+    }
+
+    /**
+     * This result printer posts test names, output and exceptions to the
+     * hosting process.
+     */
+    private class MonitoringResultPrinter extends ResultPrinter {
+        private final TargetMonitor monitor;
+        private final String actionName;
+
+        private Test current;
+        private Throwable failure;
+
+        public MonitoringResultPrinter(TargetMonitor monitor,
+                String actionName) {
+            super(System.out);
+            this.monitor = monitor;
+            this.actionName = actionName;
+        }
+
+        @Override public void addError(Test test, Throwable t) {
+            System.out.println(BaseTestRunner.getFilteredTrace(t));
+            failure = t;
+        }
+
+        @Override public void addFailure(Test test, AssertionFailedError t) {
+            System.out.println(BaseTestRunner.getFilteredTrace(t));
+            failure = t;
+        }
+
+        @Override public void endTest(Test test) {
+            if (current == null) {
+                throw new IllegalStateException();
+            }
+            monitor.outcomeFinished(
+                    failure == null ? Result.SUCCESS : Result.EXEC_FAILED);
+            current = null;
+            failure = null;
+        }
+
+        @Override public void startTest(Test test) {
+            if (current != null) {
+                throw new IllegalStateException();
+            }
+            current = test;
+            monitor.outcomeStarted(getOutcomeName(test), actionName);
+        }
+
+        @Override protected void printHeader(long runTime) {}
+        @Override protected void printErrors(TestResult result) {}
+        @Override protected void printFailures(TestResult result) {}
+        @Override protected void printFooter(TestResult result) {}
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/JtregRunner.java b/tools/runner/java/vogar/target/JtregRunner.java
similarity index 67%
rename from tools/runner/java/dalvik/runner/JtregRunner.java
rename to tools/runner/java/vogar/target/JtregRunner.java
index 633a529..47090c5 100644
--- a/tools/runner/java/dalvik/runner/JtregRunner.java
+++ b/tools/runner/java/vogar/target/JtregRunner.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.target;
 
 import java.lang.reflect.Method;
+import vogar.Result;
 
 /**
  * Runs a jtreg test.
@@ -24,8 +25,11 @@
 public final class JtregRunner implements Runner {
 
     private Method main;
+    private TargetMonitor monitor;
 
-    public void prepareTest(Class<?> testClass) {
+    public void init(TargetMonitor monitor, String actionName,
+            Class<?> testClass) {
+        this.monitor = monitor;
         try {
             main = testClass.getMethod("main", String[].class);
         } catch (Exception e) {
@@ -33,13 +37,14 @@
         }
     }
 
-    public boolean test(Class<?> testClass) {
+    public void run(String actionName, Class<?> testClass, String[] args) {
+        monitor.outcomeStarted(actionName, actionName);
         try {
-            main.invoke(null, new Object[] { new String[0] });
-            return true;
+            main.invoke(null, new Object[] { args });
+            monitor.outcomeFinished(Result.SUCCESS);
         } catch (Throwable failure) {
             failure.printStackTrace();
-            return false;
+            monitor.outcomeFinished(Result.EXEC_FAILED);
         }
     }
 }
diff --git a/tools/runner/java/dalvik/runner/MainRunner.java b/tools/runner/java/vogar/target/MainRunner.java
similarity index 70%
rename from tools/runner/java/dalvik/runner/MainRunner.java
rename to tools/runner/java/vogar/target/MainRunner.java
index 34a4a47..d4e5dec 100644
--- a/tools/runner/java/dalvik/runner/MainRunner.java
+++ b/tools/runner/java/vogar/target/MainRunner.java
@@ -14,18 +14,22 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.target;
 
 import java.lang.reflect.Method;
+import vogar.Result;
 
 /**
  * Runs a Java class with a main method.
  */
 public final class MainRunner implements Runner {
 
+    private TargetMonitor monitor;
     private Method main;
 
-    public void prepareTest(Class<?> testClass) {
+    public void init(TargetMonitor monitor, String actionName,
+            Class<?> testClass) {
+        this.monitor = monitor;
         try {
             main = testClass.getMethod("main", String[].class);
         } catch (Exception e) {
@@ -33,12 +37,13 @@
         }
     }
 
-    public boolean test(Class<?> testClass) {
+    public void run(String actionName, Class<?> testClass, String[] args) {
+        monitor.outcomeStarted(actionName, actionName);
         try {
-            main.invoke(null, new Object[] { new String[0] });
+            main.invoke(null, new Object[] { args });
         } catch (Throwable ex) {
             ex.printStackTrace();
         }
-        return false; // always print main method output
+        monitor.outcomeFinished(Result.SUCCESS);
     }
 }
diff --git a/tools/runner/java/dalvik/runner/Runner.java b/tools/runner/java/vogar/target/Runner.java
similarity index 80%
rename from tools/runner/java/dalvik/runner/Runner.java
rename to tools/runner/java/vogar/target/Runner.java
index 7d7b0ee..a06ba1a 100644
--- a/tools/runner/java/dalvik/runner/Runner.java
+++ b/tools/runner/java/vogar/target/Runner.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.target;
 
 /**
  * Interface between the generic TestRunner and the more specific
@@ -22,7 +22,8 @@
  */
 public interface Runner {
 
-    public void prepareTest(Class<?> testClass);
+    public void init(TargetMonitor monitor, String actionName,
+            Class<?> testClass);
 
-    public boolean test(Class<?> testClass);
+    public void run(String actionName, Class<?> testClass, String[] args);
 }
diff --git a/tools/runner/java/vogar/target/TargetMonitor.java b/tools/runner/java/vogar/target/TargetMonitor.java
new file mode 100644
index 0000000..1122caf
--- /dev/null
+++ b/tools/runner/java/vogar/target/TargetMonitor.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package vogar.target;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+import org.xmlpull.v1.XmlSerializer;
+import vogar.Result;
+
+/**
+ * Accepts a connection for a host process to monitor this action.
+ */
+class TargetMonitor {
+
+    private static final int ACCEPT_TIMEOUT_MILLIS = 10 * 1000;
+
+    private static final String ns = null; // no namespaces
+    ServerSocket serverSocket;
+    private Socket socket;
+    private XmlSerializer serializer;
+
+    public void await(int port) {
+        if (socket != null) {
+            throw new IllegalStateException();
+        }
+
+        try {
+            serverSocket = new ServerSocket(port);
+            serverSocket.setSoTimeout(ACCEPT_TIMEOUT_MILLIS);
+            serverSocket.setReuseAddress(true);
+            socket = serverSocket.accept();
+
+            serializer = XmlPullParserFactory.newInstance().newSerializer();
+            serializer.setOutput(socket.getOutputStream(), "UTF-8");
+            serializer.startDocument("UTF-8", null);
+            serializer.startTag(ns, "vogar-monitor");
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to accept a monitor on localhost:" + port, e);
+        } catch (XmlPullParserException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void outcomeStarted(String outcomeName, String actionName) {
+        try {
+            serializer.startTag(ns, "outcome");
+            serializer.attribute(ns, "name", outcomeName);
+            serializer.attribute(ns, "action", actionName);
+            serializer.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void output(String text) {
+        try {
+            serializer.text(text);
+            serializer.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void outcomeFinished(Result result) {
+        try {
+            serializer.startTag(ns, "result");
+            serializer.attribute(ns, "value", result.name());
+            serializer.endTag(ns, "result");
+            serializer.endTag(ns, "outcome");
+            serializer.flush();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void close() {
+        try {
+            serializer.endTag(ns, "vogar-monitor");
+            serializer.endDocument();
+            socket.close();
+            serverSocket.close();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        socket = null;
+        serverSocket = null;
+        serializer = null;
+    }
+}
diff --git a/tools/runner/java/dalvik/runner/TestRunner.java b/tools/runner/java/vogar/target/TestRunner.java
similarity index 75%
rename from tools/runner/java/dalvik/runner/TestRunner.java
rename to tools/runner/java/vogar/target/TestRunner.java
index a706d40..9419e6f 100644
--- a/tools/runner/java/dalvik/runner/TestRunner.java
+++ b/tools/runner/java/vogar/target/TestRunner.java
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.target;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.PrintStream;
 import java.util.Properties;
+import vogar.TestProperties;
 
 /**
- * Runs a test.
+ * Runs an action, in process on the target.
  */
 public class TestRunner {
 
@@ -30,12 +32,14 @@
     protected final String qualifiedName;
     protected final Class<?> testClass;
     protected final Class<?> runnerClass;
+    protected final int monitorPort;
 
-    protected TestRunner () {
+    protected TestRunner() {
         properties = loadProperties();
         qualifiedName = properties.getProperty(TestProperties.QUALIFIED_NAME);
         testClass = classProperty(TestProperties.TEST_CLASS, Object.class);
         runnerClass = classProperty(TestProperties.RUNNER_CLASS, Runner.class);
+        monitorPort = Integer.parseInt(properties.getProperty(TestProperties.MONITOR_PORT));
     }
 
     protected static Properties loadProperties() {
@@ -71,7 +75,19 @@
         }
     }
 
-    public boolean run() {
+    public void run(String... args) {
+        final TargetMonitor monitor = new TargetMonitor();
+        monitor.await(monitorPort);
+
+        PrintStream monitorPrintStream = new PrintStream(System.out) {
+            @Override public void print(String str) {
+                super.print(str);
+                monitor.output(str);
+            }
+        };
+        System.setOut(monitorPrintStream);
+        System.setErr(monitorPrintStream);
+
         Runner runner;
         try {
             runner = (Runner) runnerClass.newInstance();
@@ -80,11 +96,15 @@
         } catch (IllegalAccessException e) {
             throw new RuntimeException(e);
         }
-        runner.prepareTest(testClass);
-        return runner.test(testClass);
+        runner.init(monitor, qualifiedName, testClass);
+        runner.run(qualifiedName, testClass, args);
+
+        monitor.close();
     }
 
+
+
     public static void main(String[] args) {
-        System.out.println(TestProperties.result(new TestRunner().run()));
+        new TestRunner().run(args);
     }
 }
diff --git a/tools/runner/lib/TestActivity.java b/tools/runner/lib/TestActivity.java
index 15206f8..6e6d09f 100644
--- a/tools/runner/lib/TestActivity.java
+++ b/tools/runner/lib/TestActivity.java
@@ -14,17 +14,16 @@
  * limitations under the License.
  */
 
-package dalvik.runner;
+package vogar.target;
 
 import android.app.Activity;
 import android.os.Bundle;
 import android.util.Log;
 import android.widget.TextView;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
+import vogar.Threads;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * Runs a user-supplied {@code main(String[] args)} method
@@ -44,62 +43,19 @@
         this.view = new TextView(this);
         log("TestActivity starting...");
         setContentView(view);
-        ActivityRunner activityRunner = new ActivityRunner();
-        activityRunner.run();
+
+        ExecutorService executor = Executors.newFixedThreadPool(
+                1, Threads.daemonThreadFactory());
+        executor.submit(new Runnable() {
+            public void run() {
+                new TestRunner().run();
+            }
+        });
+        executor.shutdown();
     }
 
-    private void log(String message, Throwable ex) {
-        log(message + "\n" + Log.getStackTraceString(ex));
-    }
     private void log(String message) {
         Log.i(TAG, message);
         view.append(message + "\n");
     }
-
-    class ActivityRunner extends TestRunner {
-
-        private final File runnerDir;
-        private final Thread shutdownHook = new Thread(new ShutdownHook());
-
-        ActivityRunner() {
-            runnerDir = new File(properties.getProperty(TestProperties.DEVICE_RUNNER_DIR));
-        }
-
-        @Override public boolean run() {
-            log("Using " + runnerClass + " to run " + qualifiedName);
-            Runtime.getRuntime().addShutdownHook(shutdownHook);
-            boolean success = super.run();
-            Runtime.getRuntime().removeShutdownHook(shutdownHook);
-            writeResultFile(success);
-            return success;
-        }
-
-        private void writeResultFile (boolean success) {
-            String result = TestProperties.result(success);
-            File resultDir = new File(runnerDir, qualifiedName);
-            File resultTemp = new File(resultDir, TestProperties.RESULT_FILE + ".temp");
-            File resultFile = new File(resultDir, TestProperties.RESULT_FILE);
-            log("TestActivity " + result + " " + resultFile);
-            try {
-                FileOutputStream resultOut = new FileOutputStream(resultTemp);
-                resultOut.write(result.getBytes("UTF-8"));
-                resultOut.close();
-                // atomically rename since DalvikRunner will be polling for this
-                resultTemp.renameTo(resultFile);
-            } catch (IOException e) {
-                log("TestActivity could not create result file", e);
-            }
-        }
-
-        /**
-         * Used to trap tests that try to exit on the their own. We
-         * treat this as a failure since they usually are calling
-         * System.exit with a non-zero value.
-         */
-        class ShutdownHook implements Runnable {
-            public void run() {
-                writeResultFile(false);
-            }
-        }
-    }
 }
diff --git a/tools/runner/lib/caliper.jar b/tools/runner/lib/caliper.jar
index 63a156a..690630e 100644
--- a/tools/runner/lib/caliper.jar
+++ b/tools/runner/lib/caliper.jar
Binary files differ
diff --git a/tools/runner/test-dalvik-runner.sh b/tools/runner/test-dalvik-runner.sh
index 1b9c35d..287e8d9 100755
--- a/tools/runner/test-dalvik-runner.sh
+++ b/tools/runner/test-dalvik-runner.sh
@@ -42,7 +42,7 @@
 #clean=--no-clean-after
 extras="$verbose $clean"
 
-dalvik_runner="java -cp out/host/linux-x86/framework/dalvik_runner.jar dalvik.runner.DalvikRunner"
+dalvik_runner="java -cp out/host/linux-x86/framework/dalvik_runner.jar vogar.Vogar"
 
 for mode in $modes; do
     for test in $tests; do
diff --git a/tools/runner/vogar b/tools/runner/vogar
index e5a6ad0..470b029 100755
--- a/tools/runner/vogar
+++ b/tools/runner/vogar
@@ -17,5 +17,9 @@
 # m core-tests junit caliper snod && adb reboot bootloader && fastboot flashall && adb wait-for-device
 # mmm dalvik/libcore/tools/runner
 
-classpath=`dirname $0`/../../../../out/host/linux-x86/framework/dalvik_runner.jar
-exec java -cp $classpath dalvik.runner.DalvikRunner "$@"
+android_root=`dirname $0`/../../../..
+cd ${android_root}
+
+classpath=${android_root}/out/host/linux-x86/framework/dalvik_runner.jar
+exec java -cp $classpath vogar.Vogar "$@"
+
diff --git a/x-net/src/main/java/javax/net/package.html b/x-net/src/main/java/javax/net/package.html
index 27ba790..5674d06 100644
--- a/x-net/src/main/java/javax/net/package.html
+++ b/x-net/src/main/java/javax/net/package.html
@@ -3,14 +3,5 @@
     <p>
       This package provides factory classes to create sockets and server-sockets. This classes can be subclassed to create factories for other kinds of socket for example the SSL-capable sockets from the package javax.net.ssl.
     </p>
-    @since Android 1.0
-  </body>
-</html>
-<html>
-  <body>
-    <p>
-      This package provides factory classes to create sockets and server-sockets. This classes can be subclassed to create factories for other kinds of socket for example the SSL-capable sockets from the package javax.net.ssl.
-    </p>
-    @since Android 1.0
   </body>
 </html>
diff --git a/x-net/src/main/java/javax/net/ssl/DefaultSSLServerSocketFactory.java b/x-net/src/main/java/javax/net/ssl/DefaultSSLServerSocketFactory.java
index 6620841..3e58897 100644
--- a/x-net/src/main/java/javax/net/ssl/DefaultSSLServerSocketFactory.java
+++ b/x-net/src/main/java/javax/net/ssl/DefaultSSLServerSocketFactory.java
@@ -24,8 +24,6 @@
 
 /**
  * Default inoperative implementation of javax.net.ssl.SSLServerSocketFactory
- * 
- * @since Android 1.0
  */
 class DefaultSSLServerSocketFactory extends SSLServerSocketFactory {
 
diff --git a/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java b/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java
index d9db099..b75c218 100644
--- a/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/x-net/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -23,6 +23,7 @@
 import java.security.PrivilegedAction;
 import java.security.Security;
 // BEGIN android-added
+import java.util.logging.Level;
 import java.util.logging.Logger;
 // END android-added
 
@@ -48,7 +49,7 @@
     public static synchronized SocketFactory getDefault() {
         if (defaultSocketFactory != null) {
             // BEGIN android-added
-            log("SSLSocketFactory", "Using factory " + defaultSocketFactory);
+            // log("SSLSocketFactory", "Using factory " + defaultSocketFactory, null);
             // END android-added
             return defaultSocketFactory;
         }
@@ -65,6 +66,9 @@
                             final Class<?> sfc = Class.forName(defaultName, true, cl);
                             defaultSocketFactory = (SocketFactory) sfc.newInstance();
                         } catch (Exception e) {
+                            // BEGIN android-added
+                            log("SSLSocketFactory", "Problem creating " + defaultName, e);
+                            // END android-added
                         }
                     }
                     return null;
@@ -83,16 +87,16 @@
             // Use internal implementation
             defaultSocketFactory = new DefaultSSLSocketFactory("No SSLSocketFactory installed");
         }
-            // BEGIN android-added
-            log("SSLSocketFactory", "Using factory " + defaultSocketFactory);
-            // END android-added
+        // BEGIN android-added
+        // log("SSLSocketFactory", "Using factory " + defaultSocketFactory, null);
+        // END android-added
         return defaultSocketFactory;
     }
 
     // BEGIN android-added
     @SuppressWarnings("unchecked")
-    private static void log(String tag, String msg) {
-        Logger.getLogger(tag).info(msg);
+    private static void log(String tag, String msg, Throwable throwable) {
+        Logger.getLogger(tag).log(Level.INFO, msg, throwable);
     }
     // END android-added
 
diff --git a/x-net/src/main/java/javax/net/ssl/package.html b/x-net/src/main/java/javax/net/ssl/package.html
index 3e6448e..14753c8 100644
--- a/x-net/src/main/java/javax/net/ssl/package.html
+++ b/x-net/src/main/java/javax/net/ssl/package.html
@@ -5,7 +5,7 @@
 <html>
 <body>
 <p>
-This package provides all the classes and interfaces needed to implemenet and program the Secure Socket
+This package provides all the classes and interfaces needed to implement and program the Secure Socket
 abstraction based on the SSL protocol SSSLv3.0 or TLSv1.2.
 All the details of the SSL handshake protocol are accounted for, and a client or a server can specify the cipher 
 set to use.
@@ -13,14 +13,8 @@
 X.509 certificates are verified, and, if desired, the client and the server each have the option of verifying
 the entire certificate chain until the root Certificate Authority is reached.
 
-Notice that the Android javax.net.ssl package uses the OpenSSL Library to implement the low level
-SSL functionality. All the relevant OpenSSl write(...) and read(...) functions are hidden within two
-JNI files. The signatures of all the Java SSL methods are compliant with the Java 5.0
-specification.
-
-The provider for all SSL cryptological tools is The Legion of Bouncy Castle (http://www.bouncycastle.org).
+Android uses code from The Legion of the Bouncy Castle (http://www.bouncycastle.org) and OpenSSL (http://openssl.org).
 
 </p>
-@since Android 1.0
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/internal/nls/Messages.java b/x-net/src/main/java/org/apache/harmony/xnet/internal/nls/Messages.java
deleted file mode 100644
index e9f2b0e..0000000
--- a/x-net/src/main/java/org/apache/harmony/xnet/internal/nls/Messages.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
- * All changes made to this file manually will be overwritten 
- * if this tool runs again. Better make changes in the template file.
- */
-
-// BEGIN android-note
-// Redundant code has been removed and is now called from MsgHelp.
-// END android-note
-
-package org.apache.harmony.xnet.internal.nls;
-
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-// BEGIN android-changed
-import org.apache.harmony.luni.util.MsgHelp;
-// END android-changed
-
-/**
- * This class retrieves strings from a resource bundle and returns them,
- * formatting them with MessageFormat when required.
- * <p>
- * It is used by the system classes to provide national language support, by
- * looking up messages in the <code>
- *    org.apache.harmony.xnet.internal.nls.messages
- * </code>
- * resource bundle. Note that if this file is not available, or an invalid key
- * is looked up, or resource bundle support is not available, the key itself
- * will be returned as the associated message. This means that the <em>KEY</em>
- * should a reasonable human-readable (english) string.
- * 
- */
-public class Messages {
-
-    // BEGIN android-changed
-    private static final String sResource =
-        "org.apache.harmony.xnet.internal.nls.messages"; //$NON-NLS-1$
-    // END android-changed
-
-    /**
-     * Retrieves a message which has no arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg);
-        // END android-changed
-    }
-
-    /**
-     * Retrieves a message which takes 1 argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            Object the object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg) {
-        return getString(msg, new Object[] { arg });
-    }
-
-    /**
-     * Retrieves a message which takes 1 integer argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            int the integer to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, int arg) {
-        return getString(msg, new Object[] { Integer.toString(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 1 character argument.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg
-     *            char the character to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, char arg) {
-        return getString(msg, new Object[] { String.valueOf(arg) });
-    }
-
-    /**
-     * Retrieves a message which takes 2 arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param arg1
-     *            Object an object to insert in the formatted output.
-     * @param arg2
-     *            Object another object to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object arg1, Object arg2) {
-        return getString(msg, new Object[] { arg1, arg2 });
-    }
-
-    /**
-     * Retrieves a message which takes several arguments.
-     * 
-     * @param msg
-     *            String the key to look up.
-     * @param args
-     *            Object[] the objects to insert in the formatted output.
-     * @return String the message for that key in the system message bundle.
-     */
-    static public String getString(String msg, Object[] args) {
-        // BEGIN android-changed
-        return MsgHelp.getString(sResource, msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/internal/nls/messages.properties b/x-net/src/main/java/org/apache/harmony/xnet/internal/nls/messages.properties
deleted file mode 100644
index 229ca61..0000000
--- a/x-net/src/main/java/org/apache/harmony/xnet/internal/nls/messages.properties
+++ /dev/null
@@ -1,17 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-# 
-
-# messages for EN locale
\ No newline at end of file
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
index a95d38f..b780943 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/AbstractSessionContext.java
@@ -35,6 +35,7 @@
     volatile int timeout;
 
     final SSLParameters parameters;
+    final int sslCtxNativePointer;
 
     /** Identifies OpenSSL sessions. */
     static final int OPEN_SSL = 1;
@@ -46,9 +47,10 @@
      * @param maximumSize of cache
      * @param timeout for cache entries
      */
-    AbstractSessionContext(SSLParameters parameters, int maximumSize,
-            int timeout) {
+    AbstractSessionContext(SSLParameters parameters, int sslCtxNativePointer,
+            int maximumSize, int timeout) {
         this.parameters = parameters;
+        this.sslCtxNativePointer = sslCtxNativePointer;
         this.maximumSize = maximumSize;
         this.timeout = timeout;
     }
@@ -181,11 +183,20 @@
         }
     }
 
+    /**
+     * Puts an SSLSession in the AbstractSessionContext cache
+     */
+    abstract void putSession(SSLSession session);
+
     static void log(Throwable t) {
         java.util.logging.Logger.global.log(Level.WARNING,
                 "Error converting session.", t);
     }
 
+    protected void finalize() throws IOException {
+        NativeCrypto.SSL_CTX_free(sslCtxNativePointer);
+    }
+
     /**
      * Byte array wrapper. Implements equals() and hashCode().
      */
@@ -209,4 +220,4 @@
             return Arrays.equals(bytes, other.bytes);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java
index 7b27787..7246c4d 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java
@@ -55,7 +55,7 @@
      */
     X500Principal[] certificate_authorities;
 
-    //Requested certificate types as Strings
+    // Requested certificate types as Strings
     // ("RSA", "DSA", "DH_RSA" or "DH_DSA")
     private String[] types;
 
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
index 2c8738f..338fc39 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
@@ -64,8 +64,9 @@
     final SSLClientSessionCache persistentCache;
 
     public ClientSessionContext(SSLParameters parameters,
+            int sslCtxNativePointer,
             SSLClientSessionCache persistentCache) {
-        super(parameters, 10, 0);
+        super(parameters, sslCtxNativePointer, 10, 0);
         this.persistentCache = persistentCache;
     }
 
@@ -144,9 +145,9 @@
      * Adds the given session to the ID-based index if the index has already
      * been initialized.
      */
-    private void indexById(SSLSession session) {
+    private void indexById(byte[] id, SSLSession session) {
         if (sessionsById != null) {
-            sessionsById.put(new ByteArray(session.getId()), session);
+            sessionsById.put(new ByteArray(id), session);
         }
     }
 
@@ -173,7 +174,7 @@
                 if (session != null) {
                     synchronized (sessions) {
                         sessions.put(new HostAndPort(host, port), session);
-                        indexById(session);
+                        indexById(session.getId(), session);
                     }
                     return session;
                 }
@@ -183,12 +184,17 @@
         return null;
     }
 
+    @Override
     void putSession(SSLSession session) {
+        byte[] id = session.getId();
+        if (id.length == 0) {
+            return;
+        }
         HostAndPort key = new HostAndPort(session.getPeerHost(),
                 session.getPeerPort());
         synchronized (sessions) {
             sessions.put(key, session);
-            indexById(session);
+            indexById(id, session);
         }
 
         // TODO: This in a background thread.
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
index 33b0a45..083a342 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
@@ -115,6 +115,8 @@
                 put("KeyManagerFactory.X509", KeyManagerFactoryImpl.class.getName());
                 put("TrustManagerFactory.X509", TrustManagerFactoryImpl.class.getName());
                 // BEGIN android-added
+                put("SSLContext.SSL", SSLContextImpl.class.getName());
+                put("Alg.Alias.SSLContext.SSLv3", "SSL");
                 put("MessageDigest.SHA-1", "org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA1");
                 put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
                 put("Alg.Alias.MessageDigest.SHA", "SHA-1");
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
index 7698035..ad6ae15 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
@@ -16,6 +16,15 @@
 
 package org.apache.harmony.xnet.provider.jsse;
 
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import org.bouncycastle.openssl.PEMWriter;
+
 /**
  * Provides the Java side of our JNI glue for OpenSSL. Currently only hashing
  * and verifying are covered. Is expected to grow over time. Also needs to move
@@ -23,31 +32,31 @@
  */
 public class NativeCrypto {
 
+    // --- OpenSSL library initialization --------------------------------------
     static {
-        // Need to ensure that OpenSSL initialization is done exactly once.
-        // This can be cleaned up later, when all OpenSSL glue moves into its
-        // own libcore module. Make it run, make it nice.
-        OpenSSLSocketImpl.class.getClass();
+        clinit();
     }
 
+    private native static void clinit();
+
     // --- DSA/RSA public/private key handling functions -----------------------
-    
+
     public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g, byte[] priv_key, byte[] pub_key);
 
     public static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
-    
+
     public static native void EVP_PKEY_free(int pkey);
-  
+
     // --- General context handling functions (despite the names) --------------
-    
+
     public static native int EVP_new();
-    
+
     public static native void EVP_free(int ctx);
-    
+
     // --- Digest handling functions -------------------------------------------
-    
+
     public static native void EVP_DigestInit(int ctx, String algorithm);
-    
+
     public static native void EVP_DigestUpdate(int ctx, byte[] buffer, int offset, int length);
 
     public static native int EVP_DigestFinal(int ctx, byte[] hash, int offset);
@@ -55,13 +64,186 @@
     public static native int EVP_DigestSize(int ctx);
 
     public static native int EVP_DigestBlockSize(int ctx);
-    
+
     // --- Signature handling functions ----------------------------------------
-    
+
     public static native void EVP_VerifyInit(int ctx, String algorithm);
-    
+
     public static native void EVP_VerifyUpdate(int ctx, byte[] buffer, int offset, int length);
-    
+
     public static native int EVP_VerifyFinal(int ctx, byte[] signature, int offset, int length, int key);
-    
+
+    // --- SSL handling --------------------------------------------------------
+
+    private static final String SUPPORTED_PROTOCOL_SSLV3 = "SSLv3";
+    private static final String SUPPORTED_PROTOCOL_TLSV1 = "TLSv1";
+
+    public static long SSL_OP_NO_SSLv3 = 0x02000000L;
+    public static long SSL_OP_NO_TLSv1 = 0x04000000L;
+
+    public static native int SSL_CTX_new();
+
+    public static native String[] SSL_CTX_get_ciphers(int ssl_ctx);
+
+    public static String[] getDefaultCipherSuites() {
+        int ssl_ctx = SSL_CTX_new();
+        String[] supportedCiphers = SSL_CTX_get_ciphers(ssl_ctx);
+        SSL_CTX_free(ssl_ctx);
+        return supportedCiphers;
+    }
+
+    public static String[] getSupportedCipherSuites() {
+        // TODO really return full cipher list
+        return getDefaultCipherSuites();
+    }
+
+    public static native void SSL_CTX_free(int ssl_ctx);
+
+    public static native int SSL_new(int ssl_ctx, String privatekey, String certificate, byte[] seed) throws IOException;
+
+    /**
+     * Initialize the SSL socket and set the certificates for the
+     * future handshaking.
+     */
+    public static int SSL_new(SSLParameters sslParameters) throws IOException {
+        boolean client = sslParameters.getUseClientMode();
+
+        final int ssl_ctx = (client) ?
+            sslParameters.getClientSessionContext().sslCtxNativePointer :
+            sslParameters.getServerSessionContext().sslCtxNativePointer;
+
+        // TODO support more than RSA certificates?  non-openssl
+        // SSLEngine implementation did these callbacks during
+        // handshake after selecting cipher suite, not before
+        // handshake.
+        final String alias = (client) ?
+            sslParameters.getKeyManager().chooseClientAlias(new String[] { "RSA" }, null, null) :
+            sslParameters.getKeyManager().chooseServerAlias("RSA", null, null);
+
+        final String privateKeyString;
+        final String certificateString;
+        if (alias == null) {
+            privateKeyString = null;
+            certificateString = null;
+        } else {
+            PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias);
+            X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias);
+
+            ByteArrayOutputStream privateKeyOS = new ByteArrayOutputStream();
+            PEMWriter privateKeyPEMWriter = new PEMWriter(new OutputStreamWriter(privateKeyOS));
+            privateKeyPEMWriter.writeObject(privateKey);
+            privateKeyPEMWriter.close();
+            privateKeyString = privateKeyOS.toString();
+
+            ByteArrayOutputStream certificateOS = new ByteArrayOutputStream();
+            PEMWriter certificateWriter = new PEMWriter(new OutputStreamWriter(certificateOS));
+
+            for (X509Certificate certificate : certificates) {
+                certificateWriter.writeObject(certificate);
+            }
+            certificateWriter.close();
+            certificateString = certificateOS.toString();
+        }
+
+        final byte[] seed = (sslParameters.getSecureRandomMember() != null) ?
+            sslParameters.getSecureRandomMember().generateSeed(1024) :
+            null;
+
+        return SSL_new(ssl_ctx,
+                       privateKeyString,
+                       certificateString,
+                       seed);
+    }
+
+
+    public static native long SSL_get_options(int ssl);
+
+    public static native long SSL_set_options(int ssl, long options);
+
+    public static String[] getSupportedProtocols() {
+        return new String[] { SUPPORTED_PROTOCOL_SSLV3, SUPPORTED_PROTOCOL_TLSV1 };
+    }
+
+    public static String[] getEnabledProtocols(int ssl) {
+        long options = SSL_get_options(ssl);
+        ArrayList<String> array = new ArrayList<String>();
+        if ((options & NativeCrypto.SSL_OP_NO_SSLv3) == 0) {
+            array.add(SUPPORTED_PROTOCOL_SSLV3);
+        }
+        if ((options & NativeCrypto.SSL_OP_NO_TLSv1) == 0) {
+            array.add(SUPPORTED_PROTOCOL_TLSV1);
+        }
+        return array.toArray(new String[array.size()]);
+    }
+
+    public static void setEnabledProtocols(int ssl, String[] protocols) {
+        if (protocols == null) {
+            throw new IllegalArgumentException("Provided parameter is null");
+        }
+        // openssl uses negative logic letting you disable protocols.
+        // so first, lets turn them all off, and in the loop selectively enable
+        long options = SSL_get_options(ssl);
+        options |= (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
+        for (int i = 0; i < protocols.length; i++) {
+            if (protocols[i].equals(SUPPORTED_PROTOCOL_SSLV3)) {
+                options ^= SSL_OP_NO_SSLv3;
+            } else if (protocols[i].equals(SUPPORTED_PROTOCOL_TLSV1)) {
+                options ^= SSL_OP_NO_TLSv1;
+            } else {
+                throw new IllegalArgumentException("Protocol " + protocols[i] +
+                                                   " is not supported");
+            }
+        }
+        SSL_set_options(ssl, options);
+    }
+
+    public static native String[] SSL_get_ciphers(int ssl);
+
+    public static native void SSL_set_cipher_list(int ssl, String ciphers);
+
+    public static void setEnabledCipherSuites(int ssl, String[] suites) {
+        if (suites == null) {
+            throw new IllegalArgumentException("Provided parameter is null");
+        }
+
+        // makes sure all suites are valid, throwing on error
+        String[] supportedCipherSuites = getSupportedCipherSuites();
+        for (String suite : suites) {
+            findSuite(supportedCipherSuites, suite);
+        }
+
+        String controlString = "";
+        for (int i = 0; i < suites.length; i++) {
+            if (i == 0) {
+                controlString = suites[i];
+            } else {
+                controlString += ":" + suites[i];
+            }
+        }
+        SSL_set_cipher_list(ssl, controlString);
+    }
+
+    private static void findSuite(String[] supportedCipherSuites, String suite) {
+        for(int i = 0; i < supportedCipherSuites.length; i++) {
+            if (supportedCipherSuites[i].equals(suite)) {
+                return;
+            }
+        }
+        throw new IllegalArgumentException("Protocol " + suite + " is not supported.");
+    }
+
+    public static native void SSL_free(int ssl);
+
+    public interface CertificateChainVerifier {
+        /**
+         * Verify that we trust the certificate chain is trusted.
+         *
+         * @param bytes An array of certficates in byte form
+         *
+         * @throws AlertException if the certificate is untrusted
+         * @return false if there are other problems verifying the certificate chain
+         */
+        // TODO throw on error in all cases instead of returning false
+        public boolean verifyCertificateChain(byte[][] bytes);
+    }
 }
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java
index 970f5dc..f342457 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java
@@ -39,16 +39,16 @@
     }
 
     public OpenSSLServerSocketFactoryImpl(SSLParameters sslParameters) {
-        this.sslParameters = sslParameters;
+        this.sslParameters = (SSLParameters) sslParameters.clone();
+        this.sslParameters.setUseClientMode(false);
     }
 
     public String[] getDefaultCipherSuites() {
-        // TODO There might be a better way to implement this...
-        return OpenSSLServerSocketImpl.nativegetsupportedciphersuites();
+        return NativeCrypto.getDefaultCipherSuites();
     }
 
     public String[] getSupportedCipherSuites() {
-        return OpenSSLServerSocketImpl.nativegetsupportedciphersuites();
+        return NativeCrypto.getSupportedCipherSuites();
     }
 
     public ServerSocket createServerSocket() throws IOException {
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
index d52f08f..c79dccf 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl.java
@@ -16,98 +16,46 @@
 
 package org.apache.harmony.xnet.provider.jsse;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.net.InetAddress;
 import java.net.Socket;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-
-import org.bouncycastle.openssl.PEMWriter;
 
 /**
  * OpenSSL-based implementation of server sockets.
- *  
+ *
  * This class only supports SSLv3 and TLSv1. This should be documented elsewhere
  * later, for example in the package.html or a separate reference document.
- */ 
+ */
 public class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
-    private int ssl_ctx;
-    private boolean client_mode = true;
-    private long ssl_op_no = 0x00000000L;
-    private SSLParameters sslParameters;
-    private static final String[] supportedProtocols = new String[] {
-        "SSLv3",
-        "TLSv1"
-        };
-
-    private native static void nativeinitstatic();
-
-    static {
-        nativeinitstatic();
-    }
-
-    private native void nativeinit(String privatekey, String certificate, byte[] seed);
-
-    /**
-     * Initialize the SSL server socket and set the certificates for the
-     * future handshaking.
-     */
-    private void init() throws IOException {
-        String alias = sslParameters.getKeyManager().chooseServerAlias("RSA", null, null);
-        if (alias == null) {
-            throw new IOException("No suitable certificates found");
-        }
-
-        PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias);
-        X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias);
-
-        ByteArrayOutputStream privateKeyOS = new ByteArrayOutputStream();
-        PEMWriter privateKeyPEMWriter = new PEMWriter(new OutputStreamWriter(privateKeyOS));
-        privateKeyPEMWriter.writeObject(privateKey);
-        privateKeyPEMWriter.close();
-
-        ByteArrayOutputStream certificateOS = new ByteArrayOutputStream();
-        PEMWriter certificateWriter = new PEMWriter(new OutputStreamWriter(certificateOS));
-
-        for (int i = 0; i < certificates.length; i++) {
-            certificateWriter.writeObject(certificates[i]);
-        }
-        certificateWriter.close();
-
-        nativeinit(privateKeyOS.toString(), certificateOS.toString(),
-                sslParameters.getSecureRandomMember() != null ?
-                sslParameters.getSecureRandomMember().generateSeed(1024) : null);
-    }
+    private final SSLParameters sslParameters;
+    private int sslNativePointer;
 
     protected OpenSSLServerSocketImpl(SSLParameters sslParameters)
         throws IOException {
         super();
         this.sslParameters = sslParameters;
-        init();
+        this.sslNativePointer = NativeCrypto.SSL_new(sslParameters);
     }
 
     protected OpenSSLServerSocketImpl(int port, SSLParameters sslParameters)
         throws IOException {
         super(port);
         this.sslParameters = sslParameters;
-        init();
+        this.sslNativePointer = NativeCrypto.SSL_new(sslParameters);
     }
 
     protected OpenSSLServerSocketImpl(int port, int backlog, SSLParameters sslParameters)
         throws IOException {
         super(port, backlog);
         this.sslParameters = sslParameters;
-        init();
+        this.sslNativePointer = NativeCrypto.SSL_new(sslParameters);
     }
 
     protected OpenSSLServerSocketImpl(int port, int backlog, InetAddress iAddress, SSLParameters sslParameters)
         throws IOException {
         super(port, backlog, iAddress);
         this.sslParameters = sslParameters;
-        init();
+        this.sslNativePointer = NativeCrypto.SSL_new(sslParameters);
     }
 
     @Override
@@ -127,78 +75,41 @@
      */
     @Override
     public String[] getSupportedProtocols() {
-        return supportedProtocols.clone();
+        return NativeCrypto.getSupportedProtocols();
     }
 
     /**
-     * See the OpenSSL ssl.h header file for more information.
-     */
-    static private long SSL_OP_NO_SSLv3 = 0x02000000L;
-    static private long SSL_OP_NO_TLSv1 = 0x04000000L;
-
-    /**
      * The names of the protocols' versions that in use on this SSL connection.
-     * 
+     *
      * @return an array of protocols names
      */
     @Override
     public String[] getEnabledProtocols() {
-        ArrayList<String> array = new ArrayList<String>();
-
-        if ((ssl_op_no & SSL_OP_NO_SSLv3) == 0x00000000L) {
-            array.add(supportedProtocols[0]);
-        }
-        if ((ssl_op_no & SSL_OP_NO_TLSv1) == 0x00000000L) {
-            array.add(supportedProtocols[1]);
-        }
-        return array.toArray(new String[array.size()]);
+        return NativeCrypto.getEnabledProtocols(sslNativePointer);
     }
 
-    private native void nativesetenabledprotocols(long l);
-
     /**
      * This method enables the protocols' versions listed by
      * getSupportedProtocols().
-     * 
+     *
      * @param protocols names of all the protocols to enable.
-     * 
+     *
      * @throws IllegalArgumentException when one or more of the names in the
      *             array are not supported, or when the array is null.
      */
     @Override
     public void setEnabledProtocols(String[] protocols) {
-        if (protocols == null) {
-            throw new IllegalArgumentException("Provided parameter is null");
-        }
-
-        ssl_op_no  = SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
-
-        for (int i = 0; i < protocols.length; i++) {
-            if (protocols[i].equals("SSLv3"))
-                ssl_op_no ^= SSL_OP_NO_SSLv3;
-            else if (protocols[i].equals("TLSv1"))
-                ssl_op_no ^= SSL_OP_NO_TLSv1;
-            else throw new IllegalArgumentException("Protocol " + protocols[i] +
-            " is not supported.");
-        }
-
-        nativesetenabledprotocols(ssl_op_no);
+        NativeCrypto.setEnabledProtocols(sslNativePointer, protocols);
     }
 
-    /**
-     * Gets all available ciphers from the current OpenSSL library.
-     * Needed by OpenSSLServerSocketFactory too.
-     */
-    static native String[] nativegetsupportedciphersuites();
-
     @Override
     public String[] getSupportedCipherSuites() {
-        return nativegetsupportedciphersuites();
+        return NativeCrypto.getSupportedCipherSuites();
     }
 
     @Override
     public String[] getEnabledCipherSuites() {
-        return OpenSSLSocketImpl.nativeGetEnabledCipherSuites(ssl_ctx);
+        return NativeCrypto.SSL_get_ciphers(sslNativePointer);
     }
 
     /**
@@ -211,7 +122,7 @@
      */
     @Override
     public void setEnabledCipherSuites(String[] suites) {
-        OpenSSLSocketImpl.setEnabledCipherSuites(ssl_ctx, suites);
+        NativeCrypto.setEnabledCipherSuites(sslNativePointer, suites);
     }
 
     /**
@@ -223,10 +134,10 @@
     static private int SSL_VERIFY_CLIENT_ONCE =          0x04;
 
     /**
-     * Calls the SSL_CTX_set_verify(...) OpenSSL function with the passed int
+     * Calls the SSL_set_verify(...) OpenSSL function with the passed int
      * value.
      */
-    private native void nativesetclientauth(int value);
+    private static native void nativesetclientauth(int sslNativePointer, int value);
 
     private void setClientAuth() {
         int value = SSL_VERIFY_NONE;
@@ -237,7 +148,7 @@
             value |= SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
         }
 
-        nativesetclientauth(value);
+        nativesetclientauth(sslNativePointer, value);
     }
 
     @Override
@@ -274,20 +185,13 @@
 
     @Override
     public Socket accept() throws IOException {
-        OpenSSLSocketImpl socket
-                = new OpenSSLSocketImpl(sslParameters, ssl_op_no);
+        OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters, null);
         implAccept(socket);
-        socket.accept(ssl_ctx, client_mode);
-
+        socket.accept(sslNativePointer);
         return socket;
     }
 
     /**
-     * Removes OpenSSL objects from memory.
-     */
-    private native void nativefree();
-
-    /**
      * Unbinds the port if the socket is open.
      */
     @Override
@@ -297,7 +201,10 @@
 
     @Override
     public synchronized void close() throws IOException {
-        nativefree();
+        if (sslNativePointer != 0) {
+            NativeCrypto.SSL_free(sslNativePointer);
+            sslNativePointer = 0;
+        }
         super.close();
     }
 }
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
index 17cd088..2a3908c 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl.java
@@ -41,7 +41,7 @@
  * Implementation of the class OpenSSLSessionImpl
  * based on OpenSSL. The JNI native interface for some methods
  * of this this class are defined in the file:
- * org_apache_harmony_xnet_provider_jsse_OpenSSLSessionImpl.cpp
+ * org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
  */
 public class OpenSSLSessionImpl implements SSLSession {
 
@@ -52,11 +52,11 @@
     private boolean isValid = true;
     private TwoKeyHashMap values = new TwoKeyHashMap();
     private javax.security.cert.X509Certificate[] peerCertificateChain;
-    protected int session;
+    protected int sslSessionNativePointer;
     private SSLParameters sslParameters;
     private String peerHost;
     private int peerPort;
-    private final SSLSessionContext sessionContext;
+    private final AbstractSessionContext sessionContext;
 
     /**
      * Class constructor creates an SSL session context given the appropriate
@@ -65,9 +65,9 @@
      * @param session the Identifier for SSL session
      * @param sslParameters the SSL parameters like ciphers' suites etc.
      */
-    protected OpenSSLSessionImpl(int session, SSLParameters sslParameters,
-            String peerHost, int peerPort, SSLSessionContext sessionContext) {
-        this.session = session;
+    protected OpenSSLSessionImpl(int sslSessionNativePointer, SSLParameters sslParameters,
+            String peerHost, int peerPort, AbstractSessionContext sessionContext) {
+        this.sslSessionNativePointer = sslSessionNativePointer;
         this.sslParameters = sslParameters;
         this.peerHost = peerHost;
         this.peerPort = peerPort;
@@ -75,51 +75,58 @@
     }
 
     /**
-     * Constructs a session from a byte[].
+     * Constructs a session from a byte[] containing DER data. This
+     * allows loading the saved session.
+     * @throws IOException
      */
     OpenSSLSessionImpl(byte[] derData, SSLParameters sslParameters,
             String peerHost, int peerPort,
             javax.security.cert.X509Certificate[] peerCertificateChain,
-            SSLSessionContext sessionContext)
+            AbstractSessionContext sessionContext)
             throws IOException {
-        this.sslParameters = sslParameters;
-        this.peerHost = peerHost;
-        this.peerPort = peerPort;
+        this(initializeNativeImpl(derData, derData.length),
+             sslParameters,
+             peerHost,
+             peerPort,
+             sessionContext);
         this.peerCertificateChain = peerCertificateChain;
-        this.sessionContext = sessionContext;
-        initializeNative(derData);
+        // TODO move this check into native code so we can throw an error with more information
+        if (this.sslSessionNativePointer == 0) {
+            throw new IOException("Invalid session data");
+        }
     }
 
+    private static native int initializeNativeImpl(byte[] data, int size);
+
     /**
      * Gets the identifier of the actual SSL session
      * @return array of sessions' identifiers.
      */
-    public native byte[] getId();
+    public byte[] getId() {
+        return getId(sslSessionNativePointer);
+    }
+
+    private static native byte[] getId(int sslSessionNativePointer);
 
     /**
      * Get the session object in DER format. This allows saving the session
      * data or sharing it with other processes.  
      */
-    native byte[] getEncoded();
-
-    /**
-     * Init the underlying native object from DER data. This 
-     * allows loading the saved session.
-     * @throws IOException 
-     */
-    private void initializeNative(byte[] derData) throws IOException {
-        this.session = initializeNativeImpl(derData, derData.length);
-        if (this.session == 0) {
-            throw new IOException("Invalid session data");
-        }
+    byte[] getEncoded() {
+        return getEncoded(sslSessionNativePointer);
     }
-    private native int initializeNativeImpl(byte[] data, int size);
-    
+
+    private native static byte[] getEncoded(int sslSessionNativePointer);
+
     /**
      * Gets the creation time of the SSL session.
      * @return the session's creation time in milliseconds since the epoch
      */
-    public native long getCreationTime();
+    public long getCreationTime() {
+        return getCreationTime(sslSessionNativePointer);
+    }
+
+    private static native long getCreationTime(int sslSessionNativePointer);
 
     /**
      * Gives the last time this concrete SSL session was accessed. Accessing
@@ -184,7 +191,8 @@
     /**
      * Returns the X509 certificates of the peer in the PEM format.
      */
-    private native byte[][] getPeerCertificatesImpl();
+    private static native byte[][] getPeerCertificatesImpl(int sslCtxNativePointer,
+                                                           int sslSessionNativePointer);
 
     /**
      * Gives the certificate(s) of the peer in this SSL session
@@ -201,7 +209,7 @@
     public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
         if (peerCertificateChain == null) {
             try {
-                byte[][] bytes = getPeerCertificatesImpl();
+                byte[][] bytes = getPeerCertificatesImpl(sessionContext.sslCtxNativePointer, sslSessionNativePointer);
                 if (bytes == null) throw new SSLPeerUnverifiedException("No certificate available");
 
                 peerCertificateChain = new javax.security.cert.X509Certificate[bytes.length];
@@ -303,7 +311,11 @@
      * @return an identifier for all the cryptographic algorithms used in the
      *         actual SSL session.
      */
-    public native String getCipherSuite();
+    public String getCipherSuite() {
+        return getCipherSuite(sslSessionNativePointer);
+    }
+
+    private static native String getCipherSuite(int sslSessionNativePointer);
 
     /**
      * Gives back the standard version name of the SSL protocol used in all
@@ -313,7 +325,11 @@
      *         connections pertaining to this SSL session.
      *
      */
-    public native String getProtocol();
+    public String getProtocol() {
+        return getProtocol(sslSessionNativePointer);
+    }
+
+    private static native String getProtocol(int sslSessionNativePointer);
 
     /**
      * Gives back the context to which the actual SSL session is bound. A SSL
@@ -457,10 +473,8 @@
     }
 
     protected void finalize() {
-        synchronized (OpenSSLSocketImpl.class) {
-            freeImpl(session);
-        }
+        freeImpl(sslSessionNativePointer);
     }
 
-    private native void freeImpl(int session);
+    private static native void freeImpl(int session);
 }
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java
index aeb23b6..7b6d7c8 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java
@@ -46,12 +46,11 @@
     }
 
     public String[] getDefaultCipherSuites() {
-        // TODO There might be a better implementation for this...
-        return OpenSSLSocketImpl.nativegetsupportedciphersuites();
+        return NativeCrypto.getDefaultCipherSuites();
     }
 
     public String[] getSupportedCipherSuites() {
-        return OpenSSLSocketImpl.nativegetsupportedciphersuites();
+        return NativeCrypto.getSupportedCipherSuites();
     }
 
     public Socket createSocket() throws IOException {
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index 8006757..58d2110 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -16,7 +16,6 @@
 
 package org.apache.harmony.xnet.provider.jsse;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -25,7 +24,6 @@
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.SocketException;
-import java.security.PrivateKey;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.security.interfaces.RSAPublicKey;
@@ -41,43 +39,37 @@
 import javax.net.ssl.SSLSession;
 
 import org.apache.harmony.security.provider.cert.X509CertImpl;
-import org.bouncycastle.openssl.PEMWriter;
 
 /**
  * Implementation of the class OpenSSLSocketImpl
  * based on OpenSSL. The JNI native interface for some methods
  * of this this class are defined in the file:
- * org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl.cpp
- * 
+ * org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+ *
  * This class only supports SSLv3 and TLSv1. This should be documented elsewhere
- * later, for example in the package.html or a separate reference document. 
+ * later, for example in the package.html or a separate reference document.
  */
-public class OpenSSLSocketImpl extends javax.net.ssl.SSLSocket {
-    private int ssl_ctx;
-    private int ssl;
+public class OpenSSLSocketImpl
+        extends javax.net.ssl.SSLSocket
+        implements NativeCrypto.CertificateChainVerifier {
+    private int sslNativePointer;
     private InputStream is;
     private OutputStream os;
     private final Object handshakeLock = new Object();
-    private Object readLock = new Object();
-    private Object writeLock = new Object();
+    private final Object readLock = new Object();
+    private final Object writeLock = new Object();
     private SSLParameters sslParameters;
     private OpenSSLSessionImpl sslSession;
     private Socket socket;
     private boolean autoClose;
     private boolean handshakeStarted = false;
     private ArrayList<HandshakeCompletedListener> listeners;
-    private long ssl_op_no = 0x00000000L;
     private int timeout = 0;
     // BEGIN android-added
     private int handshakeTimeout = -1;  // -1 = same as timeout; 0 = infinite
     // END android-added
     private InetSocketAddress address;
 
-    private static final String[] supportedProtocols = new String[] {
-        "SSLv3",
-        "TLSv1"
-        };
-
     private static final AtomicInteger instanceCount = new AtomicInteger(0);
 
     public static int getInstanceCount() {
@@ -89,66 +81,6 @@
     }
 
     /**
-     * Initialize OpenSSL library.
-     */
-    private native static void nativeinitstatic();
-
-    static {
-        nativeinitstatic();
-    }
-
-    private native void nativeinit(String privatekey, String certificate, byte[] seed);
-
-    /**
-     * Initialize the SSL socket and set the certificates for the
-     * future handshaking.
-     */
-    private void init() throws IOException {
-        String alias = sslParameters.getKeyManager().chooseClientAlias(new String[] { "RSA" }, null, null);
-        if (alias != null) {
-            PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias);
-            X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias);
-
-            ByteArrayOutputStream privateKeyOS = new ByteArrayOutputStream();
-            PEMWriter privateKeyPEMWriter = new PEMWriter(new OutputStreamWriter(privateKeyOS));
-            privateKeyPEMWriter.writeObject(privateKey);
-            privateKeyPEMWriter.close();
-
-            ByteArrayOutputStream certificateOS = new ByteArrayOutputStream();
-            PEMWriter certificateWriter = new PEMWriter(new OutputStreamWriter(certificateOS));
-
-            for (int i = 0; i < certificates.length; i++) {
-                certificateWriter.writeObject(certificates[i]);
-            }
-            certificateWriter.close();
-
-            nativeinit(privateKeyOS.toString(), certificateOS.toString(),
-                    sslParameters.getSecureRandomMember() != null ?
-                    sslParameters.getSecureRandomMember().generateSeed(1024) : null);
-        } else {
-            nativeinit(null, null,
-                    sslParameters.getSecureRandomMember() != null ?
-                    sslParameters.getSecureRandomMember().generateSeed(1024) : null);
-        }
-    }
-
-    /**
-     * Class constructor with 2 parameters
-     *
-     * @param sslParameters Parameters for the SSL
-     *            context
-     * @param ssl_op_no Parameter to set the enabled
-     *            protocols
-     * @throws IOException if network fails
-     */
-    protected OpenSSLSocketImpl(SSLParameters sslParameters, long ssl_op_no) throws IOException {
-        super();
-        this.sslParameters = sslParameters;
-        this.ssl_op_no = ssl_op_no;
-        updateInstanceCount(1);
-    }
-
-    /**
      * Class constructor with 1 parameter
      *
      * @param sslParameters Parameters for the SSL
@@ -157,9 +89,7 @@
      */
     protected OpenSSLSocketImpl(SSLParameters sslParameters) throws IOException {
         super();
-        this.sslParameters = sslParameters;
-        init();
-        updateInstanceCount(1);
+        init(sslParameters);
     }
 
     /**
@@ -172,12 +102,9 @@
             SSLParameters sslParameters)
         throws IOException {
         super(host, port);
-        this.sslParameters = sslParameters;
-        init();
-        updateInstanceCount(1);
+        init(sslParameters);
     }
 
-
     /**
      * Class constructor with 3 parameters: 1st is InetAddress
      *
@@ -188,9 +115,7 @@
             SSLParameters sslParameters)
         throws IOException {
         super(address, port);
-        this.sslParameters = sslParameters;
-        init();
-        updateInstanceCount(1);
+        init(sslParameters);
     }
 
 
@@ -204,9 +129,7 @@
             int clientPort, SSLParameters sslParameters)
         throws IOException {
         super(host, port, clientAddress, clientPort);
-        this.sslParameters = sslParameters;
-        init();
-        updateInstanceCount(1);
+        init(sslParameters);
     }
 
     /**
@@ -219,9 +142,7 @@
             InetAddress clientAddress, int clientPort, SSLParameters sslParameters)
         throws IOException {
         super(address, port, clientAddress, clientPort);
-        this.sslParameters = sslParameters;
-        init();
-        updateInstanceCount(1);
+        init(sslParameters);
     }
 
     /**
@@ -237,8 +158,28 @@
         this.timeout = socket.getSoTimeout();
         this.address = new InetSocketAddress(host, port);
         this.autoClose = autoClose;
+        init(sslParameters);
+    }
+
+    /**
+     * Initialize the SSL socket and set the certificates for the
+     * future handshaking.
+     */
+    private void init(SSLParameters sslParameters) throws IOException {
         this.sslParameters = sslParameters;
-        init();
+        this.sslNativePointer = NativeCrypto.SSL_new(sslParameters);
+        updateInstanceCount(1);
+    }
+
+    /**
+     * Construct a OpenSSLSocketImpl from an SSLParameters and an
+     * existing SSL native pointer. Used for transitioning accepting
+     * the OpenSSLSocketImpl within OpenSSLServerSocketImpl.
+     */
+    protected OpenSSLSocketImpl(SSLParameters sslParameters,
+                                OpenSSLServerSocketImpl dummy) {
+        super();
+        this.sslParameters = (SSLParameters) sslParameters.clone();
         updateInstanceCount(1);
     }
 
@@ -246,9 +187,9 @@
      * Adds OpenSSL functionality to the existing socket and starts the SSL
      * handshaking.
      */
-    private native boolean nativeconnect(int ctx, Socket sock, boolean client_mode, int sslsession) throws IOException;
-    private native int nativegetsslsession(int ssl);
-    private native String nativecipherauthenticationmethod();
+    private native boolean nativeconnect(int sslNativePointer, Socket sock, int timeout, boolean client_mode, int sslSessionNativePointer) throws IOException;
+    private native int nativegetsslsession(int sslNativePointer);
+    private native String nativecipherauthenticationmethod(int sslNativePointer);
 
     /**
      * Gets the suitable session reference from the session cache container.
@@ -256,6 +197,9 @@
      * @return OpenSSLSessionImpl
      */
     private OpenSSLSessionImpl getCachedClientSession() {
+        if (!sslParameters.getUseClientMode()) {
+            return null;
+        }
         if (super.getInetAddress() == null ||
                 super.getInetAddress().getHostAddress() == null ||
                 super.getInetAddress().getHostName() == null) {
@@ -273,8 +217,7 @@
      * before logging is ready.
      */
     static class LoggerHolder {
-        static final Logger logger = Logger.getLogger(
-                OpenSSLSocketImpl.class.getName());
+        static final Logger logger = Logger.getLogger(OpenSSLSocketImpl.class.getName());
     }
 
     /**
@@ -282,7 +225,7 @@
      * from the OpenSSL library. It can negotiate new encryption keys, change
      * cipher suites, or initiate a new session. The certificate chain is
      * verified if the correspondent property in java.Security is set. All
-     * listensers are notified at the end of the TLS/SSL handshake.
+     * listeners are notified at the end of the TLS/SSL handshake.
      *
      * @throws <code>IOException</code> if network fails
      */
@@ -300,86 +243,77 @@
         // Check if it's allowed to create a new session (default is true)
         if (session == null && !sslParameters.getEnableSessionCreation()) {
             throw new SSLHandshakeException("SSL Session may not be created");
-        } else {
-            // BEGIN android-added
-            // Temporarily use a different timeout for the handshake process
-            int savedTimeout = timeout;
-            if (handshakeTimeout >= 0) {
-                setSoTimeout(handshakeTimeout);
-            }
-            // END android-added
-
-            Socket socket = this.socket != null ? this.socket : this;
-            int sessionId = session != null ? session.session : 0;
-            boolean reusedSession;
-            synchronized (OpenSSLSocketImpl.class) {
-                reusedSession = nativeconnect(ssl_ctx, socket,
-                        sslParameters.getUseClientMode(), sessionId);
-            }
-            if (reusedSession) {
-                // nativeconnect shouldn't return true if the session is not
-                // done
-                session.lastAccessedTime = System.currentTimeMillis();
-                sslSession = session;
-
-                LoggerHolder.logger.fine("Reused cached session for "
-                        + getInetAddress().getHostName() + ".");
-            } else {
-                if (session != null) {
-                    LoggerHolder.logger.fine("Reuse of cached session for "
-                            + getInetAddress().getHostName() + " failed.");
-                } else {
-                    LoggerHolder.logger.fine("Created new session for "
-                            + getInetAddress().getHostName() + ".");
-                }
-
-                ClientSessionContext sessionContext
-                        = sslParameters.getClientSessionContext();
-                synchronized (OpenSSLSocketImpl.class) {
-                    sessionId = nativegetsslsession(ssl);
-                }
-                if (address == null) {
-                    sslSession = new OpenSSLSessionImpl(
-                            sessionId, sslParameters,
-                            super.getInetAddress().getHostName(),
-                            super.getPort(), sessionContext);
-                } else  {
-                    sslSession = new OpenSSLSessionImpl(
-                            sessionId, sslParameters,
-                            address.getHostName(), address.getPort(),
-                            sessionContext);
-                }
-
-                try {
-                    X509Certificate[] peerCertificates = (X509Certificate[])
-                            sslSession.getPeerCertificates();
-
-                    if (peerCertificates == null
-                            || peerCertificates.length == 0) {
-                        throw new SSLException("Server sends no certificate");
-                    }
-
-                    String authMethod;
-                    synchronized (OpenSSLSocketImpl.class) {
-                        authMethod = nativecipherauthenticationmethod();
-                    }
-                    sslParameters.getTrustManager().checkServerTrusted(
-                            peerCertificates,
-                            authMethod);
-                    sessionContext.putSession(sslSession);
-                } catch (CertificateException e) {
-                    throw new SSLException("Not trusted server certificate", e);
-                }
-            }
-
-            // BEGIN android-added
-            // Restore the original timeout now that the handshake is complete
-            if (handshakeTimeout >= 0) {
-                setSoTimeout(savedTimeout);
-            }
-            // END android-added
         }
 
+        // BEGIN android-added
+        // Temporarily use a different timeout for the handshake process
+        int savedTimeout = timeout;
+        if (handshakeTimeout >= 0) {
+            setSoTimeout(handshakeTimeout);
+        }
+        // END android-added
+
+        Socket socket = this.socket != null ? this.socket : this;
+        int sslSessionNativePointer = session != null ? session.sslSessionNativePointer : 0;
+        boolean reusedSession = nativeconnect(sslNativePointer, socket, timeout,
+                                              sslParameters.getUseClientMode(), sslSessionNativePointer);
+        if (reusedSession) {
+            // nativeconnect shouldn't return true if the session is not
+            // done
+            session.lastAccessedTime = System.currentTimeMillis();
+            sslSession = session;
+
+            LoggerHolder.logger.fine("Reused cached session for "
+                                     + getInetAddress().getHostName() + ".");
+        } else {
+            if (session != null) {
+                LoggerHolder.logger.fine("Reuse of cached session for "
+                                         + getInetAddress().getHostName() + " failed.");
+            } else {
+                LoggerHolder.logger.fine("Created new session for "
+                                         + getInetAddress().getHostName() + ".");
+            }
+
+            AbstractSessionContext sessionContext =
+                (sslParameters.getUseClientMode()) ?
+                sslParameters.getClientSessionContext() :
+                sslParameters.getServerSessionContext();
+            sslSessionNativePointer = nativegetsslsession(sslNativePointer);
+            if (address == null) {
+                sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, sslParameters,
+                                                    super.getInetAddress().getHostName(),
+                                                    super.getPort(), sessionContext);
+            } else  {
+                sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, sslParameters,
+                                                    address.getHostName(), address.getPort(),
+                                                    sessionContext);
+            }
+
+            try {
+                X509Certificate[] peerCertificates = (X509Certificate[])
+                    sslSession.getPeerCertificates();
+
+                if (peerCertificates == null
+                    || peerCertificates.length == 0) {
+                    throw new SSLException("Server sends no certificate");
+                }
+
+                String authMethod = nativecipherauthenticationmethod(sslNativePointer);
+                sslParameters.getTrustManager().checkServerTrusted(peerCertificates,
+                                                                   authMethod);
+                sessionContext.putSession(sslSession);
+            } catch (CertificateException e) {
+                throw new SSLException("Not trusted server certificate", e);
+            }
+        }
+
+        // BEGIN android-added
+        // Restore the original timeout now that the handshake is complete
+        if (handshakeTimeout >= 0) {
+            setSoTimeout(savedTimeout);
+        }
+        // END android-added
+
         if (listeners != null) {
             // notify the listeners
             HandshakeCompletedEvent event =
@@ -392,22 +326,22 @@
     }
 
     // To be synchronized because of the verify_callback
-    native synchronized void nativeaccept(Socket socketObject, int m_ctx, boolean client_mode);
+    native synchronized int nativeaccept(int sslNativePointer, Socket socketObject);
 
     /**
      * Performs the first part of a SSL/TLS handshaking process with a given
      * 'host' connection and initializes the SSLSession.
      */
-    protected void accept(int m_ctx, boolean client_mode) throws IOException {
+    protected void accept(int serverSslNativePointer) throws IOException {
         // Must be set because no handshaking is necessary
         // in this situation
         handshakeStarted = true;
 
-        nativeaccept(this, m_ctx, client_mode);
+        sslNativePointer = nativeaccept(serverSslNativePointer, this);
 
         ServerSessionContext sessionContext
                 = sslParameters.getServerSessionContext();
-        sslSession = new OpenSSLSessionImpl(nativegetsslsession(ssl),
+        sslSession = new OpenSSLSessionImpl(nativegetsslsession(sslNativePointer),
                 sslParameters, super.getInetAddress().getHostName(),
                 super.getPort(), sessionContext);
         sslSession.lastAccessedTime = System.currentTimeMillis();
@@ -415,14 +349,16 @@
     }
 
     /**
-     * Callback methode for the OpenSSL native certificate verification process.
+     * Implementation of NativeCrypto.CertificateChainVerifier.
+     *
+     * Callback method for the OpenSSL native certificate verification process.
      *
      * @param bytes Byte array containing the cert's
      *            information.
-     * @return 0 if the certificate verification fails or 1 if OK
+     * @return false if the certificate verification fails or true if OK
      */
     @SuppressWarnings("unused")
-    private int verify_callback(byte[][] bytes) {
+    public boolean verifyCertificateChain(byte[][] bytes) {
         try {
             X509Certificate[] peerCertificateChain
                     = new X509Certificate[bytes.length];
@@ -439,11 +375,13 @@
                         new SSLException("Not trusted server certificate", e));
             }
         } catch (javax.security.cert.CertificateException e) {
-            return 0;
+            // TODO throw in all cases for consistency
+            return false;
         } catch (IOException e) {
-            return 0;
+            // TODO throw in all cases for consistency
+            return false;
         }
-        return 1;
+        return true;
     }
 
     /**
@@ -483,28 +421,28 @@
         }
     }
 
-    /**
-     * This method is not supported for this SSLSocket implementation.
-     */
     public void shutdownInput() throws IOException {
-        throw new UnsupportedOperationException(
-        "Method shutdownInput() is not supported.");
+        if (socket == null) {
+            super.shutdownInput();
+            return;
+        }
+        socket.shutdownInput();
     }
 
-    /**
-     * This method is not supported for this SSLSocket implementation.
-     */
     public void shutdownOutput() throws IOException {
-        throw new UnsupportedOperationException(
-        "Method shutdownOutput() is not supported.");
+        if (socket == null) {
+            super.shutdownOutput();
+            return;
+        }
+        socket.shutdownOutput();
     }
 
     /**
      * Reads with the native SSL_read function from the encrypted data stream
      * @return -1 if error or the end of the stream is reached.
      */
-    private native int nativeread(int timeout) throws IOException;
-    private native int nativeread(byte[] b, int off, int len, int timeout) throws IOException;
+    private native int nativeread(int sslNativePointer, int timeout) throws IOException;
+    private native int nativeread(int sslNativePointer, byte[] b, int off, int len, int timeout) throws IOException;
 
     /**
      * This inner class provides input data stream functionality
@@ -529,7 +467,7 @@
          */
         public int read() throws IOException {
             synchronized(readLock) {
-                return OpenSSLSocketImpl.this.nativeread(timeout);
+                return OpenSSLSocketImpl.this.nativeread(sslNativePointer, timeout);
             }
         }
 
@@ -539,7 +477,7 @@
          */
         public int read(byte[] b, int off, int len) throws IOException {
             synchronized(readLock) {
-                return OpenSSLSocketImpl.this.nativeread(b, off, len, timeout);
+                return OpenSSLSocketImpl.this.nativeread(sslNativePointer, b, off, len, timeout);
             }
         }
     }
@@ -547,8 +485,8 @@
     /**
      * Writes with the native SSL_write function to the encrypted data stream.
      */
-    private native void nativewrite(int b) throws IOException;
-    private native void nativewrite(byte[] b, int off, int len) throws IOException;
+    private native void nativewrite(int sslNativePointer, int b) throws IOException;
+    private native void nativewrite(int sslNativePointer, byte[] b, int off, int len) throws IOException;
 
     /**
      * This inner class provides output data stream functionality
@@ -559,7 +497,7 @@
         SSLOutputStream() throws IOException {
             /**
             /* Note: When startHandshake() throws an exception, no
-             * SSLInputStream object will be created.
+             * SSLOutputStream object will be created.
              */
             OpenSSLSocketImpl.this.startHandshake();
         }
@@ -570,7 +508,7 @@
          */
         public void write(int b) throws IOException {
             synchronized(writeLock) {
-                OpenSSLSocketImpl.this.nativewrite(b);
+                OpenSSLSocketImpl.this.nativewrite(sslNativePointer, b);
             }
         }
 
@@ -580,7 +518,7 @@
          */
         public void write(byte[] b, int start, int len) throws IOException {
             synchronized(writeLock) {
-                OpenSSLSocketImpl.this.nativewrite(b, start, len);
+                OpenSSLSocketImpl.this.nativewrite(sslNativePointer, b, start, len);
             }
         }
     }
@@ -598,9 +536,6 @@
         try {
             startHandshake();
         } catch (IOException e) {
-            Logger.getLogger(getClass().getName()).log(Level.WARNING,
-                    "Error negotiating SSL connection.", e);
-
             // return an invalid session with
             // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
             return SSLSessionImpl.NULL_SESSION;
@@ -666,22 +601,14 @@
     }
 
     /**
-     * Gets all available ciphers from the current OpenSSL library.
-     * Needed by OpenSSLSocketFactory too.
-     */
-    static native String[] nativegetsupportedciphersuites();
-
-    /**
      * The names of the cipher suites which could be used by the SSL connection
      * are returned.
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        return nativegetsupportedciphersuites();
+        return NativeCrypto.getSupportedCipherSuites();
     }
 
-    static native String[] nativeGetEnabledCipherSuites(int ssl_ctx);
-
     /**
      * The names of the cipher suites that are in use in the actual the SSL
      * connection are returned.
@@ -689,23 +616,7 @@
      * @return an array of cipher suite names
      */
     public String[] getEnabledCipherSuites() {
-        return nativeGetEnabledCipherSuites(ssl_ctx);
-    }
-
-    /**
-     * Calls the SSL_CTX_set_cipher_list(...) OpenSSL function with the passed
-     * char array.
-     */
-    static native void nativeSetEnabledCipherSuites(int ssl_ctx, String controlString);
-
-    private static boolean findSuite(String suite) {
-        String[] supportedCipherSuites = nativegetsupportedciphersuites();
-        for(int i = 0; i < supportedCipherSuites.length; i++) {
-            if (supportedCipherSuites[i].equals(suite)) {
-                return true;
-            }
-        }
-        throw new IllegalArgumentException("Protocol " + suite + " is not supported.");
+        return NativeCrypto.SSL_get_ciphers(sslNativePointer);
     }
 
     /**
@@ -719,20 +630,7 @@
      *             is null.
      */
     public void setEnabledCipherSuites(String[] suites) {
-        setEnabledCipherSuites(ssl_ctx, suites);
-    }
-    
-    static void setEnabledCipherSuites(int ssl_ctx, String[] suites) {
-        if (suites == null) {
-            throw new IllegalArgumentException("Provided parameter is null");
-        }
-        String controlString = "";
-        for (int i = 0; i < suites.length; i++) {
-            findSuite(suites[i]);
-            if (i == 0) controlString = suites[i];
-            else controlString += ":" + suites[i];
-        }
-        nativeSetEnabledCipherSuites(ssl_ctx, controlString);
+        NativeCrypto.setEnabledCipherSuites(sslNativePointer, suites);
     }
 
     /**
@@ -741,65 +639,32 @@
      * @return an array of protocols names
      */
     public String[] getSupportedProtocols() {
-        return supportedProtocols.clone();
+        return NativeCrypto.getSupportedProtocols();
     }
 
     /**
-     * SSL mode of operation with or without back compatibility. See the OpenSSL
-     * ssl.h header file for more information.
-     */
-    static private long SSL_OP_NO_SSLv3 = 0x02000000L;
-    static private long SSL_OP_NO_TLSv1 = 0x04000000L;
-
-    /**
      * The names of the protocols' versions that are in use on this SSL
      * connection.
-     * 
+     *
      * @return an array of protocols names
      */
     @Override
     public String[] getEnabledProtocols() {
-        ArrayList<String> array = new ArrayList<String>();
-
-        if ((ssl_op_no & SSL_OP_NO_SSLv3) == 0x00000000L) {
-            array.add(supportedProtocols[1]);
-        }
-        if ((ssl_op_no & SSL_OP_NO_TLSv1) == 0x00000000L) {
-            array.add(supportedProtocols[2]);
-        }
-        return array.toArray(new String[array.size()]);
+        return NativeCrypto.getEnabledProtocols(sslNativePointer);
     }
 
-    private native void nativesetenabledprotocols(long l);
-
     /**
      * This method enables the protocols' versions listed by
      * getSupportedProtocols().
-     * 
+     *
      * @param protocols The names of all the protocols to put on use
-     * 
+     *
      * @throws IllegalArgumentException when one or more of the names in the
      *             array are not supported, or when the array is null.
      */
     @Override
     public synchronized void setEnabledProtocols(String[] protocols) {
-
-        if (protocols == null) {
-            throw new IllegalArgumentException("Provided parameter is null");
-        }
-
-        ssl_op_no  = SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
-
-        for(int i = 0; i < protocols.length; i++) {
-            if (protocols[i].equals("SSLv3"))
-                ssl_op_no ^= SSL_OP_NO_SSLv3;
-            else if (protocols[i].equals("TLSv1"))
-                ssl_op_no ^= SSL_OP_NO_TLSv1;
-            else throw new IllegalArgumentException("Protocol " + protocols[i] +
-            " is not supported.");
-        }
-
-        nativesetenabledprotocols(ssl_op_no);
+        NativeCrypto.setEnabledProtocols(sslNativePointer, protocols);
     }
 
     /**
@@ -912,8 +777,8 @@
     }
     // END android-added
 
-    private native void nativeinterrupt() throws IOException;
-    private native void nativeclose() throws IOException;
+    private native void nativeinterrupt(int sslNativePointer) throws IOException;
+    private native void nativeclose(int sslNativePointer) throws IOException;
 
     /**
      * Closes the SSL socket. Once closed, a socket is not available for further
@@ -929,9 +794,9 @@
         synchronized (handshakeLock) {
             if (!handshakeStarted) {
                 handshakeStarted = true;
-                
+
                 synchronized (this) {
-                    nativefree();
+                    free();
 
                     if (socket != null) {
                         if (autoClose && !socket.isClosed()) socket.close();
@@ -939,12 +804,12 @@
                         if (!super.isClosed()) super.close();
                     }
                 }
-                
+
                 return;
             }
         }
 
-        nativeinterrupt();
+        nativeinterrupt(sslNativePointer);
 
         synchronized (this) {
             synchronized (writeLock) {
@@ -955,7 +820,7 @@
                     // Shut down the SSL connection, per se.
                     try {
                         if (handshakeStarted) {
-                            nativeclose();
+                            nativeclose(sslNativePointer);
                         }
                     } catch (IOException ex) {
                         /*
@@ -970,7 +835,7 @@
                      * the native structs, and we need to do so lest we leak
                      * memory.
                      */
-                    nativefree();
+                    free();
 
                     if (socket != null) {
                         if (autoClose && !socket.isClosed())
@@ -988,12 +853,18 @@
         }
     }
 
-    private native void nativefree();
+    private void free() {
+        if (sslNativePointer == 0) {
+            return;
+        }
+        NativeCrypto.SSL_free(sslNativePointer);
+        sslNativePointer = 0;
+    }
 
     protected void finalize() throws IOException {
         updateInstanceCount(-1);
 
-        if (ssl == 0) {
+        if (sslNativePointer == 0) {
             /*
              * It's already been closed, so there's no need to do anything
              * more at this point.
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
index c39e3ff..34942e1 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
@@ -73,8 +73,6 @@
      * @param clientCache persistent client session cache or {@code null}
      * @param serverCache persistent server session cache or {@code null}
      * @throws KeyManagementException if initializing this instance fails
-     * 
-     * @since Android 1.1
      */
     public void engineInit(KeyManager[] kms, TrustManager[] tms,
             SecureRandom sr, SSLClientSessionCache clientCache,
@@ -126,4 +124,4 @@
     public ClientSessionContext engineGetClientSessionContext() {
         return clientSessionContext;
     }
-}
\ No newline at end of file
+}
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
index 89916de..525756d 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
@@ -93,29 +93,11 @@
         if (enabledCipherSuites == null) this.enabledCipherSuites = CipherSuite.defaultCipherSuites;
         return enabledCipherSuites;
     }
-
-    /**
-     * Holds a pointer to our native SSL context.
-     */
-    private int ssl_ctx = 0;
-    
-    /**
-     * Initializes our native SSL context.
-     */
-    private native int nativeinitsslctx();
-
-    /**
-     * Returns the native SSL context, creating it on-the-fly, if necessary.
-     */
-    protected synchronized int getSSLCTX() {
-        if (ssl_ctx == 0) ssl_ctx = nativeinitsslctx();
-        return ssl_ctx;
-    }
 // END android-changed
 
     /**
      * Initializes the parameters. Naturally this constructor is used
-     * in SSLContextImpl.engineInit method which dirrectly passes its 
+     * in SSLContextImpl.engineInit method which dirrectly passes its
      * parameters. In other words this constructor holds all
      * the functionality provided by SSLContext.init method.
      * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
@@ -127,21 +109,21 @@
             SSLServerSessionCache serverCache)
             throws KeyManagementException {
         this.serverSessionContext
-                = new ServerSessionContext(this, serverCache);
+                = new ServerSessionContext(this, NativeCrypto.SSL_CTX_new(), serverCache);
         this.clientSessionContext
-                = new ClientSessionContext(this, clientCache);
+                = new ClientSessionContext(this, NativeCrypto.SSL_CTX_new(), clientCache);
 // END android-changed
         try {
             // initialize key manager
             boolean initialize_default = false;
-            // It's not described by the spec of SSLContext what should happen 
+            // It's not described by the spec of SSLContext what should happen
             // if the arrays of length 0 are specified. This implementation
             // behave as for null arrays (i.e. use installed security providers)
             if ((kms == null) || (kms.length == 0)) {
                 if (defaultKeyManager == null) {
                     KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                             KeyManagerFactory.getDefaultAlgorithm());
-                    kmf.init(null, null);                
+                    kmf.init(null, null);
                     kms = kmf.getKeyManagers();
                     // tell that we are trying to initialize defaultKeyManager
                     initialize_default = true;
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
index a3c2c6d..c379fee 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
@@ -46,8 +46,9 @@
     private final SSLServerSessionCache persistentCache;
 
     public ServerSessionContext(SSLParameters parameters,
+            int sslCtxNativePointer,
             SSLServerSessionCache persistentCache) {
-        super(parameters, 100, 0);
+        super(parameters, sslCtxNativePointer, 100, 0);
         this.persistentCache = persistentCache;
     }
 
@@ -107,8 +108,13 @@
         return null;
     }
 
+    @Override
     void putSession(SSLSession session) {
-        ByteArray key = new ByteArray(session.getId());
+        byte[] id = session.getId();
+        if (id.length == 0) {
+            return;
+        }
+        ByteArray key = new ByteArray(id);
         synchronized (sessions) {
             sessions.put(key, session);
         }
diff --git a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
index d0682a4..8af33aa 100644
--- a/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+++ b/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
@@ -46,7 +46,7 @@
 
 /**
  * Frees the SSL error state.
- * 
+ *
  * OpenSSL keeps an "error stack" per thread, and given that this code
  * can be called from arbitrary threads that we don't keep track of,
  * we err on the side of freeing the error state promptly (instead of,
@@ -60,7 +60,7 @@
 /*
  * Checks this thread's OpenSSL error queue and throws a RuntimeException if
  * necessary.
- * 
+ *
  * @return 1 if an exception was thrown, 0 if not.
  */
 static int throwExceptionIfNecessary(JNIEnv* env) {
@@ -79,328 +79,6 @@
     return result;
 }
 
-/**
- * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
- * fly.
- */
-static BIGNUM* arrayToBignum(JNIEnv* env, jbyteArray source) {
-    // LOGD("Entering arrayToBignum()");
-  
-    jbyte* sourceBytes = env->GetByteArrayElements(source, NULL);
-    int sourceLength = env->GetArrayLength(source);
-    BIGNUM* bignum = BN_bin2bn((unsigned char*) sourceBytes, sourceLength, NULL);
-    env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
-    return bignum;
-}
-
-/**
- * private static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g, byte[] pub_key, byte[] priv_key);
- */
-static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass clazz, jbyteArray p, jbyteArray q, jbyteArray g, jbyteArray pub_key, jbyteArray priv_key) {
-    // LOGD("Entering EVP_PKEY_new_DSA()");
-  
-    DSA* dsa = DSA_new();
-  
-    dsa->p = arrayToBignum(env, p);
-    dsa->q = arrayToBignum(env, q);
-    dsa->g = arrayToBignum(env, g);
-    dsa->pub_key = arrayToBignum(env, pub_key);
-    
-    if (priv_key != NULL) {
-        dsa->priv_key = arrayToBignum(env, priv_key);
-    }
-
-    if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) {
-        DSA_free(dsa);
-        jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
-        return NULL;
-    }
-    
-    EVP_PKEY* pkey = EVP_PKEY_new();
-    EVP_PKEY_assign_DSA(pkey, dsa);
-    
-    return pkey;
-}
-
-/**
- * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
- */
-static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass clazz, jbyteArray n, jbyteArray e, jbyteArray d, jbyteArray p, jbyteArray q) {
-    // LOGD("Entering EVP_PKEY_new_RSA()");
-  
-    RSA* rsa = RSA_new();
-  
-    rsa->n = arrayToBignum(env, n);
-    rsa->e = arrayToBignum(env, e);
-    
-    if (d != NULL) {
-        rsa->d = arrayToBignum(env, d);
-    }
-    
-    if (p != NULL) {
-        rsa->p = arrayToBignum(env, p);
-    }
-    
-    if (q != NULL) {
-        rsa->q = arrayToBignum(env, q);
-    }
-
-    // int check = RSA_check_key(rsa);
-    // LOGI("RSA_check_key returns %d", check);
-    
-    if (rsa->n == NULL || rsa->e == NULL) {
-        RSA_free(rsa);
-        jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
-        return NULL;
-    }
-    
-    EVP_PKEY* pkey = EVP_PKEY_new();
-    EVP_PKEY_assign_RSA(pkey, rsa);
-    
-    return pkey;
-}
-
-/**
- * private static native void EVP_PKEY_free(int pkey);
- */
-static void NativeCrypto_EVP_PKEY_free(JNIEnv* env, jclass clazz, EVP_PKEY* pkey) {
-    // LOGD("Entering EVP_PKEY_free()");
-
-    if (pkey != NULL) {
-        EVP_PKEY_free(pkey);
-    }
-}
-
-/*
- * public static native int EVP_new()
- */
-static jint NativeCrypto_EVP_new(JNIEnv* env, jclass clazz) {
-    // LOGI("NativeCrypto_EVP_DigestNew");
-    
-    return (jint)EVP_MD_CTX_create();
-}
-
-/*
- * public static native void EVP_free(int)
- */
-static void NativeCrypto_EVP_free(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
-    // LOGI("NativeCrypto_EVP_DigestFree");
-  
-    if (ctx != NULL) {
-        EVP_MD_CTX_destroy(ctx);
-    }
-}
-
-/*
- * public static native int EVP_DigestFinal(int, byte[], int)
- */
-static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray hash, jint offset) {
-    // LOGI("NativeCrypto_EVP_DigestFinal%x, %x, %d, %d", ctx, hash, offset);
-    
-    if (ctx == NULL || hash == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return -1;
-    }
-
-    int result = -1;
-    
-    jbyte* hashBytes = env->GetByteArrayElements(hash, NULL);
-    EVP_DigestFinal(ctx, (unsigned char*) (hashBytes + offset), (unsigned int*)&result);
-    env->ReleaseByteArrayElements(hash, hashBytes, 0);
-
-    throwExceptionIfNecessary(env);
-    
-    return result;
-}
-
-/*
- * public static native void EVP_DigestInit(int, java.lang.String)
- */
-static void NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
-    // LOGI("NativeCrypto_EVP_DigestInit");
-    
-    if (ctx == NULL || algorithm == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return;
-    }
-    
-    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
-    
-    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
-    env->ReleaseStringUTFChars(algorithm, algorithmChars);
-    
-    if (digest == NULL) {
-        jniThrowRuntimeException(env, "Hash algorithm not found");
-        return;
-    }
-    
-    EVP_DigestInit(ctx, digest);
-    
-    throwExceptionIfNecessary(env);
-}
-
-/*
- * public static native void EVP_DigestSize(int)
- */
-static jint NativeCrypto_EVP_DigestSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
-    // LOGI("NativeCrypto_EVP_DigestSize");
-    
-    if (ctx == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return -1;
-    }
-    
-    int result = EVP_MD_CTX_size(ctx);
-    
-    throwExceptionIfNecessary(env);
-    
-    return result;
-}
-
-/*
- * public static native void EVP_DigestBlockSize(int)
- */
-static jint NativeCrypto_EVP_DigestBlockSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
-    // LOGI("NativeCrypto_EVP_DigestBlockSize");
-    
-    if (ctx == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return -1;
-    }
-    
-    int result = EVP_MD_CTX_block_size(ctx);
-    
-    throwExceptionIfNecessary(env);
-    
-    return result;
-}
-
-/*
- * public static native void EVP_DigestUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) {
-    // LOGI("NativeCrypto_EVP_DigestUpdate %x, %x, %d, %d", ctx, buffer, offset, length);
-    
-    if (ctx == NULL || buffer == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return;
-    }
-  
-    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
-    EVP_DigestUpdate(ctx, (unsigned char*) (bufferBytes + offset), length);
-    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
-  
-    throwExceptionIfNecessary(env);
-}
-
-/*
- * public static native void EVP_VerifyInit(int, java.lang.String)
- */
-static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
-    // LOGI("NativeCrypto_EVP_VerifyInit");
-    
-    if (ctx == NULL || algorithm == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return;
-    }
-    
-    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
-    
-    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
-    env->ReleaseStringUTFChars(algorithm, algorithmChars);
-    
-    if (digest == NULL) {
-        jniThrowRuntimeException(env, "Hash algorithm not found");
-        return;
-    }
-    
-    EVP_VerifyInit(ctx, digest);
-    
-    throwExceptionIfNecessary(env);
-}
-
-/*
- * public static native void EVP_VerifyUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) {
-    // LOGI("NativeCrypto_EVP_VerifyUpdate %x, %x, %d, %d", ctx, buffer, offset, length);
-    
-    if (ctx == NULL || buffer == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return;
-    }
-  
-    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
-    EVP_VerifyUpdate(ctx, (unsigned char*) (bufferBytes + offset), length);
-    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
-  
-    throwExceptionIfNecessary(env);
-}
-
-/*
- * public static native void EVP_VerifyFinal(int, byte[], int, int, int)
- */
-static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length, EVP_PKEY* pkey) {
-    // LOGI("NativeCrypto_EVP_VerifyFinal %x, %x, %d, %d %x", ctx, buffer, offset, length, pkey);
-    
-    if (ctx == NULL || buffer == NULL || pkey == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return -1;
-    }
-  
-    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
-    int result = EVP_VerifyFinal(ctx, (unsigned char*) (bufferBytes + offset), length, pkey);
-    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
-  
-    throwExceptionIfNecessary(env);
-    
-    return result;
-}
-
-/*
- * Defines the mapping from Java methods and their signatures
- * to native functions. Order is (1) Java name, (2) signature,
- * (3) pointer to C function.
- */
-static JNINativeMethod sNativeCryptoMethods[] = {
-    { "EVP_PKEY_new_DSA",    "([B[B[B[B[B)I", (void*)NativeCrypto_EVP_PKEY_new_DSA },
-    { "EVP_PKEY_new_RSA",    "([B[B[B[B[B)I", (void*)NativeCrypto_EVP_PKEY_new_RSA },
-    { "EVP_PKEY_free",       "(I)V",          (void*)NativeCrypto_EVP_PKEY_free },
-    { "EVP_new",             "()I",           (void*)NativeCrypto_EVP_new },
-    { "EVP_free",            "(I)V",          (void*)NativeCrypto_EVP_free },
-    { "EVP_DigestFinal",     "(I[BI)I",       (void*)NativeCrypto_EVP_DigestFinal },
-    { "EVP_DigestInit",      "(ILjava/lang/String;)V", (void*)NativeCrypto_EVP_DigestInit },
-    { "EVP_DigestBlockSize", "(I)I",          (void*)NativeCrypto_EVP_DigestBlockSize },
-    { "EVP_DigestSize",      "(I)I",          (void*)NativeCrypto_EVP_DigestSize },
-    { "EVP_DigestUpdate",    "(I[BII)V",      (void*)NativeCrypto_EVP_DigestUpdate },
-    { "EVP_VerifyInit",      "(ILjava/lang/String;)V", (void*)NativeCrypto_EVP_VerifyInit },
-    { "EVP_VerifyUpdate",    "(I[BII)V",      (void*)NativeCrypto_EVP_VerifyUpdate },
-    { "EVP_VerifyFinal",     "(I[BIII)I",     (void*)NativeCrypto_EVP_VerifyFinal }
-};
-
-/**
- * Module scope variables initialized during JNI registration.
- */
-static jfieldID field_Socket_ssl_ctx;
-static jfieldID field_Socket_ssl;
-static jfieldID field_FileDescriptor_descriptor;
-static jfieldID field_Socket_mImpl;
-static jfieldID field_Socket_mFD;
-static jfieldID field_Socket_timeout;
-
-/**
- * Gets the chars of a String object as a '\0'-terminated UTF-8 string,
- * stored in a freshly-allocated BIO memory buffer.
- */
-static BIO *stringToMemBuf(JNIEnv* env, jstring string) {
-    jsize byteCount = env->GetStringUTFLength(string);
-    LocalArray<1024> buf(byteCount + 1);
-    env->GetStringUTFRegion(string, 0, env->GetStringLength(string), &buf[0]);
-
-    BIO* result = BIO_new(BIO_s_mem());
-    BIO_puts(result, &buf[0]);
-    return result;
-}
 
 /**
  * Throws an SocketTimeoutException with the given string as a message.
@@ -423,7 +101,7 @@
 /**
  * Throws an IOException with a message constructed from the current
  * SSL errors. This will also log the errors.
- * 
+ *
  * @param env the JNI environment
  * @param sslReturnCode return code from failing SSL function
  * @param sslErrorCode error code returned from SSL_get_error()
@@ -435,7 +113,7 @@
     char* str;
     int ret;
 
-    // First consult the SSL error code for the general message. 
+    // First consult the SSL error code for the general message.
     switch (sslErrorCode) {
         case SSL_ERROR_NONE:
             messageStr = "Ok";
@@ -511,7 +189,7 @@
             free(allocStr);
             allocStr = str;
         }
-    // For errors during system calls, errno might be our friend.        
+    // For errors during system calls, errno might be our friend.
     } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
         if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
             free(allocStr);
@@ -533,21 +211,20 @@
 }
 
 /**
- * Helper function that grabs the ssl pointer out of the given object.
+ * Helper function that grabs the casts an ssl pointer and then checks for nullness.
  * If this function returns NULL and <code>throwIfNull</code> is
  * passed as <code>true</code>, then this function will call
  * <code>throwIOExceptionStr</code> before returning, so in this case of
  * NULL, a caller of this function should simply return and allow JNI
  * to do its thing.
- * 
- * @param env non-null; the JNI environment
- * @param obj non-null; socket object
+ *
+ * @param env the JNI environment
+ * @param ssl_address; the ssl_address pointer as an integer
  * @param throwIfNull whether to throw if the SSL pointer is NULL
  * @returns the pointer, which may be NULL
  */
-static SSL *getSslPointer(JNIEnv* env, jobject obj, bool throwIfNull) {
-    SSL *ssl = (SSL *)env->GetIntField(obj, field_Socket_ssl);
-
+static SSL* getSslPointer(JNIEnv* env, int ssl_address, bool throwIfNull) {
+    SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
     if ((ssl == NULL) && throwIfNull) {
         throwIOExceptionStr(env, "null SSL pointer");
     }
@@ -555,9 +232,19 @@
     return ssl;
 }
 
-// ============================================================================
-// === OpenSSL-related helper stuff begins here. ==============================
-// ============================================================================
+/**
+ * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
+ * fly.
+ */
+static BIGNUM* arrayToBignum(JNIEnv* env, jbyteArray source) {
+    // LOGD("Entering arrayToBignum()");
+
+    jbyte* sourceBytes = env->GetByteArrayElements(source, NULL);
+    int sourceLength = env->GetArrayLength(source);
+    BIGNUM* bignum = BN_bin2bn((unsigned char*) sourceBytes, sourceLength, NULL);
+    env->ReleaseByteArrayElements(source, sourceBytes, JNI_ABORT);
+    return bignum;
+}
 
 /**
  * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
@@ -626,59 +313,611 @@
     return 1;
 }
 
-int get_socket_timeout(int type, int sd) {
-    struct timeval tv;
-    socklen_t len = sizeof(tv);
-    if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
-         LOGE("getsockopt(%d, SOL_SOCKET): %s (%d)",
-              sd,
-              strerror(errno),
-              errno);
-        return 0;         
+/**
+ * Initialization phase for every OpenSSL job: Loads the Error strings, the
+ * crypto algorithms and reset the OpenSSL library
+ */
+static void NativeCrypto_clinit(JNIEnv* env, jclass)
+{
+    SSL_load_error_strings();
+    ERR_load_crypto_strings();
+    SSL_library_init();
+    OpenSSL_add_all_algorithms();
+    THREAD_setup();
+}
+
+/**
+ * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g, byte[] pub_key, byte[] priv_key);
+ */
+static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass clazz, jbyteArray p, jbyteArray q, jbyteArray g, jbyteArray pub_key, jbyteArray priv_key) {
+    // LOGD("Entering EVP_PKEY_new_DSA()");
+
+    DSA* dsa = DSA_new();
+
+    dsa->p = arrayToBignum(env, p);
+    dsa->q = arrayToBignum(env, q);
+    dsa->g = arrayToBignum(env, g);
+    dsa->pub_key = arrayToBignum(env, pub_key);
+
+    if (priv_key != NULL) {
+        dsa->priv_key = arrayToBignum(env, priv_key);
     }
-    // LOGI("Current socket timeout (%d(s), %d(us))!",
-    //      (int)tv.tv_sec, (int)tv.tv_usec);
-    int timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
-    return timeout;
-}
 
-#ifdef TIMEOUT_DEBUG_SSL
-
-void print_socket_timeout(const char* name, int type, int sd) {
-    struct timeval tv;
-    int len = sizeof(tv);
-    if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
-         LOGE("getsockopt(%d, SOL_SOCKET, %s): %s (%d)",
-              sd,
-              name,
-              strerror(errno),
-              errno);
+    if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) {
+        DSA_free(dsa);
+        jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
+        return NULL;
     }
-    LOGI("Current socket %s is (%d(s), %d(us))!",
-          name, (int)tv.tv_sec, (int)tv.tv_usec);
+
+    EVP_PKEY* pkey = EVP_PKEY_new();
+    EVP_PKEY_assign_DSA(pkey, dsa);
+
+    return pkey;
 }
 
-void print_timeout(const char* method, SSL* ssl) {    
-    LOGI("SSL_get_default_timeout %d in %s", SSL_get_default_timeout(ssl), method);
-    int fd = SSL_get_fd(ssl);
-    print_socket_timeout("SO_RCVTIMEO", SO_RCVTIMEO, fd);
-    print_socket_timeout("SO_SNDTIMEO", SO_SNDTIMEO, fd);
+/**
+ * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
+ */
+static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass clazz, jbyteArray n, jbyteArray e, jbyteArray d, jbyteArray p, jbyteArray q) {
+    // LOGD("Entering EVP_PKEY_new_RSA()");
+
+    RSA* rsa = RSA_new();
+
+    rsa->n = arrayToBignum(env, n);
+    rsa->e = arrayToBignum(env, e);
+
+    if (d != NULL) {
+        rsa->d = arrayToBignum(env, d);
+    }
+
+    if (p != NULL) {
+        rsa->p = arrayToBignum(env, p);
+    }
+
+    if (q != NULL) {
+        rsa->q = arrayToBignum(env, q);
+    }
+
+    // int check = RSA_check_key(rsa);
+    // LOGI("RSA_check_key returns %d", check);
+
+    if (rsa->n == NULL || rsa->e == NULL) {
+        RSA_free(rsa);
+        jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
+        return NULL;
+    }
+
+    EVP_PKEY* pkey = EVP_PKEY_new();
+    EVP_PKEY_assign_RSA(pkey, rsa);
+
+    return pkey;
 }
 
+/**
+ * private static native void EVP_PKEY_free(int pkey);
+ */
+static void NativeCrypto_EVP_PKEY_free(JNIEnv* env, jclass clazz, EVP_PKEY* pkey) {
+    // LOGD("Entering EVP_PKEY_free()");
+
+    if (pkey != NULL) {
+        EVP_PKEY_free(pkey);
+    }
+}
+
+/*
+ * public static native int EVP_new()
+ */
+static jint NativeCrypto_EVP_new(JNIEnv* env, jclass clazz) {
+    // LOGI("NativeCrypto_EVP_DigestNew");
+
+    return (jint)EVP_MD_CTX_create();
+}
+
+/*
+ * public static native void EVP_free(int)
+ */
+static void NativeCrypto_EVP_free(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
+    // LOGI("NativeCrypto_EVP_DigestFree");
+
+    if (ctx != NULL) {
+        EVP_MD_CTX_destroy(ctx);
+    }
+}
+
+/*
+ * public static native int EVP_DigestFinal(int, byte[], int)
+ */
+static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray hash, jint offset) {
+    // LOGI("NativeCrypto_EVP_DigestFinal%x, %x, %d, %d", ctx, hash, offset);
+
+    if (ctx == NULL || hash == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return -1;
+    }
+
+    int result = -1;
+
+    jbyte* hashBytes = env->GetByteArrayElements(hash, NULL);
+    EVP_DigestFinal(ctx, (unsigned char*) (hashBytes + offset), (unsigned int*)&result);
+    env->ReleaseByteArrayElements(hash, hashBytes, 0);
+
+    throwExceptionIfNecessary(env);
+
+    return result;
+}
+
+/*
+ * public static native void EVP_DigestInit(int, java.lang.String)
+ */
+static void NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
+    // LOGI("NativeCrypto_EVP_DigestInit");
+
+    if (ctx == NULL || algorithm == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+
+    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
+
+    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
+    env->ReleaseStringUTFChars(algorithm, algorithmChars);
+
+    if (digest == NULL) {
+        jniThrowRuntimeException(env, "Hash algorithm not found");
+        return;
+    }
+
+    EVP_DigestInit(ctx, digest);
+
+    throwExceptionIfNecessary(env);
+}
+
+/*
+ * public static native void EVP_DigestSize(int)
+ */
+static jint NativeCrypto_EVP_DigestSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
+    // LOGI("NativeCrypto_EVP_DigestSize");
+
+    if (ctx == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return -1;
+    }
+
+    int result = EVP_MD_CTX_size(ctx);
+
+    throwExceptionIfNecessary(env);
+
+    return result;
+}
+
+/*
+ * public static native void EVP_DigestBlockSize(int)
+ */
+static jint NativeCrypto_EVP_DigestBlockSize(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx) {
+    // LOGI("NativeCrypto_EVP_DigestBlockSize");
+
+    if (ctx == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return -1;
+    }
+
+    int result = EVP_MD_CTX_block_size(ctx);
+
+    throwExceptionIfNecessary(env);
+
+    return result;
+}
+
+/*
+ * public static native void EVP_DigestUpdate(int, byte[], int, int)
+ */
+static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) {
+    // LOGI("NativeCrypto_EVP_DigestUpdate %x, %x, %d, %d", ctx, buffer, offset, length);
+
+    if (ctx == NULL || buffer == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+
+    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
+    EVP_DigestUpdate(ctx, (unsigned char*) (bufferBytes + offset), length);
+    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
+
+    throwExceptionIfNecessary(env);
+}
+
+/*
+ * public static native void EVP_VerifyInit(int, java.lang.String)
+ */
+static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jstring algorithm) {
+    // LOGI("NativeCrypto_EVP_VerifyInit");
+
+    if (ctx == NULL || algorithm == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+
+    const char* algorithmChars = env->GetStringUTFChars(algorithm, NULL);
+
+    const EVP_MD *digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars));
+    env->ReleaseStringUTFChars(algorithm, algorithmChars);
+
+    if (digest == NULL) {
+        jniThrowRuntimeException(env, "Hash algorithm not found");
+        return;
+    }
+
+    EVP_VerifyInit(ctx, digest);
+
+    throwExceptionIfNecessary(env);
+}
+
+/*
+ * public static native void EVP_VerifyUpdate(int, byte[], int, int)
+ */
+static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length) {
+    // LOGI("NativeCrypto_EVP_VerifyUpdate %x, %x, %d, %d", ctx, buffer, offset, length);
+
+    if (ctx == NULL || buffer == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return;
+    }
+
+    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
+    EVP_VerifyUpdate(ctx, (unsigned char*) (bufferBytes + offset), length);
+    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
+
+    throwExceptionIfNecessary(env);
+}
+
+/*
+ * public static native void EVP_VerifyFinal(int, byte[], int, int, int)
+ */
+static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass clazz, EVP_MD_CTX* ctx, jbyteArray buffer, jint offset, jint length, EVP_PKEY* pkey) {
+    // LOGI("NativeCrypto_EVP_VerifyFinal %x, %x, %d, %d %x", ctx, buffer, offset, length, pkey);
+
+    if (ctx == NULL || buffer == NULL || pkey == NULL) {
+        jniThrowNullPointerException(env, NULL);
+        return -1;
+    }
+
+    jbyte* bufferBytes = env->GetByteArrayElements(buffer, NULL);
+    int result = EVP_VerifyFinal(ctx, (unsigned char*) (bufferBytes + offset), length, pkey);
+    env->ReleaseByteArrayElements(buffer, bufferBytes, JNI_ABORT);
+
+    throwExceptionIfNecessary(env);
+
+    return result;
+}
+
+/**
+ * Convert ssl version constant to string. Based on SSL_get_version
+ */
+static const char* get_ssl_version(int ssl_version) {
+    switch (ssl_version) {
+        // newest to oldest
+        case TLS1_VERSION: {
+          return SSL_TXT_TLSV1;
+        }
+        case SSL3_VERSION: {
+          return SSL_TXT_SSLV3;
+        }
+        case SSL2_VERSION: {
+          return SSL_TXT_SSLV2;
+        }
+        default: {
+          return "unknown";
+        }
+    }
+}
+
+/**
+ * Convert content type constant to string.
+ */
+static const char* get_content_type(int content_type) {
+    switch (content_type) {
+        case SSL3_RT_CHANGE_CIPHER_SPEC: {
+            return "SSL3_RT_CHANGE_CIPHER_SPEC";
+        }
+        case SSL3_RT_ALERT: {
+            return "SSL3_RT_ALERT";
+        }
+        case SSL3_RT_HANDSHAKE: {
+            return "SSL3_RT_HANDSHAKE";
+        }
+        case SSL3_RT_APPLICATION_DATA: {
+            return "SSL3_RT_APPLICATION_DATA";
+        }
+        default: {
+            LOGD("Unknown TLS/SSL content type %d", content_type);
+            return "<unknown>";
+        }
+    }
+}
+
+/**
+ * Simple logging call back to show hand shake messages
+ */
+static void ssl_msg_callback_LOG(int write_p, int ssl_version, int content_type,
+                                 const void *buf, size_t len, SSL* ssl, void* arg) {
+    LOGD("SSL %p %s %s %s %p %d %p",
+         ssl,
+         (write_p) ? "send" : "recv",
+         get_ssl_version(ssl_version),
+         get_content_type(content_type),
+         buf,
+         len,
+         arg);
+}
+
+/*
+ * public static native int SSL_CTX_new();
+ */
+static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass clazz) {
+    SSL_CTX* sslCtx = SSL_CTX_new(SSLv23_method());
+    // Note: We explicitly do not allow SSLv2 to be used.
+    SSL_CTX_set_options(sslCtx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
+
+    int mode = SSL_CTX_get_mode(sslCtx);
+    /*
+     * Turn on "partial write" mode. This means that SSL_write() will
+     * behave like Posix write() and possibly return after only
+     * writing a partial buffer. Note: The alternative, perhaps
+     * surprisingly, is not that SSL_write() always does full writes
+     * but that it will force you to retry write calls having
+     * preserved the full state of the original call. (This is icky
+     * and undesirable.)
+     */
+    mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
+#if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
+    mode |= SSL_MODE_SMALL_BUFFERS;  /* lazily allocate record buffers; usually saves
+                                      * 44k over the default */
 #endif
+#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) /* not all SSL versions have this */
+    mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;  /* enable sending of client data as soon as
+                                             * ClientCCS and ClientFinished are sent */
+#endif
+    SSL_CTX_set_mode(sslCtx, mode);
+
+    // SSL_CTX_set_msg_callback(sslCtx, ssl_msg_callback_LOG); /* enable for handshake debug */
+    return (jint) sslCtx;
+}
+
+static jobjectArray makeCipherList(JNIEnv* env, STACK_OF(SSL_CIPHER)* cipher_list) {
+    // Create a String[].
+    jclass stringClass = env->FindClass("java/lang/String");
+    if (stringClass == NULL) {
+        return NULL;
+    }
+    int cipherCount = sk_SSL_CIPHER_num(cipher_list);
+    jobjectArray array = env->NewObjectArray(cipherCount, stringClass, NULL);
+    if (array == NULL) {
+        return NULL;
+    }
+
+    // Fill in the cipher names.
+    for (int i = 0; i < cipherCount; ++i) {
+        const char* c = sk_SSL_CIPHER_value(cipher_list, i)->name;
+        env->SetObjectArrayElement(array, i, env->NewStringUTF(c));
+    }
+    return array;
+}
+
+/**
+ * Loads the ciphers suites that are supported by an SSL_CTX
+ * and returns them in a string array.
+ */
+static jobjectArray NativeCrypto_SSL_CTX_get_ciphers(JNIEnv* env,
+        jclass, jint ssl_ctx_address)
+{
+    SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
+    if (ssl_ctx == NULL) {
+        jniThrowNullPointerException(env, "SSL_CTX is null");
+        return NULL;
+    }
+    return makeCipherList(env, ssl_ctx->cipher_list);
+}
+
+/**
+ * public static native void SSL_CTX_free(int ssl_ctx)
+ */
+static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
+        jclass, jint ssl_ctx_address)
+{
+    SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
+    if (ssl_ctx == NULL) {
+        jniThrowNullPointerException(env, "SSL_CTX is null");
+        return;
+    }
+    SSL_CTX_free(ssl_ctx);
+}
+
+/**
+ * Gets the chars of a String object as a '\0'-terminated UTF-8 string,
+ * stored in a freshly-allocated BIO memory buffer.
+ */
+static BIO *stringToMemBuf(JNIEnv* env, jstring string) {
+    jsize byteCount = env->GetStringUTFLength(string);
+    LocalArray<1024> buf(byteCount + 1);
+    env->GetStringUTFRegion(string, 0, env->GetStringLength(string), &buf[0]);
+
+    BIO* result = BIO_new(BIO_s_mem());
+    BIO_puts(result, &buf[0]);
+    return result;
+}
+
+/**
+ * public static native int SSL_new(int ssl_ctx, String privatekey, String certificate, byte[] seed) throws IOException;
+ */
+static jint NativeCrypto_SSL_new(JNIEnv* env, jclass,
+        jint ssl_ctx_address, jstring privatekey, jstring certificates, jbyteArray seed)
+{
+    SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
+    if (ssl_ctx == NULL) {
+        jniThrowNullPointerException(env, "SSL_CTX is null");
+        return 0;
+    }
+
+    // 'seed == null' when no SecureRandom Object is set
+    // in the SSLContext.
+    if (seed != NULL) {
+        jbyte* randseed = env->GetByteArrayElements(seed, NULL);
+        RAND_seed((unsigned char*) randseed, 1024);
+        env->ReleaseByteArrayElements(seed, randseed, 0);
+    } else {
+        RAND_load_file("/dev/urandom", 1024);
+    }
+
+    SSL* ssl = SSL_new(ssl_ctx);
+    if (ssl == NULL) {
+        throwIOExceptionWithSslErrors(env, 0, 0,
+                "Unable to create SSL structure");
+        return NULL;
+    }
+
+    /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
+     * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
+     * (by default disabled), the server will send a certificate which will
+     * be checked. The result of the certificate verification process can be
+     * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
+     * function. The handshake will be continued regardless of the
+     * verification result.
+     */
+    SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
+
+    if (privatekey != NULL) {
+        BIO* privatekeybio = stringToMemBuf(env, (jstring) privatekey);
+        EVP_PKEY* privatekeyevp =
+          PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL);
+        BIO_free(privatekeybio);
+
+        if (privatekeyevp == NULL) {
+            LOGE(ERR_error_string(ERR_get_error(), NULL));
+            throwIOExceptionWithSslErrors(env, 0, 0,
+                    "Error parsing the private key");
+            SSL_free(ssl);
+            return NULL;
+        }
+
+        BIO* certificatesbio = stringToMemBuf(env, (jstring) certificates);
+        X509* certificatesx509 =
+          PEM_read_bio_X509(certificatesbio, NULL, 0, NULL);
+        BIO_free(certificatesbio);
+
+        if (certificatesx509 == NULL) {
+            LOGE(ERR_error_string(ERR_get_error(), NULL));
+            throwIOExceptionWithSslErrors(env, 0, 0,
+                    "Error parsing the certificates");
+            EVP_PKEY_free(privatekeyevp);
+            SSL_free(ssl);
+            return NULL;
+        }
+
+        int ret = SSL_use_certificate(ssl, certificatesx509);
+        if (ret != 1) {
+            LOGE(ERR_error_string(ERR_get_error(), NULL));
+            throwIOExceptionWithSslErrors(env, ret, 0,
+                    "Error setting the certificates");
+            X509_free(certificatesx509);
+            EVP_PKEY_free(privatekeyevp);
+            SSL_free(ssl);
+            return NULL;
+        }
+
+        ret = SSL_use_PrivateKey(ssl, privatekeyevp);
+        if (ret != 1) {
+            LOGE(ERR_error_string(ERR_get_error(), NULL));
+            throwIOExceptionWithSslErrors(env, ret, 0,
+                    "Error setting the private key");
+            X509_free(certificatesx509);
+            EVP_PKEY_free(privatekeyevp);
+            SSL_free(ssl);
+            return NULL;
+        }
+
+        ret = SSL_check_private_key(ssl);
+        if (ret != 1) {
+            throwIOExceptionWithSslErrors(env, ret, 0,
+                    "Error checking the private key");
+            X509_free(certificatesx509);
+            EVP_PKEY_free(privatekeyevp);
+            SSL_free(ssl);
+            return NULL;
+        }
+    }
+    return (jint)ssl;
+}
+
+/**
+ * public static native long SSL_get_options(int ssl);
+ */
+static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
+        jint ssl_address) {
+    SSL* ssl = getSslPointer(env, ssl_address, true);
+    if (ssl == NULL) {
+      return 0;
+    }
+    return SSL_get_options(ssl);
+}
+
+/**
+ * public static native long SSL_set_options(int ssl, long options);
+ */
+static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
+        jint ssl_address, jlong options) {
+    SSL* ssl = getSslPointer(env, ssl_address, true);
+    if (ssl == NULL) {
+      return 0 ;
+    }
+    return SSL_set_options(ssl, options);
+}
+
+/**
+ * Loads the ciphers suites that are enabled in the SSL
+ * and returns them in a string array.
+ */
+static jobjectArray NativeCrypto_SSL_get_ciphers(JNIEnv* env,
+        jclass, jint ssl_address)
+{
+    SSL* ssl = getSslPointer(env, ssl_address, true);
+    if (ssl == NULL) {
+      return NULL;
+    }
+    return makeCipherList(env, SSL_get_ciphers(ssl));
+}
+
+/**
+ * Sets the ciphers suites that are enabled in the SSL
+ */
+static void NativeCrypto_SSL_set_cipher_list(JNIEnv* env, jclass,
+        jint ssl_address, jstring controlString)
+{
+    SSL* ssl = getSslPointer(env, ssl_address, true);
+    if (ssl == NULL) {
+      return;
+    }
+    const char* str = env->GetStringUTFChars(controlString, NULL);
+    int rc = SSL_set_cipher_list(ssl, str);
+    env->ReleaseStringUTFChars(controlString, str);
+    if (rc == 0) {
+        freeSslErrorState();
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                          "Illegal cipher suite strings.");
+    }
+}
 
 /**
  * Our additional application data needed for getting synchronization right.
  * This maybe warrants a bit of lengthy prose:
- * 
+ *
  * (1) We use a flag to reflect whether we consider the SSL connection alive.
  * Any read or write attempt loops will be cancelled once this flag becomes 0.
- * 
+ *
  * (2) We use an int to count the number of threads that are blocked by the
  * underlying socket. This may be at most two (one reader and one writer), since
  * the Java layer ensures that no more threads will enter the native code at the
  * same time.
- * 
+ *
  * (3) The pipe is used primarily as a means of cancelling a blocking select()
  * when we want to close the connection (aka "emergency button"). It is also
  * necessary for dealing with a possible race condition situation: There might
@@ -687,23 +926,23 @@
  * If one leaves the select() successfully before the other enters it, the
  * "success" event is already consumed and the second thread will be blocked,
  * possibly forever (depending on network conditions).
- *  
+ *
  * The idea for solving the problem looks like this: Whenever a thread is
  * successful in moving around data on the network, and it knows there is
  * another thread stuck in a select(), it will write a byte to the pipe, waking
  * up the other thread. A thread that returned from select(), on the other hand,
  * knows whether it's been woken up by the pipe. If so, it will consume the
  * byte, and the original state of affairs has been restored.
- * 
+ *
  * The pipe may seem like a bit of overhead, but it fits in nicely with the
  * other file descriptors of the select(), so there's only one condition to wait
  * for.
- * 
+ *
  * (4) Finally, a mutex is needed to make sure that at most one thread is in
  * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
  * requirement. We use the same mutex to guard the field for counting the
  * waiting threads.
- * 
+ *
  * Note: The current implementation assumes that we don't have to deal with
  * problems induced by multiple cores or processors and their respective
  * memory caches. One possible problem is that of inconsistent views on the
@@ -712,7 +951,7 @@
  * currently this seems a bit like overkill.
  */
 typedef struct app_data {
-    int aliveAndKicking;
+    volatile int aliveAndKicking;
     int waitingThreads;
     int fdsEmergency[2];
     MUTEX_TYPE mutex;
@@ -720,7 +959,7 @@
 
 /**
  * Creates our application data and attaches it to a given SSL connection.
- * 
+ *
  * @param ssl The SSL connection to attach the data to.
  * @return 0 on success, -1 on failure.
  */
@@ -751,16 +990,16 @@
 
 /**
  * Destroys our application data, cleaning up everything in the process.
- * 
+ *
  * @param ssl The SSL connection to take the data from.
- */ 
+ */
 static void sslDestroyAppData(SSL* ssl) {
     APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
 
     if (data != NULL) {
         SSL_set_app_data(ssl, NULL);
 
-        data -> aliveAndKicking = 0;
+        data->aliveAndKicking = 0;
 
         if (data->fdsEmergency[0] != -1) {
             close(data->fdsEmergency[0]);
@@ -776,72 +1015,101 @@
     }
 }
 
-
 /**
- * Frees the SSL_CTX struct for the given instance.
+ * public static native void SSL_free(int ssl);
  */
-static void free_ssl_ctx(JNIEnv* env, jobject object) {
-    /*
-     * Preserve and restore the exception state around this call, so
-     * that GetIntField and SetIntField will operate without complaint.
-     */
-    jthrowable exception = env->ExceptionOccurred();
-
-    if (exception != NULL) {
-        env->ExceptionClear();
+static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jint ssl_address)
+{
+    SSL* ssl = getSslPointer(env, ssl_address, true);
+    if (ssl == NULL) {
+      return;
     }
-
-    SSL_CTX *ctx = (SSL_CTX *)env->GetIntField(object, field_Socket_ssl_ctx);
-
-    if (ctx != NULL) {
-        SSL_CTX_free(ctx);
-        env->SetIntField(object, field_Socket_ssl_ctx, (int) NULL);
-    }
-
-    if (exception != NULL) {
-        env->Throw(exception);
-    }
+    sslDestroyAppData(ssl);
+    SSL_free(ssl);
 }
 
-/**
- * Frees the SSL struct for the given instance.
+/*
+ * Defines the mapping from Java methods and their signatures
+ * to native functions. Order is (1) Java name, (2) signature,
+ * (3) pointer to C function.
  */
-static void free_ssl(JNIEnv* env, jobject object) {
-    /*
-     * Preserve and restore the exception state around this call, so
-     * that GetIntField and SetIntField will operate without complaint.
-     */
-    jthrowable exception = env->ExceptionOccurred();
-
-    if (exception != NULL) {
-        env->ExceptionClear();
-    }
-
-    SSL *ssl = (SSL *)env->GetIntField(object, field_Socket_ssl);
-
-    if (ssl != NULL) {
-        sslDestroyAppData(ssl);
-        SSL_free(ssl);
-        env->SetIntField(object, field_Socket_ssl, (int) NULL);
-    }
-
-    if (exception != NULL) {
-        env->Throw(exception);
-    }
-}
+static JNINativeMethod sNativeCryptoMethods[] = {
+    { "clinit",              "()V",           (void*)NativeCrypto_clinit},
+    { "EVP_PKEY_new_DSA",    "([B[B[B[B[B)I", (void*)NativeCrypto_EVP_PKEY_new_DSA },
+    { "EVP_PKEY_new_RSA",    "([B[B[B[B[B)I", (void*)NativeCrypto_EVP_PKEY_new_RSA },
+    { "EVP_PKEY_free",       "(I)V",          (void*)NativeCrypto_EVP_PKEY_free },
+    { "EVP_new",             "()I",           (void*)NativeCrypto_EVP_new },
+    { "EVP_free",            "(I)V",          (void*)NativeCrypto_EVP_free },
+    { "EVP_DigestFinal",     "(I[BI)I",       (void*)NativeCrypto_EVP_DigestFinal },
+    { "EVP_DigestInit",      "(ILjava/lang/String;)V", (void*)NativeCrypto_EVP_DigestInit },
+    { "EVP_DigestBlockSize", "(I)I",          (void*)NativeCrypto_EVP_DigestBlockSize },
+    { "EVP_DigestSize",      "(I)I",          (void*)NativeCrypto_EVP_DigestSize },
+    { "EVP_DigestUpdate",    "(I[BII)V",      (void*)NativeCrypto_EVP_DigestUpdate },
+    { "EVP_VerifyInit",      "(ILjava/lang/String;)V", (void*)NativeCrypto_EVP_VerifyInit },
+    { "EVP_VerifyUpdate",    "(I[BII)V",      (void*)NativeCrypto_EVP_VerifyUpdate },
+    { "EVP_VerifyFinal",     "(I[BIII)I",     (void*)NativeCrypto_EVP_VerifyFinal },
+    { "SSL_CTX_new",         "()I",           (void*)NativeCrypto_SSL_CTX_new },
+    { "SSL_CTX_get_ciphers", "(I)[Ljava/lang/String;", (void*)NativeCrypto_SSL_CTX_get_ciphers},
+    { "SSL_CTX_free",        "(I)V",          (void*)NativeCrypto_SSL_CTX_free },
+    { "SSL_new",             "(ILjava/lang/String;Ljava/lang/String;[B)I", (void*)NativeCrypto_SSL_new},
+    { "SSL_get_options",     "(I)J",          (void*)NativeCrypto_SSL_get_options },
+    { "SSL_set_options",     "(IJ)J",         (void*)NativeCrypto_SSL_set_options },
+    { "SSL_get_ciphers",     "(I)[Ljava/lang/String;", (void*)NativeCrypto_SSL_get_ciphers},
+    { "SSL_set_cipher_list", "(ILjava/lang/String;)V", (void*)NativeCrypto_SSL_set_cipher_list},
+    { "SSL_free",            "(I)V",          (void*)NativeCrypto_SSL_free},
+};
 
 /**
- * Constructs the SSL struct for the given instance, replacing one
- * that was already made, if any.
+ * Module scope variables initialized during JNI registration.
  */
-static SSL* create_ssl(JNIEnv* env, jobject object, SSL_CTX*  ssl_ctx) {
-    free_ssl(env, object);
+static jfieldID field_Socket_mImpl;
+static jfieldID field_Socket_mFD;
 
-    SSL *ssl = SSL_new(ssl_ctx);
-    env->SetIntField(object, field_Socket_ssl, (int) ssl);
-    return ssl;
+// ============================================================================
+// === OpenSSL-related helper stuff begins here. ==============================
+// ============================================================================
+
+int get_socket_timeout(int type, int sd) {
+    struct timeval tv;
+    socklen_t len = sizeof(tv);
+    if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
+         LOGE("getsockopt(%d, SOL_SOCKET): %s (%d)",
+              sd,
+              strerror(errno),
+              errno);
+        return 0;
+    }
+    // LOGI("Current socket timeout (%d(s), %d(us))!",
+    //      (int)tv.tv_sec, (int)tv.tv_usec);
+    int timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+    return timeout;
 }
 
+#ifdef TIMEOUT_DEBUG_SSL
+
+void print_socket_timeout(const char* name, int type, int sd) {
+    struct timeval tv;
+    int len = sizeof(tv);
+    if (getsockopt(sd, SOL_SOCKET, type, &tv, &len) < 0) {
+         LOGE("getsockopt(%d, SOL_SOCKET, %s): %s (%d)",
+              sd,
+              name,
+              strerror(errno),
+              errno);
+    }
+    LOGI("Current socket %s is (%d(s), %d(us))!",
+          name, (int)tv.tv_sec, (int)tv.tv_usec);
+}
+
+void print_timeout(const char* method, SSL* ssl) {
+    LOGI("SSL_get_default_timeout %d in %s", SSL_get_default_timeout(ssl), method);
+    int fd = SSL_get_fd(ssl);
+    print_socket_timeout("SO_RCVTIMEO", SO_RCVTIMEO, fd);
+    print_socket_timeout("SO_SNDTIMEO", SO_SNDTIMEO, fd);
+}
+
+#endif
+
 /**
  * Dark magic helper function that checks, for a given SSL session, whether it
  * can SSL_read() or SSL_write() without blocking. Takes into account any
@@ -851,15 +1119,15 @@
  * specifies whether we are waiting for readability or writability. It expects
  * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
  * only need to wait in case one of these problems occurs.
- * 
+ *
  * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
  * @param fd The file descriptor to wait for (the underlying socket)
- * @param data The application data structure with mutex info etc. 
+ * @param data The application data structure with mutex info etc.
  * @param timeout The timeout value for select call, with the special value
  *                0 meaning no timeout at all (wait indefinitely). Note: This is
  *                the Java semantics of the timeout value, not the usual
  *                select() semantics.
- * @return The result of the inner select() call, -1 on additional errors 
+ * @return The result of the inner select() call, -1 on additional errors
  */
 static int sslSelect(int type, int fd, APP_DATA *data, int timeout) {
     fd_set rfds;
@@ -888,16 +1156,16 @@
     } else {
         ptv = NULL;
     }
-    
+
     // LOGD("Doing select() for SSL_ERROR_WANT_%s...", type == SSL_ERROR_WANT_READ ? "READ" : "WRITE");
     int result = select(max + 1, &rfds, &wfds, NULL, ptv);
     // LOGD("Returned from select(), result is %d", result);
-    
+
     // Lock
     if (MUTEX_LOCK(data->mutex) == -1) {
         return -1;
     }
-    
+
     // If we have been woken up by the emergency pipe, there must be a token in
     // it. Thus we can safely read it (even in a blocking way).
     if (FD_ISSET(data->fdsEmergency[0], &rfds)) {
@@ -910,7 +1178,7 @@
     // Tell the world that there is now one thread less waiting for the
     // underlying network.
     data->waitingThreads--;
-    
+
     // Unlock
     MUTEX_UNLOCK(data->mutex);
     // LOGD("leave sslSelect");
@@ -921,8 +1189,8 @@
  * Helper function that wakes up a thread blocked in select(), in case there is
  * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
  * before closing the connection.
- * 
- * @param data The application data structure with mutex info etc. 
+ *
+ * @param data The application data structure with mutex info etc.
  */
 static void sslNotify(APP_DATA *data) {
     // Write a byte to the emergency pipe, so a concurrent select() can return.
@@ -940,7 +1208,7 @@
 /**
  * Helper function which does the actual reading. The Java layer guarantees that
  * at most one thread will enter this function at any given time.
- * 
+ *
  * @param ssl non-null; the SSL context
  * @param buf non-null; buffer to read into
  * @param len length of the buffer, in bytes
@@ -953,7 +1221,7 @@
         int* sslErrorCode, int timeout) {
 
     // LOGD("Entering sslRead, caller requests to read %d bytes...", len);
-    
+
     if (len == 0) {
         // Don't bother doing anything in this case.
         return 0;
@@ -961,7 +1229,7 @@
 
     int fd = SSL_get_fd(ssl);
     BIO *bio = SSL_get_rbio(ssl);
-    
+
     APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
 
     while (data->aliveAndKicking) {
@@ -973,7 +1241,7 @@
         }
 
         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
-        
+
         // LOGD("Doing SSL_Read()");
         int result = SSL_read(ssl, buf, len);
         int error = SSL_ERROR_NONE;
@@ -989,13 +1257,13 @@
         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved && data->waitingThreads > 0) {
             sslNotify(data);
         }
-        
+
         // If we are blocked by the underlying socket, tell the world that
         // there will be one more waiting thread now.
         if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
             data->waitingThreads++;
         }
-        
+
         // Unlock
         MUTEX_UNLOCK(data->mutex);
 
@@ -1010,7 +1278,7 @@
                 return -1;
             }
 
-            // Need to wait for availability of underlying layer, then retry. 
+            // Need to wait for availability of underlying layer, then retry.
             case SSL_ERROR_WANT_READ:
             case SSL_ERROR_WANT_WRITE: {
                 int selectResult = sslSelect(error, fd, data, timeout);
@@ -1021,7 +1289,7 @@
                 } else if (selectResult == 0) {
                     return THROW_SOCKETTIMEOUTEXCEPTION;
                 }
-                
+
                 break;
             }
 
@@ -1033,16 +1301,16 @@
                 if (result == 0) {
                     return -1;
                 }
-                
+
                 // System call has been interrupted. Simply retry.
                 if (errno == EINTR) {
                     break;
                 }
-                
+
                 // Note that for all other system call errors we fall through
-                // to the default case, which results in an Exception. 
+                // to the default case, which results in an Exception.
             }
-            
+
             // Everything else is basically an error.
             default: {
                 *sslReturnCode = result;
@@ -1051,14 +1319,14 @@
             }
         }
     }
-    
+
     return -1;
 }
 
 /**
  * Helper function which does the actual writing. The Java layer guarantees that
  * at most one thread will enter this function at any given time.
- * 
+ *
  * @param ssl non-null; the SSL context
  * @param buf non-null; buffer to write
  * @param len length of the buffer, in bytes
@@ -1069,29 +1337,29 @@
  */
 static int sslWrite(SSL* ssl, const char* buf, jint len, int* sslReturnCode,
         int* sslErrorCode) {
-  
+
     // LOGD("Entering sslWrite(), caller requests to write %d bytes...", len);
 
     if (len == 0) {
         // Don't bother doing anything in this case.
         return 0;
     }
-    
+
     int fd = SSL_get_fd(ssl);
     BIO *bio = SSL_get_wbio(ssl);
-    
+
     APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
-    
+
     int count = len;
-    
-    while(data->aliveAndKicking && len > 0) {
+
+    while (data->aliveAndKicking && len > 0) {
         errno = 0;
         if (MUTEX_LOCK(data->mutex) == -1) {
             return -1;
         }
-        
+
         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
-        
+
         // LOGD("Doing SSL_write() with %d bytes to go", len);
         int result = SSL_write(ssl, buf, len);
         int error = SSL_ERROR_NONE;
@@ -1107,15 +1375,15 @@
         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved && data->waitingThreads > 0) {
             sslNotify(data);
         }
-        
+
         // If we are blocked by the underlying socket, tell the world that
         // there will be one more waiting thread now.
         if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
             data->waitingThreads++;
         }
-        
+
         MUTEX_UNLOCK(data->mutex);
-        
+
         switch (error) {
              // Sucessfully write at least one byte.
             case SSL_ERROR_NONE: {
@@ -1128,7 +1396,7 @@
             case SSL_ERROR_ZERO_RETURN: {
                 return -1;
             }
-                
+
             // Need to wait for availability of underlying layer, then retry.
             // The concept of a write timeout doesn't really make sense, and
             // it's also not standard Java behavior, so we wait forever here.
@@ -1142,7 +1410,7 @@
                 } else if (selectResult == 0) {
                     return THROW_SOCKETTIMEOUTEXCEPTION;
                 }
-                
+
                 break;
             }
 
@@ -1154,16 +1422,16 @@
                 if (result == 0) {
                     return -1;
                 }
-                
+
                 // System call has been interrupted. Simply retry.
                 if (errno == EINTR) {
                     break;
                 }
-                
+
                 // Note that for all other system call errors we fall through
-                // to the default case, which results in an Exception. 
+                // to the default case, which results in an Exception.
             }
-            
+
             // Everything else is basically an error.
             default: {
                 *sslReturnCode = result;
@@ -1173,20 +1441,20 @@
         }
     }
     // LOGD("Successfully wrote %d bytes", count);
-    
+
     return count;
 }
 
 /**
  * Helper function that creates an RSA public key from two buffers containing
  * the big-endian bit representation of the modulus and the public exponent.
- * 
+ *
  * @param mod The data of the modulus
  * @param modLen The length of the modulus data
  * @param exp The data of the exponent
  * @param expLen The length of the exponent data
- * 
- * @return A pointer to the new RSA structure, or NULL on error 
+ *
+ * @return A pointer to the new RSA structure, or NULL on error
  */
 static RSA* rsaCreateKey(unsigned char* mod, int modLen, unsigned char* exp, int expLen) {
     // LOGD("Entering rsaCreateKey()");
@@ -1207,7 +1475,7 @@
 /**
  * Helper function that frees an RSA key. Just calls the corresponding OpenSSL
  * function.
- * 
+ *
  * @param rsa The pointer to the new RSA structure to free.
  */
 static void rsaFreeKey(RSA* rsa) {
@@ -1220,16 +1488,16 @@
 
 /**
  * Helper function that verifies a given RSA signature for a given message.
- * 
+ *
  * @param msg The message to verify
  * @param msgLen The length of the message
  * @param sig The signature to verify
  * @param sigLen The length of the signature
  * @param algorithm The name of the hash/sign algorithm to use, e.g. "RSA-SHA1"
  * @param rsa The RSA public key to use
- * 
+ *
  * @return 1 on success, 0 on failure, -1 on error (check SSL errors then)
- * 
+ *
  */
 static int rsaVerify(unsigned char* msg, unsigned int msgLen, unsigned char* sig,
                      unsigned int sigLen, char* algorithm, RSA* rsa) {
@@ -1248,7 +1516,7 @@
 
     EVP_MD_CTX ctx;
 
-    EVP_MD_CTX_init(&ctx);    
+    EVP_MD_CTX_init(&ctx);
     if (EVP_VerifyInit_ex(&ctx, type, NULL) == 0) {
         goto cleanup;
     }
@@ -1271,163 +1539,21 @@
 // ============================================================================
 
 /**
- * Initialization phase for every OpenSSL job: Loads the Error strings, the 
- * crypto algorithms and reset the OpenSSL library
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_initstatic(JNIEnv* env, jobject obj)
-{
-    SSL_load_error_strings();
-    ERR_load_crypto_strings();
-    SSL_library_init();
-    OpenSSL_add_all_algorithms();
-    THREAD_setup();
-}
-
-/**
- * Initialization phase for a socket with OpenSSL.  The server's private key
- * and X509 certificate are read and the Linux /dev/urandom file is loaded 
- * as RNG for the session keys.
- *  
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_init(JNIEnv* env, jobject object,
-        jstring privatekey, jstring certificates, jbyteArray seed)
-{   
-    SSL_CTX* ssl_ctx;
-
-    // 'seed == null' when no SecureRandom Object is set
-    // in the SSLContext.
-    if (seed != NULL) {
-        jbyte* randseed = env->GetByteArrayElements(seed, NULL);
-        RAND_seed((unsigned char*) randseed, 1024);
-        env->ReleaseByteArrayElements(seed, randseed, 0);
-    } else {
-        RAND_load_file("/dev/urandom", 1024);
-    }
-
-    ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-
-    // Note: We explicitly do not allow SSLv2 to be used. It
-    SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
-
-    /* Java code in class OpenSSLSocketImpl does the verification. Meaning of 
-     * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
-     * (by default disabled), the server will send a certificate which will 
-     * be checked. The result of the certificate verification process can be  
-     * checked after the TLS/SSL handshake using the SSL_get_verify_result(3) 
-     * function. The handshake will be continued regardless of the 
-     * verification result.    
-     */
-    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
-
-    int mode = SSL_CTX_get_mode(ssl_ctx);
-    /*
-     * Turn on "partial write" mode. This means that SSL_write() will
-     * behave like Posix write() and possibly return after only
-     * writing a partial buffer. Note: The alternative, perhaps
-     * surprisingly, is not that SSL_write() always does full writes
-     * but that it will force you to retry write calls having
-     * preserved the full state of the original call. (This is icky
-     * and undesirable.)
-     */
-    mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
-#if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
-    mode |= SSL_MODE_SMALL_BUFFERS;  /* lazily allocate record buffers; usually saves
-                                      * 44k over the default */
-#endif
-#if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) /* not all SSL versions have this */
-    mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;  /* enable sending of client data as soon as
-                                             * ClientCCS and ClientFinished are sent */
-#endif
-
-    SSL_CTX_set_mode(ssl_ctx, mode);
-
-    if (privatekey != NULL) {
-        BIO* privatekeybio = stringToMemBuf(env, (jstring) privatekey);
-        EVP_PKEY* privatekeyevp =
-          PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL);
-        BIO_free(privatekeybio);
-
-        if (privatekeyevp == NULL) {
-            throwIOExceptionWithSslErrors(env, 0, 0,
-                    "Error parsing the private key");
-            SSL_CTX_free(ssl_ctx);
-            return;
-        }
-
-        BIO* certificatesbio = stringToMemBuf(env, (jstring) certificates);
-        X509* certificatesx509 =
-          PEM_read_bio_X509(certificatesbio, NULL, 0, NULL);
-        BIO_free(certificatesbio);
-
-        if (certificatesx509 == NULL) {
-            throwIOExceptionWithSslErrors(env, 0, 0,
-                    "Error parsing the certificates");
-            EVP_PKEY_free(privatekeyevp);
-            SSL_CTX_free(ssl_ctx);
-            return;
-        }
-
-        int ret = SSL_CTX_use_certificate(ssl_ctx, certificatesx509);
-        if (ret != 1) {
-            throwIOExceptionWithSslErrors(env, ret, 0,
-                    "Error setting the certificates");
-            X509_free(certificatesx509);
-            EVP_PKEY_free(privatekeyevp);
-            SSL_CTX_free(ssl_ctx);
-            return;
-        }
-
-        ret = SSL_CTX_use_PrivateKey(ssl_ctx, privatekeyevp);
-        if (ret != 1) {
-            throwIOExceptionWithSslErrors(env, ret, 0,
-                    "Error setting the private key");
-            X509_free(certificatesx509);
-            EVP_PKEY_free(privatekeyevp);
-            SSL_CTX_free(ssl_ctx);
-            return;
-        }
-
-        ret = SSL_CTX_check_private_key(ssl_ctx);
-        if (ret != 1) {
-            throwIOExceptionWithSslErrors(env, ret, 0,
-                    "Error checking the private key");
-            X509_free(certificatesx509);
-            EVP_PKEY_free(privatekeyevp);
-            SSL_CTX_free(ssl_ctx);
-            return;
-        }
-    }
-
-    env->SetIntField(object, field_Socket_ssl_ctx, (int)ssl_ctx);
-}
-
-/**
  * A connection within an OpenSSL context is established. (1) A new socket is
- * constructed, (2) the TLS/SSL handshake with a server is initiated. 
+ * constructed, (2) the TLS/SSL handshake with a server is initiated.
  */
-static jboolean org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect(JNIEnv* env, jobject object,
-        jint ctx, jobject socketObject, jboolean client_mode, jint session)
+static jboolean org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect(JNIEnv* env, jclass,
+        jint ssl_address, jobject socketObject, jint timeout, jboolean client_mode, jint ssl_session_address)
 {
     // LOGD("ENTER connect");
-    int ret, fd;
-    SSL_CTX* ssl_ctx;
-    SSL* ssl;
-    SSL_SESSION* ssl_session;
-
-    ssl_ctx = (SSL_CTX*)env->GetIntField(object, field_Socket_ssl_ctx);
-
-    ssl = create_ssl(env, object, ssl_ctx);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
     if (ssl == NULL) {
-        throwIOExceptionWithSslErrors(env, 0, 0,
-                "Unable to create SSL structure");
-        free_ssl_ctx(env, object);
-        return (jboolean) false;
+      return (jboolean) false;
     }
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
 
     jobject socketImplObject = env->GetObjectField(socketObject, field_Socket_mImpl);
     if (socketImplObject == NULL) {
-        free_ssl(env, object);
-        free_ssl_ctx(env, object);
         throwIOExceptionStr(env,
             "couldn't get the socket impl from the socket");
         return (jboolean) false;
@@ -1435,30 +1561,25 @@
 
     jobject fdObject = env->GetObjectField(socketImplObject, field_Socket_mFD);
     if (fdObject == NULL) {
-        free_ssl(env, object);
-        free_ssl_ctx(env, object);
         throwIOExceptionStr(env,
             "couldn't get the file descriptor from the socket impl");
         return (jboolean) false;
     }
 
-    fd = jniGetFDFromFileDescriptor(env, fdObject);
+    int fd = jniGetFDFromFileDescriptor(env, fdObject);
 
-    ssl_session = (SSL_SESSION *) session;
-
-    ret = SSL_set_fd(ssl, fd);
+    int ret = SSL_set_fd(ssl, fd);
 
     if (ret != 1) {
         throwIOExceptionWithSslErrors(env, ret, 0,
                 "Error setting the file descriptor");
-        free_ssl(env, object);
-        free_ssl_ctx(env, object);
+        SSL_clear(ssl);
         return (jboolean) false;
     }
 
     if (ssl_session != NULL) {
+        // LOGD("Trying to reuse session %p", ssl_session);
         ret = SSL_set_session(ssl, ssl_session);
-
         if (ret != 1) {
             /*
              * Translate the error, and throw if it turns out to be a real
@@ -1468,8 +1589,7 @@
             if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
                 throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
                         "SSL session set");
-                free_ssl(env, object);
-                free_ssl_ctx(env, object);
+                SSL_clear(ssl);
                 return (jboolean) false;
             }
         }
@@ -1482,8 +1602,7 @@
     int mode = fcntl(fd, F_GETFL);
     if (mode == -1 || fcntl(fd, F_SETFL, mode | O_NONBLOCK) == -1) {
         throwIOExceptionStr(env, "Unable to make socket non blocking");
-        free_ssl(env, object);
-        free_ssl_ctx(env, object);
+        SSL_clear(ssl);
         return (jboolean) false;
     }
 
@@ -1492,19 +1611,15 @@
      */
     if (sslCreateAppData(ssl) == -1) {
         throwIOExceptionStr(env, "Unable to create application data");
-        free_ssl(env, object);
-        free_ssl_ctx(env, object);
+        SSL_clear(ssl);
         // TODO
         return (jboolean) false;
     }
-    
+
     APP_DATA* data = (APP_DATA*) SSL_get_app_data(ssl);
-    env->SetIntField(object, field_Socket_ssl, (int)ssl);
-    
-    int timeout = (int)env->GetIntField(object, field_Socket_timeout);
-    
+
     while (data->aliveAndKicking) {
-        errno = 0;        
+        errno = 0;
         ret = SSL_connect(ssl);
         if (ret == 1) {
             break;
@@ -1525,26 +1640,24 @@
             if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
                 data->waitingThreads++;
                 int selectResult = sslSelect(error, fd, data, timeout);
-                
+
                 if (selectResult == -1) {
                     throwIOExceptionWithSslErrors(env, -1, error,
                         "Connect error");
-                    free_ssl(env, object);
-                    free_ssl_ctx(env, object);
+                    SSL_clear(ssl);
                     return (jboolean) false;
                 } else if (selectResult == 0) {
                     throwSocketTimeoutException(env, "SSL handshake timed out");
+                    SSL_clear(ssl);
                     freeSslErrorState();
-                    free_ssl(env, object);
-                    free_ssl_ctx(env, object);
                     return (jboolean) false;
                 }
             } else {
                 LOGE("Unknown error %d during connect", error);
                 break;
             }
-        }        
-    } 
+        }
+    }
 
     if (ret != 1) {
         /*
@@ -1555,80 +1668,72 @@
         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
             throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
                     "SSL handshake failure");
-            free_ssl(env, object);
-            free_ssl_ctx(env, object);
+            SSL_clear(ssl);
             return (jboolean) false;
         }
     }
 
     if (ssl_session != NULL) {
         ret = SSL_session_reused(ssl);
-        // if (ret == 1) LOGD("A session was reused");
-        // else LOGD("A new session was negotiated");
+        // if (ret == 1) LOGD("Session %p was reused", ssl_session);
+        // else LOGD("Session %p was not reused, using new session %p", ssl_session, SSL_get_session(ssl));
         return (jboolean) ret;
     } else {
-        // LOGD("A new session was negotiated");
+        // LOGD("New session %p was negotiated", SSL_get_session(ssl));
         return (jboolean) 0;
     }
     // LOGD("LEAVE connect");
 }
 
-static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession(JNIEnv* env, jobject object,
+static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession(JNIEnv* env, jclass,
         jint jssl)
 {
-    return (jint) SSL_get1_session((SSL *) jssl);
+    return (jint) SSL_get1_session((SSL*) jssl);
 }
 
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept(JNIEnv* env, jobject object,
-        jobject socketObject, jint jssl_ctx, jboolean client_mode)
+static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept(JNIEnv* env, jclass,
+        jint ssl_address, jobject socketObject)
 {
-    int sd, ret;
-    BIO *bio;
-    SSL *ssl;
-    SSL_CTX *ssl_ctx;
-    jsse_ssl_app_data_t appdata;
+    SSL* serverSocketSsl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
+    if (serverSocketSsl == NULL) {
+        throwIOExceptionWithSslErrors(env, 0, 0,
+                "Unusable SSL structure");
+        return NULL;
+    }
 
-    ssl_ctx = (SSL_CTX *)jssl_ctx;
-
-    ssl = create_ssl(env, object, ssl_ctx);
+    SSL* ssl = SSL_dup(serverSocketSsl);
     if (ssl == NULL) {
         throwIOExceptionWithSslErrors(env, 0, 0,
                 "Unable to create SSL structure");
-        return;
+        return NULL;
     }
 
     jobject socketImplObject = env->GetObjectField(socketObject, field_Socket_mImpl);
     if (socketImplObject == NULL) {
-        free_ssl(env, object);
         throwIOExceptionStr(env, "couldn't get the socket impl from the socket");
-        return;
+        return NULL;
     }
 
     jobject fdObject = env->GetObjectField(socketImplObject, field_Socket_mFD);
     if (fdObject == NULL) {
-        free_ssl(env, object);
         throwIOExceptionStr(env, "couldn't get the file descriptor from the socket impl");
-        return;
+        return NULL;
     }
 
 
-    sd = jniGetFDFromFileDescriptor(env, fdObject);
+    int sd = jniGetFDFromFileDescriptor(env, fdObject);
 
-    bio = BIO_new_socket(sd, BIO_NOCLOSE);
-
-    /* The parameter client_mode must be 1 */
-    if (client_mode != 0)
-        client_mode = 1;
-    BIO_set_ssl_mode(bio, client_mode);
-
+    BIO* bio = BIO_new_socket(sd, BIO_NOCLOSE);
     SSL_set_bio(ssl, bio, bio);
 
     /*
-     * Fill in the appdata structure needed for the certificate callback and
-     * store this in the SSL application data slot.
+     * Fill in the stack allocated appdata structure needed for the
+     * certificate callback and store this in the SSL application data
+     * slot.
      */
+    jsse_ssl_app_data_t appdata;
     appdata.env = env;
-    appdata.object = object;
+    appdata.object = socketObject;
     SSL_set_app_data(ssl, &appdata);
 
     /*
@@ -1636,7 +1741,7 @@
      * Maybe we need to deal with all the special SSL error cases (WANT_*),
      * just like we do for SSL_connect(). But currently it is looking ok.
      */
-    ret = SSL_accept(ssl);
+    int ret = SSL_accept(ssl);
 
     /*
      * Clear the SSL application data slot again, so we can safely use it for
@@ -1660,8 +1765,8 @@
           throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
               "Trouble accepting connection");
     	}
-        free_ssl(env, object);
-        return;
+        SSL_clear(ssl);
+        return NULL;
     } else if (ret < 0) {
         /*
          * Translate the error and throw exception. We are sure it is an error
@@ -1670,8 +1775,8 @@
         int sslErrorCode = SSL_get_error(ssl, ret);
         throwIOExceptionWithSslErrors(env, ret, sslErrorCode,
                 "Trouble accepting connection");
-        free_ssl(env, object);
-        return;
+        SSL_clear(ssl);
+        return NULL;
     }
 
     /*
@@ -1682,8 +1787,8 @@
     int mode = fcntl(fd, F_GETFL);
     if (mode == -1 || fcntl(fd, F_SETFL, mode | O_NONBLOCK) == -1) {
         throwIOExceptionStr(env, "Unable to make socket non blocking");
-        free_ssl(env, object);
-        return;
+        SSL_clear(ssl);
+        return NULL;
     }
 
     /*
@@ -1691,126 +1796,11 @@
      */
     if (sslCreateAppData(ssl) == -1) {
         throwIOExceptionStr(env, "Unable to create application data");
-        free_ssl(env, object);
-        return;
-    }
-}
-
-/**
- * Loads the desired protocol for the OpenSSL client and enables it.  
- * For example SSL_OP_NO_TLSv1 means do not use TLS v. 1.
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols(JNIEnv* env, jobject object,
-        jlong protocol)
-{
-    if (protocol != 0x00000000L) {
-        if (protocol & SSL_OP_NO_SSLv3)
-            LOGD("SSL_OP_NO_SSLv3 is set");
-        if (protocol & SSL_OP_NO_TLSv1)
-            LOGD("SSL_OP_NO_TLSv1 is set");
-
-        SSL_CTX* ctx = (SSL_CTX*)env->GetIntField(object, field_Socket_ssl_ctx);
-        int options = SSL_CTX_get_options(ctx);
-        options |= protocol; // Note: SSLv2 disabled earlier.
-        SSL_CTX_set_options(ctx, options);
-    }
-}
-
-static jobjectArray makeCipherList(JNIEnv* env, SSL* ssl) {
-    STACK_OF(SSL_CIPHER)* cipher_list = SSL_get_ciphers(ssl);
-    // Count the ciphers.
-    int num = sk_SSL_CIPHER_num(cipher_list);
-    int cipherCount = 0;
-    for (int i = 0; i < num; ++i) {
-        SSL_CIPHER* cipher = sk_SSL_CIPHER_value(cipher_list, i);
-        if (strcmp(SSL_CIPHER_get_version(cipher), SSL_TXT_SSLV2) == 0) {
-            // openssl-1.0.0 includes duplicate names for SSLv2 and SSLv3 ciphers
-            continue;
-        }
-        ++cipherCount;
-    }
-
-    // Create a String[].
-    jclass stringClass = env->FindClass("java/lang/String");
-    if (stringClass == NULL) {
-        return NULL;
-    }
-    jobjectArray array = env->NewObjectArray(cipherCount, stringClass, NULL);
-    if (array == NULL) {
+        SSL_clear(ssl);
         return NULL;
     }
 
-    // Fill in the cipher names.
-    int cipherIndex = 0;
-    for (int i = 0; i < num; ++i) {
-        SSL_CIPHER* cipher = sk_SSL_CIPHER_value(cipher_list, i);
-        if (strcmp(SSL_CIPHER_get_version(cipher), SSL_TXT_SSLV2) == 0) {
-            continue;
-        }
-        env->SetObjectArrayElement(array, cipherIndex, env->NewStringUTF(cipher->name));
-        ++cipherIndex;
-    }
-    return array;
-}
-
-jobjectArray makeCipherList(JNIEnv* env, SSL_CTX* ssl_ctx) {
-    SSL* ssl = SSL_new(ssl_ctx);
-    if (ssl == NULL) {
-        return NULL;
-    }
-    jobjectArray result = makeCipherList(env, ssl);
-    SSL_free(ssl);
-    return result;
-}
-
-/**
- * Loads the ciphers suites that are supported by the OpenSSL client
- * and returns them in a string array.
- */
-static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites(JNIEnv* env,
-        jobject object)
-{
-    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-    if (ssl_ctx == NULL) {
-        return NULL;
-    }
-    jobjectArray result = makeCipherList(env, ssl_ctx);
-    SSL_CTX_free(ssl_ctx);
-    return result;
-}
-
-/**
- * Loads the ciphers suites that are enabled in the OpenSSL client
- * and returns them in a string array.
- */
-static jobjectArray OpenSSLSocketImpl_nativeGetEnabledCipherSuites(JNIEnv* env,
-        jclass, jint ssl_ctx_address)
-{
-    SSL_CTX* ssl_ctx =
-            reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
-    return makeCipherList(env, ssl_ctx);
-}
-
-void setEnabledCipherSuites(JNIEnv* env, jstring controlString, SSL_CTX* ssl_ctx) {
-    const char* str = env->GetStringUTFChars(controlString, NULL);
-    int rc = SSL_CTX_set_cipher_list(ssl_ctx, str);
-    env->ReleaseStringUTFChars(controlString, str);
-    if (rc == 0) {
-        freeSslErrorState();
-        jniThrowException(env, "java/lang/IllegalArgumentException",
-                          "Illegal cipher suite strings.");
-    }
-}
-
-/**
- * Sets the ciphers suites that are enabled in the OpenSSL client.
- */
-static void OpenSSLSocketImpl_nativeSetEnabledCipherSuites(JNIEnv* env, jclass,
-        jint ssl_ctx_address, jstring controlString)
-{
-    SSL_CTX* ssl_ctx =
-            reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
-    setEnabledCipherSuites(env, controlString, ssl_ctx);
+    return (jint) ssl;
 }
 
 #define SSL_aRSA                0x00000001L
@@ -1826,24 +1816,18 @@
  * Sets  the client's crypto algorithms and authentication methods.
  */
 static jstring org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod(JNIEnv* env,
-        jobject object)
+        jclass, jint ssl_address)
 {
-    SSL* ssl;
-    const SSL_CIPHER *cipher;
-    jstring ret;
-    char buf[512];
-    unsigned long alg_auth;
-    const char *au;
-
-    ssl = getSslPointer(env, object, true);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
     if (ssl == NULL) {
         return NULL;
     }
 
-    cipher = SSL_get_current_cipher(ssl);
+    const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl);
 
-    alg_auth = cipher->algorithm_auth;
+    unsigned long alg_auth = cipher->algorithm_auth;
 
+    const char *au;
     switch (alg_auth) {
         case SSL_aRSA:
             au="RSA";
@@ -1874,7 +1858,7 @@
             break;
     }
 
-    ret = env->NewStringUTF(au);
+    jstring ret = env->NewStringUTF(au);
 
     return ret;
 }
@@ -1882,9 +1866,9 @@
 /**
  * OpenSSL read function (1): only one chunk is read (returned as jint).
  */
-static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read(JNIEnv* env, jobject object, jint timeout)
+static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read(JNIEnv* env, jclass, jint ssl_address, jint timeout)
 {
-    SSL *ssl = getSslPointer(env, object, true);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
     if (ssl == NULL) {
         return 0;
     }
@@ -1914,12 +1898,12 @@
 }
 
 /**
- * OpenSSL read function (2): read into buffer at offset n chunks. 
+ * OpenSSL read function (2): read into buffer at offset n chunks.
  * Returns 1 (success) or value <= 0 (failure).
  */
-static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba(JNIEnv* env, jobject obj, jbyteArray dest, jint offset, jint len, jint timeout)
+static jint org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba(JNIEnv* env, jclass, jint ssl_address, jbyteArray dest, jint offset, jint len, jint timeout)
 {
-    SSL *ssl = getSslPointer(env, obj, true);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
     if (ssl == NULL) {
         return 0;
     }
@@ -1949,9 +1933,9 @@
 /**
  * OpenSSL write function (1): only one chunk is written.
  */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write(JNIEnv* env, jobject object, jint b)
+static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write(JNIEnv* env, jclass, jint ssl_address, jint b)
 {
-    SSL *ssl = getSslPointer(env, object, true);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
     if (ssl == NULL) {
         return;
     }
@@ -1971,12 +1955,12 @@
 }
 
 /**
- * OpenSSL write function (2): write into buffer at offset n chunks. 
+ * OpenSSL write function (2): write into buffer at offset n chunks.
  */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba(JNIEnv* env, jobject obj,
-        jbyteArray dest, jint offset, jint len)
+static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba(JNIEnv* env, jclass,
+        jint ssl_address, jbyteArray dest, jint offset, jint len)
 {
-    SSL *ssl = getSslPointer(env, obj, true);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
     if (ssl == NULL) {
         return;
     }
@@ -1984,8 +1968,7 @@
     jbyte* bytes = env->GetByteArrayElements(dest, NULL);
     int returnCode = 0;
     int errorCode = 0;
-    int timeout = (int)env->GetIntField(obj, field_Socket_timeout);
-    int ret = sslWrite(ssl, (const char *) (bytes + offset), len, 
+    int ret = sslWrite(ssl, (const char *) (bytes + offset), len,
             &returnCode, &errorCode);
 
     env->ReleaseByteArrayElements(dest, bytes, 0);
@@ -2000,11 +1983,11 @@
 }
 
 /**
- * Interrupt any pending IO before closing the socket. 
+ * Interrupt any pending IO before closing the socket.
  */
 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt(
-        JNIEnv* env, jobject object) {
-    SSL *ssl = getSslPointer(env, object, false);
+        JNIEnv* env, jclass, jint ssl_address) {
+    SSL* ssl = getSslPointer(env, ssl_address, false);
     if (ssl == NULL) {
         return;
     }
@@ -2024,11 +2007,11 @@
 }
 
 /**
- * OpenSSL close SSL socket function. 
+ * OpenSSL close SSL socket function.
  */
 static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close(
-        JNIEnv* env, jobject object) {
-    SSL *ssl = getSslPointer(env, object, false);
+        JNIEnv* env, jclass, jint ssl_address) {
+    SSL* ssl = getSslPointer(env, ssl_address, false);
     if (ssl == NULL) {
         return;
     }
@@ -2068,24 +2051,14 @@
              * Everything else is a real error condition. We should
              * let the Java layer know about this by throwing an
              * exception.
-             */ 
+             */
             int sslErrorCode = SSL_get_error(ssl, ret);
             throwIOExceptionWithSslErrors(env, ret, sslErrorCode, "SSL shutdown failed");
             break;
     }
 
+    SSL_clear(ssl);
     freeSslErrorState();
-    free_ssl(env, object);
-    free_ssl_ctx(env, object);
-}    
-
-/**
- * OpenSSL free SSL socket function. 
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_free(JNIEnv* env, jobject object)
-{
-    free_ssl(env, object);
-    free_ssl_ctx(env, object);
 }
 
 /**
@@ -2148,151 +2121,20 @@
 
 static JNINativeMethod sSocketImplMethods[] =
 {
-    {"nativeinitstatic", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_initstatic},
-    {"nativeinit", "(Ljava/lang/String;Ljava/lang/String;[B)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_init},
-    {"nativeconnect", "(ILjava/net/Socket;ZI)Z", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect},
+    {"nativeconnect", "(ILjava/net/Socket;IZI)Z", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_connect},
     {"nativegetsslsession", "(I)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsslsession},
-    {"nativeread", "(I)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read},
-    {"nativeread", "([BIII)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba},
-    {"nativewrite", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write},
-    {"nativewrite", "([BII)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba},
-    {"nativeaccept", "(Ljava/net/Socket;IZ)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept},
-    {"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_setenabledprotocols},
-    {"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_getsupportedciphersuites},
-    {"nativeGetEnabledCipherSuites", "(I)[Ljava/lang/String;", (void*) OpenSSLSocketImpl_nativeGetEnabledCipherSuites},
-    {"nativeSetEnabledCipherSuites", "(ILjava/lang/String;)V", (void*) OpenSSLSocketImpl_nativeSetEnabledCipherSuites},
-    {"nativecipherauthenticationmethod", "()Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod},
-    {"nativeinterrupt", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt},
-    {"nativeclose", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close},
-    {"nativefree", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_free},
+    {"nativeread", "(II)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_read},
+    {"nativeread", "(I[BIII)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_readba},
+    {"nativewrite", "(II)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_write},
+    {"nativewrite", "(I[BII)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_writeba},
+    {"nativeaccept", "(ILjava/net/Socket;)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_accept},
+    {"nativecipherauthenticationmethod", "(I)Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_cipherauthenticationmethod},
+    {"nativeinterrupt", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_interrupt},
+    {"nativeclose", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_close},
     {"nativeverifysignature", "([B[BLjava/lang/String;[B[B)I", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLSocketImpl_verifysignature},
 };
 
 /**
- * Module scope variables initialized during JNI registration.
- */
-static jfieldID field_ServerSocket_ssl_ctx;
-
-/**
- * Initialization phase of OpenSSL: Loads the Error strings, the crypto algorithms and reset the OpenSSL library
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_initstatic(JNIEnv* env, jobject obj)
-{
-    SSL_load_error_strings();
-    ERR_load_crypto_strings();
-    SSL_library_init();
-    OpenSSL_add_all_algorithms();
-}
-
-/**
- * Initialization phase for a server socket with OpenSSL.  The server's private key and X509 certificate are read and  
- * the Linux /dev/random file is loaded as RNG for the session keys.
- *  
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_init(JNIEnv* env, jobject object,
-        jstring privatekey, jstring certificates, jbyteArray seed)
-{
-    SSL_CTX *ssl_ctx;
-    const char *privatekeychar;
-    const char *certificateschar;
-    EVP_PKEY * privatekeyevp;
-
-    BIO *privatekeybio;
-    BIO *certificatesbio;
-
-    // 'seed == null' when no SecureRandom Object is set
-    // in the SSLContext.
-    if (seed != NULL) {
-        jbyte* randseed = env->GetByteArrayElements(seed, NULL);
-        RAND_seed((unsigned char*) randseed, 1024);
-        env->ReleaseByteArrayElements(seed, randseed, 0);
-    } else {
-        RAND_load_file("/dev/urandom", 1024);
-    }
-
-    ssl_ctx = SSL_CTX_new(SSLv23_server_method());
-    SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2);
-
-    privatekeychar = env->GetStringUTFChars((jstring)privatekey, NULL);
-    privatekeybio = BIO_new_mem_buf((void*)privatekeychar, -1);
-
-    privatekeyevp = PEM_read_bio_PrivateKey(privatekeybio, NULL, 0, NULL);
-    env->ReleaseStringUTFChars(privatekey, privatekeychar);
-
-    if (privatekeyevp == NULL) {
-        LOGE(ERR_error_string(ERR_get_error(), NULL));
-        throwIOExceptionStr(env, "Error parsing the private key");
-        return;
-    }
-
-    certificateschar = env->GetStringUTFChars((jstring)certificates, NULL);
-    certificatesbio = BIO_new_mem_buf((void*)certificateschar, -1);
-
-    X509 * certificatesx509 = PEM_read_bio_X509(certificatesbio, NULL, 0, NULL);
-    env->ReleaseStringUTFChars(certificates, certificateschar);
-
-    if (certificatesx509 == NULL) {
-        LOGE(ERR_error_string(ERR_get_error(), NULL));
-        throwIOExceptionStr(env, "Error parsing the certificates");
-        return;
-    }
-
-    if (!SSL_CTX_use_certificate(ssl_ctx, certificatesx509)) {
-        LOGE(ERR_error_string(ERR_get_error(), NULL));
-        throwIOExceptionStr(env, "Error setting the certificates");
-        return;
-    }
-
-    if (!SSL_CTX_use_PrivateKey(ssl_ctx, privatekeyevp)) {
-        LOGE(ERR_error_string(ERR_get_error(), NULL));
-        throwIOExceptionStr(env, "Error setting the private key");
-        return;
-    }
-
-    if (!SSL_CTX_check_private_key(ssl_ctx)) {
-        LOGE(ERR_error_string(ERR_get_error(), NULL));
-        throwIOExceptionStr(env, "Error checking private key");
-        return;
-    }
-
-    env->SetIntField(object, field_ServerSocket_ssl_ctx, (int)ssl_ctx);
-}
-
-/**
- * Loads the desired protocol for the OpenSSL server and enables it.  
- * For example SSL_OP_NO_TLSv1 means do not use TLS v. 1.
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledprotocols(JNIEnv* env,
-        jobject object, jlong protocol)
-{
-    if (protocol != 0x00000000L) {
-        if (protocol & SSL_OP_NO_SSLv3)
-            LOGD("SSL_OP_NO_SSLv3 is set");
-        if (protocol & SSL_OP_NO_TLSv1)
-            LOGD("SSL_OP_NO_TLSv1 is set");
-
-        SSL_CTX* ctx = (SSL_CTX*)env->GetIntField(object, field_ServerSocket_ssl_ctx);
-        SSL_CTX_set_options((SSL_CTX*)ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2|(long)protocol);
-    }
-}
-
-/**
- * Loads the ciphers suites that are supported by the OpenSSL server
- * and returns them in a string array.
- */
-static jobjectArray org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getsupportedciphersuites(JNIEnv* env,
-        jobject object)
-{
-    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_server_method());
-    if (ssl_ctx == NULL) {
-        return NULL;
-    }
-    jobjectArray result = makeCipherList(env, ssl_ctx);
-    SSL_CTX_free(ssl_ctx);
-    return result;
-}
-
-/**
  * Gives an array back containing all the X509 certificate's bytes.
  */
 static jobjectArray getcertificatebytes(JNIEnv* env,
@@ -2356,79 +2198,64 @@
  */
 static int verify_callback(int preverify_ok, X509_STORE_CTX *x509_store_ctx)
 {
-    SSL *ssl;
-    jsse_ssl_app_data_t *appdata;
-    jclass cls;
-
-    jobjectArray objectArray;
-
     /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
-    ssl = (SSL*)X509_STORE_CTX_get_ex_data(x509_store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+    SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(x509_store_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
 
-    appdata = (jsse_ssl_app_data_t*)SSL_get_app_data(ssl);
+    jsse_ssl_app_data_t* appdata = (jsse_ssl_app_data_t*)SSL_get_app_data(ssl);
 
-    cls = appdata->env->GetObjectClass(appdata->object);
+    jclass cls = appdata->env->GetObjectClass(appdata->object);
 
-    jmethodID methodID = appdata->env->GetMethodID(cls, "verify_callback", "([[B)I");
+    jmethodID methodID = appdata->env->GetMethodID(cls, "verifyCertificateChain", "([[B)Z");
 
-    objectArray = getcertificatebytes(appdata->env, x509_store_ctx->untrusted);
+    jobjectArray objectArray = getcertificatebytes(appdata->env, x509_store_ctx->untrusted);
 
-    appdata->env->CallIntMethod(appdata->object, methodID, objectArray);
+    jboolean verified = appdata->env->CallBooleanMethod(appdata->object, methodID, objectArray);
 
-    return 1;
+    return (verified) ? 1 : 0;
 }
 
 /**
  * Sets  the client's credentials and the depth of theirs verification.
  */
 static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativesetclientauth(JNIEnv* env,
-        jobject object, jint value)
+        jclass, jint ssl_address, jint value)
 {
-    SSL_CTX *ssl_ctx = (SSL_CTX *)env->GetIntField(object, field_ServerSocket_ssl_ctx);
-    SSL_CTX_set_verify(ssl_ctx, (int)value, verify_callback);
-}
-
-/**
- * The actual SSL context is reset.
- */
-static void org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativefree(JNIEnv* env, jobject object)
-{
-    SSL_CTX *ctx = (SSL_CTX *)env->GetIntField(object, field_ServerSocket_ssl_ctx);
-    SSL_CTX_free(ctx);
-    env->SetIntField(object, field_ServerSocket_ssl_ctx, 0);
+    SSL* ssl = getSslPointer(env, ssl_address, true);
+    if (ssl == NULL) {
+      return;
+    }
+    SSL_set_verify(ssl, (int)value, verify_callback);
 }
 
 static JNINativeMethod sServerSocketImplMethods[] =
 {
-    {"nativeinitstatic", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_initstatic},
-    {"nativeinit", "(Ljava/lang/String;Ljava/lang/String;[B)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_init},
-    {"nativesetenabledprotocols", "(J)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_setenabledprotocols},
-    {"nativegetsupportedciphersuites", "()[Ljava/lang/String;", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_getsupportedciphersuites},
-    {"nativesetclientauth", "(I)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativesetclientauth},
-    {"nativefree", "()V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativefree}
+    {"nativesetclientauth", "(II)V", (void*)org_apache_harmony_xnet_provider_jsse_OpenSSLServerSocketImpl_nativesetclientauth},
 };
 
-static jfieldID field_Session_session;
-
-static SSL_SESSION* getSslSessionPointer(JNIEnv* env, jobject object) {
-    return reinterpret_cast<SSL_SESSION*>(env->GetIntField(object, field_Session_session));
+/**
+ * Our implementation of what might be considered
+ * SSL_SESSION_get_peer_cert_chain
+ */
+static STACK_OF(X509)* SSL_SESSION_get_peer_cert_chain(SSL_CTX* ssl_ctx, SSL_SESSION* ssl_session) {
+    SSL* ssl = SSL_new(ssl_ctx);
+    SSL_set_session(ssl, ssl_session);
+    STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
+    SSL_free(ssl);
+    return chain;
 }
 
 // Fills a byte[][] with the peer certificates in the chain.
 static jobjectArray OpenSSLSessionImpl_getPeerCertificatesImpl(JNIEnv* env,
-        jobject object, jint jssl)
+        jclass, jint ssl_ctx_address, jint ssl_session_address)
 {
-    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
-    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-    SSL* ssl = SSL_new(ssl_ctx);
-
-    SSL_set_session(ssl, ssl_session);
-
-    STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
+    SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
+    if (ssl_ctx == NULL) {
+        jniThrowNullPointerException(env, "SSL_CTX is null");
+        return NULL;
+    }
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
+    STACK_OF(X509)* chain = SSL_SESSION_get_peer_cert_chain(ssl_ctx, ssl_session);
     jobjectArray objectArray = getcertificatebytes(env, chain);
-
-    SSL_free(ssl);
-    SSL_CTX_free(ssl_ctx);
     return objectArray;
 }
 
@@ -2437,8 +2264,8 @@
  * not certificates). Returns a byte[] containing the DER-encoded state.
  * See apache mod_ssl.
  */
-static jbyteArray OpenSSLSessionImpl_getEncoded(JNIEnv* env, jobject object) {
-    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+static jbyteArray OpenSSLSessionImpl_getEncoded(JNIEnv* env, jclass, jint ssl_session_address) {
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
     if (ssl_session == NULL) {
         return NULL;
     }
@@ -2463,7 +2290,7 @@
 /**
  * Deserialize the session.
  */
-static jint OpenSSLSessionImpl_initializeNativeImpl(JNIEnv* env, jobject object, jbyteArray bytes, jint size) {
+static jint OpenSSLSessionImpl_initializeNativeImpl(JNIEnv* env, jclass, jbyteArray bytes, jint size) {
     if (bytes == NULL) {
         return 0;
     }
@@ -2479,8 +2306,8 @@
 /**
  * Gets and returns in a byte array the ID of the actual SSL session.
  */
-static jbyteArray OpenSSLSessionImpl_getId(JNIEnv* env, jobject object) {
-    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+static jbyteArray OpenSSLSessionImpl_getId(JNIEnv* env, jclass, jint ssl_session_address) {
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
 
     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
     if (result != NULL) {
@@ -2495,68 +2322,61 @@
  * Gets and returns in a long integer the creation's time of the
  * actual SSL session.
  */
-static jlong OpenSSLSessionImpl_getCreationTime(JNIEnv* env, jobject object) {
-    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
+static jlong OpenSSLSessionImpl_getCreationTime(JNIEnv* env, jclass, jint ssl_session_address) {
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
     jlong result = SSL_SESSION_get_time(ssl_session);
     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
     return result;
 }
 
 /**
+ * Our implementation of what might be considered
+ * SSL_SESSION_get_version, based on SSL_get_version.
+ * See get_ssl_version above.
+ */
+static const char* SSL_SESSION_get_version(SSL_SESSION* ssl_session) {
+  return get_ssl_version(ssl_session->ssl_version);
+}
+
+/**
  * Gets and returns in a string the version of the SSL protocol. If it
  * returns the string "unknown" it means that no connection is established.
  */
-static jstring OpenSSLSessionImpl_getProtocol(JNIEnv* env, jobject object) {
-    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
-    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-    SSL* ssl = SSL_new(ssl_ctx);
-
-    SSL_set_session(ssl, ssl_session);
-
-    const char* protocol = SSL_get_version(ssl);
+static jstring OpenSSLSessionImpl_getProtocol(JNIEnv* env, jclass, jint ssl_session_address) {
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
+    const char* protocol = SSL_SESSION_get_version(ssl_session);
     jstring result = env->NewStringUTF(protocol);
-
-    SSL_free(ssl);
-    SSL_CTX_free(ssl_ctx);
     return result;
 }
 
 /**
  * Gets and returns in a string the set of ciphers the actual SSL session uses.
  */
-static jstring OpenSSLSessionImpl_getCipherSuite(JNIEnv* env, jobject object) {
-    SSL_SESSION* ssl_session = getSslSessionPointer(env, object);
-    SSL_CTX* ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-    SSL* ssl = SSL_new(ssl_ctx);
-
-    SSL_set_session(ssl, ssl_session);
-
-    const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl);
+static jstring OpenSSLSessionImpl_getCipherSuite(JNIEnv* env, jclass, jint ssl_session_address) {
+    SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
+    const SSL_CIPHER* cipher = ssl_session->cipher;
     jstring result = env->NewStringUTF(SSL_CIPHER_get_name(cipher));
-
-    SSL_free(ssl);
-    SSL_CTX_free(ssl_ctx);
     return result;
 }
 
 /**
  * Frees the SSL session.
  */
-static void OpenSSLSessionImpl_freeImpl(JNIEnv* env, jobject object, jint session) {
-    LOGD("Freeing OpenSSL session");
+static void OpenSSLSessionImpl_freeImpl(JNIEnv* env, jclass, jint session) {
     SSL_SESSION* ssl_session = reinterpret_cast<SSL_SESSION*>(session);
+    // LOGD("Freeing OpenSSL session %p", session);
     SSL_SESSION_free(ssl_session);
 }
 
 static JNINativeMethod sSessionImplMethods[] = {
     { "freeImpl", "(I)V", (void*) OpenSSLSessionImpl_freeImpl },
-    { "getCipherSuite", "()Ljava/lang/String;", (void*) OpenSSLSessionImpl_getCipherSuite },
-    { "getCreationTime", "()J", (void*) OpenSSLSessionImpl_getCreationTime },
-    { "getEncoded", "()[B", (void*) OpenSSLSessionImpl_getEncoded },
-    { "getId", "()[B", (void*) OpenSSLSessionImpl_getId },
-    { "getPeerCertificatesImpl", "()[[B", (void*) OpenSSLSessionImpl_getPeerCertificatesImpl },
-    { "getProtocol", "()Ljava/lang/String;", (void*) OpenSSLSessionImpl_getProtocol },
-    { "initializeNativeImpl", "([BI)I", (void*) OpenSSLSessionImpl_initializeNativeImpl }
+    { "getCipherSuite", "(I)Ljava/lang/String;", (void*) OpenSSLSessionImpl_getCipherSuite },
+    { "getCreationTime", "(I)J", (void*) OpenSSLSessionImpl_getCreationTime },
+    { "getEncoded", "(I)[B", (void*) OpenSSLSessionImpl_getEncoded },
+    { "getId", "(I)[B", (void*) OpenSSLSessionImpl_getId },
+    { "getPeerCertificatesImpl", "(II)[[B", (void*) OpenSSLSessionImpl_getPeerCertificatesImpl },
+    { "getProtocol", "(I)Ljava/lang/String;", (void*) OpenSSLSessionImpl_getProtocol },
+    { "initializeNativeImpl", "([BI)I", (void*) OpenSSLSessionImpl_initializeNativeImpl },
 };
 
 typedef struct {
@@ -2571,15 +2391,7 @@
     { "org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl", sServerSocketImplMethods, NELEM(sServerSocketImplMethods) },
     { "org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl", sSessionImplMethods, NELEM(sSessionImplMethods) },
 };
-
-/*
- * Peforms the actual registration of the native methods.
- * Also looks up the fields that belong to the class (if
- * any) and stores the field IDs. Simply remove what you
- * don't need.
- */
-extern "C" int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
-
+int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
     // Register org.apache.harmony.xnet.provider.jsse.* methods
     for (int i = 0; i < NELEM(sClasses); i++) {
         int result = jniRegisterNativeMethods(env,
@@ -2591,18 +2403,6 @@
         }
     }
 
-    // java.io.FileDescriptor
-    jclass fileDescriptor = env->FindClass("java/io/FileDescriptor");
-    if (fileDescriptor == NULL) {
-        LOGE("Can't find java/io/FileDescriptor");
-        return -1;
-    }
-    field_FileDescriptor_descriptor = env->GetFieldID(fileDescriptor, "descriptor", "I");
-    if (field_FileDescriptor_descriptor == NULL) {
-        LOGE("Can't find FileDescriptor.descriptor");
-        return -1;
-    }
-
     // java.net.Socket
     jclass socket = env->FindClass("java/net/Socket");
     if (socket == NULL) {
@@ -2627,58 +2427,5 @@
         return -1;
     }
 
-    // org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
-    jclass socketImpl = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
-    if (socketImpl == NULL) {
-        LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl");
-        return -1;
-    }
-    // Note: do these after the registration of native methods, because 
-    // there is a static method "initstatic" that's called when the
-    // OpenSSLSocketImpl class is first loaded, and that required
-    // a native method to be associated with it.
-    field_Socket_ssl_ctx = env->GetFieldID(socketImpl, "ssl_ctx", "I");
-    if (field_Socket_ssl_ctx == NULL) {
-      LOGE("Can't find OpenSSLSocketImpl.ssl_ctx");
-      return -1;
-    }
-    field_Socket_ssl = env->GetFieldID(socketImpl, "ssl", "I");
-    if (field_Socket_ssl == NULL) {
-      LOGE("Can't find OpenSSLSocketImpl.ssl");
-      return -1;
-    }
-    field_Socket_timeout = env->GetFieldID(socketImpl, "timeout", "I");
-    if (field_Socket_timeout == NULL) {
-      LOGE("Can't find OpenSSLSocketImpl.timeout");
-      return -1;
-    }
-
-    // org.apache.harmony.xnet.provider.jsse.OpenSSLServerSocketImpl
-    jclass serverSocketImpl = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
-    if (serverSocketImpl == NULL) {
-        LOGE("Can't find org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketImpl");
-        return -1;
-    }
-    // Note: do these after the registration of native methods, because
-    // there is a static method "initstatic" that's called when the
-    // OpenSSLServerSocketImpl class is first loaded, and that required
-    // a native method to be associated with it.
-    field_ServerSocket_ssl_ctx = env->GetFieldID(serverSocketImpl, "ssl_ctx", "I");
-    if (field_ServerSocket_ssl_ctx == NULL) {
-      LOGE("Can't find OpenSSLServerSocketImpl.ssl_ctx");
-      return -1;
-    }
-
-    // org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl
-    jclass sessionImpl = env->FindClass("org/apache/harmony/xnet/provider/jsse/OpenSSLSessionImpl");
-    if (sessionImpl == NULL) {
-        return -1;
-    }
-    field_Session_session = env->GetFieldID(sessionImpl, "session", "I");
-    if (field_Session_session == NULL) {
-      LOGE("Can't find OpenSSLSessionImpl.session");
-      return -1;
-    }
-
     return 0;
 }
diff --git a/x-net/src/test/java/tests/api/javax/net/AllTests.java b/x-net/src/test/java/tests/api/javax/net/AllTests.java
index 90c2a6a..35cd6f5 100644
--- a/x-net/src/test/java/tests/api/javax/net/AllTests.java
+++ b/x-net/src/test/java/tests/api/javax/net/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.javax.net;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.javax.net;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(ServerSocketFactoryTest.class);
diff --git a/x-net/src/test/java/tests/api/javax/net/ssl/AllTests.java b/x-net/src/test/java/tests/api/javax/net/ssl/AllTests.java
index ecfe83f..5f9c32d 100644
--- a/x-net/src/test/java/tests/api/javax/net/ssl/AllTests.java
+++ b/x-net/src/test/java/tests/api/javax/net/ssl/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.javax.net.ssl;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.javax.net.ssl;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(CertPathTrustManagerParametersTest.class);
diff --git a/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java b/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
index f659919..8205059 100644
--- a/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
+++ b/x-net/src/test/java/tests/api/javax/net/ssl/SSLEngineTest.java
@@ -62,10 +62,6 @@
     private HandshakeHandler clientEngine;
     private HandshakeHandler serverEngine;
 
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(SSLEngineTest.class);
-    }
-
     @Override protected void setUp() throws Exception {
         super.setUp();
         TestEnvironment.reset();
diff --git a/x-net/src/test/java/tests/xnet/AllTests.java b/x-net/src/test/java/tests/xnet/AllTests.java
index 53b11dc..04a2ed6 100644
--- a/x-net/src/test/java/tests/xnet/AllTests.java
+++ b/x-net/src/test/java/tests/xnet/AllTests.java
@@ -23,14 +23,8 @@
  * Test suite that includes all tests for the Math project.
  */
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite(
-                "All javax.net and javax.net.ssl test suites");
+        TestSuite suite = new TestSuite("All javax.net and javax.net.ssl test suites");
         // $JUnit-BEGIN$
         suite.addTest(tests.api.javax.net.AllTests.suite());
         suite.addTest(tests.api.javax.net.ssl.AllTests.suite());
diff --git a/xml/src/main/java/javax/xml/package.html b/xml/src/main/java/javax/xml/package.html
index 5a4621d..f3d8318 100644
--- a/xml/src/main/java/javax/xml/package.html
+++ b/xml/src/main/java/javax/xml/package.html
@@ -3,6 +3,5 @@
     <p>
       Provides a utility class with useful XML constants.
     </p>
-    @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/xml/src/main/java/javax/xml/parsers/SAXParser.java b/xml/src/main/java/javax/xml/parsers/SAXParser.java
index cd020ab..8c52461 100644
--- a/xml/src/main/java/javax/xml/parsers/SAXParser.java
+++ b/xml/src/main/java/javax/xml/parsers/SAXParser.java
@@ -63,7 +63,7 @@
  * given {@link org.xml.sax.HandlerBase} or the
  * {@link org.xml.sax.helpers.DefaultHandler} are called.<p>
  *
- * Implementors of this class which wrap an underlaying implementation
+ * Implementations of this class which wrap an underlying implementation
  * can consider using the {@link org.xml.sax.helpers.ParserAdapter}
  * class to initially adapt their SAX1 implementation to work under
  * this revised class.
diff --git a/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java b/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
index d187456..3bf5d07 100644
--- a/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
+++ b/xml/src/main/java/org/apache/harmony/xml/ExpatReader.java
@@ -148,7 +148,7 @@
 
         if (name.equals(LEXICAL_HANDLER_PROPERTY)) {
             // The object must implement LexicalHandler
-            if (value instanceof LexicalHandler) {
+            if (value instanceof LexicalHandler || value == null) {
                 this.lexicalHandler = (LexicalHandler) value;
                 return;
             }
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
index 8bce9aa..31384a0 100644
--- a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -57,19 +57,20 @@
     private static DOMImplementationImpl dom = DOMImplementationImpl.getInstance();
 
     private boolean coalescing;
-
     private EntityResolver entityResolver;
-
     private ErrorHandler errorHandler;
-
     private boolean ignoreComments;
-
     private boolean ignoreElementContentWhitespace;
-
     private boolean namespaceAware;
+    // adding a new field? don't forget to update reset().
 
-    DocumentBuilderImpl() {
-        // Do nothing.
+    @Override public void reset() {
+        coalescing = false;
+        entityResolver = null;
+        errorHandler = null;
+        ignoreComments = false;
+        ignoreElementContentWhitespace = false;
+        namespaceAware = false;
     }
 
     @Override
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
index b3af61f..55de4b3 100644
--- a/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/SAXParserImpl.java
@@ -16,6 +16,8 @@
 
 package org.apache.harmony.xml.parsers;
 
+import java.util.Collections;
+import java.util.HashMap;
 import org.apache.harmony.xml.ExpatReader;
 
 import java.util.Map;
@@ -30,25 +32,44 @@
 import org.xml.sax.helpers.XMLReaderAdapter;
 
 /**
- * Provides a straightforward SAXParser implementation based on ExpatReader.
- * The class is used internally only, thus only notable members that are not
- * already in the abstract superclass are documented. Hope that's ok.
+ * A SAX parser based on Expat.
  */
-class SAXParserImpl extends SAXParser {
+final class SAXParserImpl extends SAXParser {
 
+    private Map<String, Boolean> initialFeatures;
     private XMLReader reader;
-
     private Parser parser;
 
-    SAXParserImpl(Map<String, Boolean> features)
+    SAXParserImpl(Map<String, Boolean> initialFeatures)
             throws SAXNotRecognizedException, SAXNotSupportedException {
-        reader = new ExpatReader();
+        this.initialFeatures = initialFeatures.isEmpty()
+                ? Collections.<String, Boolean>emptyMap()
+                : new HashMap<String, Boolean>(initialFeatures);
+        resetInternal();
+    }
 
-        for (Map.Entry<String,Boolean> entry : features.entrySet()) {
+    private void resetInternal()
+            throws SAXNotSupportedException, SAXNotRecognizedException {
+        reader = new ExpatReader();
+        for (Map.Entry<String,Boolean> entry : initialFeatures.entrySet()) {
             reader.setFeature(entry.getKey(), entry.getValue());
         }
     }
 
+    @Override public void reset() {
+        /*
+         * The exceptions are impossible. If any features are unrecognized or
+         * unsupported, construction of this instance would have failed.
+         */
+        try {
+            resetInternal();
+        } catch (SAXNotRecognizedException e) {
+            throw new AssertionError();
+        } catch (SAXNotSupportedException e) {
+            throw new AssertionError();
+        }
+    }
+
     @Override
     public Parser getParser() {
         if (parser == null) {
diff --git a/xml/src/main/java/org/w3c/dom/package.html b/xml/src/main/java/org/w3c/dom/package.html
index 8189944..15f8ff6 100644
--- a/xml/src/main/java/org/w3c/dom/package.html
+++ b/xml/src/main/java/org/w3c/dom/package.html
@@ -6,7 +6,5 @@
       {@link javax.xml.parsers.DocumentBuilder} are accessed and manipulated
       through these interfaces.
     </p>
-    
-  @since Android 1.0
   </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/xml/src/main/java/org/xml/sax/ext/package.html b/xml/src/main/java/org/xml/sax/ext/package.html
index 9b79d77..e443df4 100644
--- a/xml/src/main/java/org/xml/sax/ext/package.html
+++ b/xml/src/main/java/org/xml/sax/ext/package.html
@@ -43,6 +43,4 @@
 As an example, most validation systems can be cleanly layered on top
 of parsers supporting the standardized SAX2 interfaces.  </p>
 
-@since Android 1.0
-
 </BODY></HTML>
diff --git a/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java b/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
index 96151a1..b761c34 100644
--- a/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
+++ b/xml/src/main/java/org/xml/sax/helpers/XMLReaderFactory.java
@@ -124,10 +124,7 @@
             in = loader.getResourceAsStream (service);
 
         if (in != null) {
-            // BEGIN android-modified
-            reader = new BufferedReader (
-                new InputStreamReader (in, "UTF8"), 8192);
-            // END android-modified
+            reader = new BufferedReader (new InputStreamReader (in, "UTF8"));
             className = reader.readLine ();
             in.close ();
         }
diff --git a/xml/src/main/java/org/xml/sax/helpers/package.html b/xml/src/main/java/org/xml/sax/helpers/package.html
index 3a265fd..8f323c0 100644
--- a/xml/src/main/java/org/xml/sax/helpers/package.html
+++ b/xml/src/main/java/org/xml/sax/helpers/package.html
@@ -8,6 +8,4 @@
 <p>See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
 for more information about SAX.</p>
 
-@since Android 1.0
-
 </BODY></HTML>
diff --git a/xml/src/main/java/org/xml/sax/package.html b/xml/src/main/java/org/xml/sax/package.html
index fbe7108..7d7f257 100644
--- a/xml/src/main/java/org/xml/sax/package.html
+++ b/xml/src/main/java/org/xml/sax/package.html
@@ -294,6 +294,4 @@
 XMLReader implementations need not support them.
 </p>
 
-@since Android 1.0
-
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
index b893309..c684708 100644
--- a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -562,6 +562,10 @@
             mPrefix = "";
         }
     }
+
+    // Disallow copy and assignment.
+    ExpatElementName(const ExpatElementName&);
+    void operator=(const ExpatElementName&);
 };
 
 /**
@@ -1522,11 +1526,7 @@
         (void*) getAttributeValueForQName },
     { "freeAttributes", "(I)V", (void*) freeAttributes },
 };
-
-/**
- * Called from Register.c.
- */
-extern "C" int register_org_apache_harmony_xml_ExpatParser(JNIEnv* env) {
+int register_org_apache_harmony_xml_ExpatParser(JNIEnv* env) {
     int result = jniRegisterNativeMethods(env, "org/apache/harmony/xml/ExpatParser",
         parserMethods, NELEM(parserMethods));
     if (result != 0) {
diff --git a/xml/src/test/java/org/apache/harmony/xml/AllTests.java b/xml/src/test/java/org/apache/harmony/xml/AllTests.java
index f7fac7c..c04c1b5 100644
--- a/xml/src/test/java/org/apache/harmony/xml/AllTests.java
+++ b/xml/src/test/java/org/apache/harmony/xml/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(ExpatParserTest.class);
         return suite;
     }
diff --git a/xml/src/test/java/org/apache/harmony/xml/JaxenXPathTestSuite.java b/xml/src/test/java/org/apache/harmony/xml/JaxenXPathTestSuite.java
index e752fc0..17f0341 100644
--- a/xml/src/test/java/org/apache/harmony/xml/JaxenXPathTestSuite.java
+++ b/xml/src/test/java/org/apache/harmony/xml/JaxenXPathTestSuite.java
@@ -20,7 +20,6 @@
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
-import junit.textui.TestRunner;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -54,21 +53,11 @@
  */
 public class JaxenXPathTestSuite {
 
-    private static final File DEFAULT_JAXEN_HOME
-            = new File("/home/dalvik-prebuild/jaxen");
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 1) {
-            System.out.println("Usage: JaxenXPathTestSuite <jaxen-home>");
-            return;
-        }
-
-        File jaxenHome = new File(args[0]);
-        TestRunner.run(suite(jaxenHome));
-    }
+    private static final String DEFAULT_JAXEN_HOME = "/home/dalvik-prebuild/jaxen";
 
     public static Test suite() throws Exception {
-        return suite(DEFAULT_JAXEN_HOME);
+        String jaxenHome = System.getProperty("jaxen.home", DEFAULT_JAXEN_HOME);
+        return suite(new File(jaxenHome));
     }
 
     /**
diff --git a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
index 7dbfaea..3f0d2cb 100644
--- a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
+++ b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
@@ -21,7 +21,6 @@
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
-import junit.textui.TestRunner;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -135,7 +134,7 @@
         }
 
         File catalogXml = new File(args[0]);
-        TestRunner.run(suite(catalogXml));
+        // TestRunner.run(suite(catalogXml)); android-changed
     }
 
     public static Test suite() throws Exception {
diff --git a/xml/src/test/java/org/kxml2/io/AllTests.java b/xml/src/test/java/org/kxml2/io/AllTests.java
index f996d25..4fcc44a 100644
--- a/xml/src/test/java/org/kxml2/io/AllTests.java
+++ b/xml/src/test/java/org/kxml2/io/AllTests.java
@@ -21,7 +21,7 @@
 
 public class AllTests {
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
         suite.addTestSuite(KXmlSerializerTest.class);
         return suite;
     }
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java b/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java
index 6a22109..aecc746 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/AllTests.java
@@ -25,13 +25,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package tests.api.javax.xml.parsers;");
+        TestSuite suite = new TestSuite("All tests for package tests.api.javax.xml.parsers;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(DocumentBuilderFactoryTest.class);
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
index 80c6e3c..7356d3a 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderFactoryTest.java
@@ -319,7 +319,6 @@
             args = {boolean.class}
         )
     })
-    @KnownFailure("Should handle XIncludeAware flag more gracefully")
     public void test_isSetXIncludeAware() {
         dbf.setXIncludeAware(true);
         assertTrue(dbf.isXIncludeAware());
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
index 4b4511d..2818460 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/DocumentBuilderTest.java
@@ -252,7 +252,6 @@
         method = "isXIncludeAware",
         args = {}
     )
-    @KnownFailure("Should handle XIncludeAware flag more gracefully")
     public void testIsXIncludeAware() {
         try {
             dbf.setXIncludeAware(false);
@@ -607,7 +606,6 @@
         method = "reset",
         args = { }
     )
-    @KnownFailure("Android DocumentBuilder should implement reset() properly")
     public void testReset() {
         // Make sure EntityResolver gets reset
         InputStream source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
@@ -694,7 +692,6 @@
         method = "setEntityResolver",
         args = { EntityResolver.class }
     )
-    @KnownFailure("Android DocumentBuilder should support entity resolving")
     public void testSetEntityResolver() {
         // Ordinary case
         InputStream source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
index 6f050e3..d5bf289 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserFactoryTest.java
@@ -163,7 +163,6 @@
             args = {boolean.class}
         )
     })
-    @KnownFailure("Should handle XIncludeAware flag more gracefully")
     public void test_setIsXIncludeAware() {
         spf.setXIncludeAware(true);
         assertTrue(spf.isXIncludeAware());
diff --git a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
index ad0b9c2..a80c4e3 100644
--- a/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
+++ b/xml/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
@@ -327,7 +327,6 @@
         method = "isXIncludeAware",
         args = {}
     )
-    @KnownFailure("Should handle XIncludeAware flag more gracefully")
     public void testIsXIncludeAware() {
         try {
             spf.setXIncludeAware(false);
@@ -1047,7 +1046,6 @@
         method = "reset",
         args = { }
     )
-    @KnownFailure("Android DocumentBuilder should implement reset() properly")
     public void testReset() {
         try {
             spf = SAXParserFactory.newInstance();
@@ -1103,7 +1101,6 @@
             args = { String.class, Object.class }
         )
     })
-    @KnownFailure("ExpatParser should allow to clear properties")
     public void testSetGetProperty() {
         // Ordinary case
         String validName = "http://xml.org/sax/properties/lexical-handler";
diff --git a/xml/src/test/java/tests/api/org/xml/sax/AllTests.java b/xml/src/test/java/tests/api/org/xml/sax/AllTests.java
index 9c29178..f7643e9 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/AllTests.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.xml.sax package");
+        TestSuite suite = new TestSuite("Tests for org.xml.sax package");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(HandlerBaseTest.class);
diff --git a/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java b/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java
index f4b34b8..1334780 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/ext/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.xml.sax.ext package");
+        TestSuite suite = new TestSuite("Tests for org.xml.sax.ext package");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(Attributes2ImplTest.class);
diff --git a/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java b/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java
index 5bf63bf..135496c 100644
--- a/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java
+++ b/xml/src/test/java/tests/api/org/xml/sax/helpers/AllTests.java
@@ -20,13 +20,8 @@
 import junit.framework.TestSuite;
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for org.xml.sax.helpers package");
+        TestSuite suite = new TestSuite("Tests for org.xml.sax.helpers package");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AttributeListImplTest.class);
diff --git a/xml/src/test/java/tests/org/w3c/dom/AllTests.java b/xml/src/test/java/tests/org/w3c/dom/AllTests.java
index a4299a7..5dba844 100644
--- a/xml/src/test/java/tests/org/w3c/dom/AllTests.java
+++ b/xml/src/test/java/tests/org/w3c/dom/AllTests.java
@@ -24,13 +24,8 @@
  */
 
 public class AllTests {
-
-    public static void main(String[] args) {
-        junit.textui.TestRunner.run(AllTests.suite());
-    }
-
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.w3c.dom;");
+        TestSuite suite = new TestSuite("All tests for package org.w3c.dom;");
         // $JUnit-BEGIN$
 
         suite.addTestSuite(AttrGetOwnerElement.class);
diff --git a/xml/src/test/java/tests/xml/AllTests.java b/xml/src/test/java/tests/xml/AllTests.java
index e9f833f..2e12a59 100644
--- a/xml/src/test/java/tests/xml/AllTests.java
+++ b/xml/src/test/java/tests/xml/AllTests.java
@@ -22,7 +22,7 @@
 public class AllTests {
 
     public static Test suite() {
-        TestSuite suite = tests.TestSuiteFactory.createTestSuite();
+        TestSuite suite = new TestSuite();
 
         suite.addTestSuite(DeclarationTest.class);
         suite.addTestSuite(DomTest.class);
@@ -36,7 +36,9 @@
         suite.addTest(tests.api.javax.xml.parsers.AllTests.suite());
 
         suite.addTest(tests.api.org.xml.sax.AllTests.suite());
-        suite.addTest(tests.api.org.w3c.dom.AllTests.suite());
+        // BEGIN android-changed: this is in the dom module!
+        // suite.addTest(tests.api.org.w3c.dom.AllTests.suite());
+        // END android-changed
         suite.addTest(tests.org.w3c.dom.AllTests.suite());
         suite.addTest(org.apache.harmony.xml.AllTests.suite());
         suite.addTest(org.kxml2.io.AllTests.suite());